Initial
This commit is contained in:
151
experiments/maze_solver/SpaceEfficientMazeSolver.cs
Normal file
151
experiments/maze_solver/SpaceEfficientMazeSolver.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
public static class SpaceEfficientMazeSolver
|
||||
{
|
||||
// Memory-limited DFS that only keeps O(√n) visited nodes in memory
|
||||
// Recomputes paths when needed, trading time for space
|
||||
public static MazeResult MemoryLimitedDFS(bool[,] maze, int memoryLimit)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
long memBefore = GC.GetTotalMemory(true);
|
||||
|
||||
int rows = maze.GetLength(0);
|
||||
int cols = maze.GetLength(1);
|
||||
int nodesExplored = 0;
|
||||
bool pathFound = false;
|
||||
int pathLength = 0;
|
||||
|
||||
// Limited memory for visited nodes - simulates √n space
|
||||
var limitedVisited = new HashSet<(int, int)>(memoryLimit);
|
||||
var currentPath = new HashSet<(int, int)>(); // Track current recursion path to prevent cycles
|
||||
|
||||
bool DfsWithRecomputation(int r, int c, int depth)
|
||||
{
|
||||
nodesExplored++;
|
||||
|
||||
// Goal reached
|
||||
if (r == rows - 1 && c == cols - 1)
|
||||
{
|
||||
pathLength = depth;
|
||||
return true;
|
||||
}
|
||||
|
||||
var current = (r, c);
|
||||
|
||||
// Prevent cycles in current path
|
||||
if (currentPath.Contains(current))
|
||||
return false;
|
||||
|
||||
currentPath.Add(current);
|
||||
|
||||
// Add to limited visited set (may evict old entries)
|
||||
if (limitedVisited.Count >= memoryLimit && !limitedVisited.Contains(current))
|
||||
{
|
||||
// Evict oldest entry (simulate FIFO for simplicity)
|
||||
var toRemove = limitedVisited.First();
|
||||
limitedVisited.Remove(toRemove);
|
||||
}
|
||||
limitedVisited.Add(current);
|
||||
|
||||
int[] dr = { 0, 1, 0, -1 };
|
||||
int[] dc = { 1, 0, -1, 0 };
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int nr = r + dr[i], nc = c + dc[i];
|
||||
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && maze[nr, nc])
|
||||
{
|
||||
if (DfsWithRecomputation(nr, nc, depth + 1))
|
||||
{
|
||||
currentPath.Remove(current);
|
||||
pathFound = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentPath.Remove(current);
|
||||
return false;
|
||||
}
|
||||
|
||||
pathFound = DfsWithRecomputation(0, 0, 1);
|
||||
|
||||
sw.Stop();
|
||||
long memAfter = GC.GetTotalMemory(true);
|
||||
|
||||
return new MazeResult
|
||||
{
|
||||
Elapsed = sw.Elapsed,
|
||||
MemoryUsage = memAfter - memBefore,
|
||||
PathFound = pathFound,
|
||||
PathLength = pathLength,
|
||||
NodesExplored = nodesExplored
|
||||
};
|
||||
}
|
||||
|
||||
// Iterative deepening DFS - uses O(log n) space but recomputes extensively
|
||||
public static MazeResult IterativeDeepeningDFS(bool[,] maze)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
long memBefore = GC.GetTotalMemory(true);
|
||||
|
||||
int rows = maze.GetLength(0);
|
||||
int cols = maze.GetLength(1);
|
||||
int nodesExplored = 0;
|
||||
bool pathFound = false;
|
||||
int pathLength = 0;
|
||||
|
||||
// Try increasing depth limits
|
||||
for (int maxDepth = 1; maxDepth <= rows * cols; maxDepth++)
|
||||
{
|
||||
bool DepthLimitedDFS(int r, int c, int depth)
|
||||
{
|
||||
nodesExplored++;
|
||||
|
||||
if (depth > maxDepth) return false;
|
||||
|
||||
if (r == rows - 1 && c == cols - 1)
|
||||
{
|
||||
pathLength = depth;
|
||||
return true;
|
||||
}
|
||||
|
||||
int[] dr = { 0, 1, 0, -1 };
|
||||
int[] dc = { 1, 0, -1, 0 };
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int nr = r + dr[i], nc = c + dc[i];
|
||||
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && maze[nr, nc])
|
||||
{
|
||||
if (DepthLimitedDFS(nr, nc, depth + 1))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DepthLimitedDFS(0, 0, 0))
|
||||
{
|
||||
pathFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
long memAfter = GC.GetTotalMemory(true);
|
||||
|
||||
return new MazeResult
|
||||
{
|
||||
Elapsed = sw.Elapsed,
|
||||
MemoryUsage = memAfter - memBefore,
|
||||
PathFound = pathFound,
|
||||
PathLength = pathLength,
|
||||
NodesExplored = nodesExplored
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user