private static void MakeComponents() { var A = new WeightedGraphNode <char>('A'); var B = new WeightedGraphNode <char>('B'); var C = new WeightedGraphNode <char>('C'); var D = new WeightedGraphNode <char>('D'); var E = new WeightedGraphNode <char>('E'); var F = new WeightedGraphNode <char>('F'); A.AddMutualNeighbor(B); A.AddMutualNeighbor(C); B.AddMutualNeighbor(C); D.AddMutualNeighbor(E); var G = new Graph <char>(A, B, C, D, E, F); var components = G.FindConnectedComponents(); foreach (var component in components) { component.PrintNodes(); Console.WriteLine(); } }
static void MakeWeightedGraph() { //Vertex Set WeightedGraphNode <char> A = new WeightedGraphNode <char>('A'); WeightedGraphNode <char> B = new WeightedGraphNode <char>('B'); WeightedGraphNode <char> C = new WeightedGraphNode <char>('C'); WeightedGraphNode <char> D = new WeightedGraphNode <char>('D'); WeightedGraphNode <char> E = new WeightedGraphNode <char>('E'); WeightedGraphNode <char> F = new WeightedGraphNode <char>('F'); WeightedGraphNode <char> G = new WeightedGraphNode <char>('G'); //Edge Set A.AddMutualNeighbor(B, 4); A.AddMutualNeighbor(G, 2); A.AddMutualNeighbor(D, 1); B.AddMutualNeighbor(D, 6); B.AddMutualNeighbor(G, 9); C.AddMutualNeighbor(D, 6); C.AddMutualNeighbor(E, 4); E.AddMutualNeighbor(F, 3); F.AddMutualNeighbor(G, 5); GraphNode <char>[] nodes = { A, B, C, D, E, F, G }; Graph <char> a_graph = new Graph <char>(nodes); Console.WriteLine("Finding the shorting path between B and E"); var path = a_graph.RunDijkstra(B, E); if (path == null) { Console.WriteLine("Nope :("); } else { Console.WriteLine("\n The shortest path has weight {0} ", path.PathWeightToHere); //use a stack to figure out the order to take var reverse_backtracking = new Stack <NodePath <char> >(); while (path != null) { reverse_backtracking.Add(path); path = (WeightedNodePath <char>)path.Parent; } while (!reverse_backtracking.IsEmpty()) { var top = reverse_backtracking.Pop(); Console.Write("{0}", top.Node.GetValue()); if (reverse_backtracking.Count > 0) { Console.Write(" -> "); } } Console.WriteLine("\n-------------------------------\n"); } }
public static WeightedGraph <double> GetWeightedGraph(ICellMap map, NeighbourMode neighbourMode) { WeightedGraphNode <double>[,] nodes = new WeightedGraphNode <double> [map.Width, map.Height]; for (int x = 0; x < map.Width; x++) { for (int y = 0; y < map.Height; y++) { if (map.IsPassable(x, y)) { WeightedGraphNode <double> connectionNode; WeightedGraphNode <double> currentNode = new WeightedGraphNode <double>(Double.PositiveInfinity); nodes[x, y] = currentNode; currentNode.Position = new Vector2Int(x, y); int prevX = x - 1; int prevY = y - 1; int nextY = y + 1; if (prevX >= 0) { connectionNode = nodes[prevX, y]; ConnectNodes(currentNode, connectionNode, 1); } if (prevY >= 0) { connectionNode = nodes[x, prevY]; ConnectNodes(currentNode, connectionNode, 1); } if (prevX >= 0 && prevY >= 0 && neighbourMode == NeighbourMode.SidesAndDiagonals) { connectionNode = nodes[prevX, prevY]; ConnectNodes(currentNode, connectionNode, Sqrt2); } if (nextY < map.Height && prevX >= 0 && neighbourMode == NeighbourMode.SidesAndDiagonals) { connectionNode = nodes[prevX, nextY]; ConnectNodes(currentNode, connectionNode, Sqrt2); } } else { nodes[x, y] = null; } } } WeightedGraph <double> weightedGraph = new WeightedGraph <double>(nodes, Double.PositiveInfinity); return(weightedGraph); ; }
private static void ConnectNodes(WeightedGraphNode <double> nodeA, WeightedGraphNode <double> nodeB, double weight) { if (nodeA == null || nodeB == null) { return; } nodeA.SetWeight(nodeB, weight); nodeB.SetWeight(nodeA, weight); }
private static void MakeKruskals() { var A = new WeightedGraphNode <char>('A'); var B = new WeightedGraphNode <char>('B'); var C = new WeightedGraphNode <char>('C'); var D = new WeightedGraphNode <char>('D'); var E = new WeightedGraphNode <char>('E'); var F = new WeightedGraphNode <char>('F'); A.AddMutualNeighbor(B, 1); A.AddMutualNeighbor(D, 2); B.AddMutualNeighbor(D, 4); B.AddMutualNeighbor(C, 2); C.AddMutualNeighbor(D, 3); C.AddMutualNeighbor(E, 4); C.AddMutualNeighbor(F, 5); E.AddMutualNeighbor(F, 1); var G = new Graph <char>(A, B, C, D, E, F); var MSF_G = G.KruskalsAlgorithmForMinimumSpanningForest(); var edges = MSF_G.GetEdgeList(); foreach (var edge in edges) { if (edge.Node1.GetValue().CompareTo(edge.Node2.GetValue()) > 0) { Console.WriteLine(edge.FlipDirection().ToString()); } else { Console.WriteLine(edge.ToString()); } } }
/// <summary> /// Runs an A* search to solve the board using manhattan distance as the heuristic function. /// </summary> /// <param name="initial_state"></param> /// <param name="IsGreedy">Whether or not to use greedy best-first search instead of A*.</param> /// <returns></returns> public static NodePath <GameBoard> A_Star_Search(GameBoard initial_state, bool IsGreedy) { IPriorityQueue <WeightedNodePath <GameBoard> > priQueue = new Heap <WeightedNodePath <GameBoard> >(2000); WeightedGraphNode <GameBoard> starting_path = new WeightedGraphNode <GameBoard>(initial_state); var foundBoards = new HashSet <uint>(); var Start = new WeightedNodePath <GameBoard>(starting_path, null, 0); priQueue.Enqueue(Start); int totalProcessed = 0; while (!priQueue.IsEmpty()) { WeightedNodePath <GameBoard> cur = priQueue.Dequeue(); GameBoard top_gb = cur.Node.GetValue(); if (foundBoards.Contains(top_gb.GetHashValue())) { continue; } totalProcessed++; if (top_gb.IsSolved) { Console.WriteLine("Solved Path Length of {0} with {1} boards revealed", cur.PathLength, totalProcessed); return(cur); } //add to marked foundBoards.Add(top_gb.GetHashValue()); int nextPathLength = cur.PathLength + 1; //add all new nodes to the stack foreach (var neighbor in top_gb.GetAllNeighborBoards()) { if (foundBoards.Contains(neighbor.GetHashValue())) { continue; } double new_cost; if (IsGreedy) { //cost ~= h(x) new_cost = neighbor.GetSigmaManhattanDistance(); } else { //cost = h(x) + g(x) new_cost = neighbor.GetSigmaManhattanDistance() + nextPathLength; } var n_wgn = new WeightedGraphNode <GameBoard>(neighbor); priQueue.Enqueue(new WeightedNodePath <GameBoard>(n_wgn, cur, new_cost, nextPathLength)); } if (priQueue.IsEmpty()) { Console.WriteLine("foobar!"); } } Console.WriteLine("foobar!"); return(null); }
public void GetWeightedGraphTest() { int width = _rnd.Next(10, 20); int height = _rnd.Next(10, 20); NeighbourMode neighbourMode = NeighbourMode.SidesAndDiagonals; MemoryCellFragment cellFragment = new MemoryCellFragment(width, height); FillRandom(cellFragment); WeightedGraph <double> weightedGraph = GraphGenerator.GetWeightedGraph(cellFragment, neighbourMode); if (weightedGraph.Width != width) { Assert.Fail("Graph width is incorrect"); } if (weightedGraph.Height != height) { Assert.Fail("Graph height is incorrect"); } Vector2Int[] steps = Steps.GetSteps(neighbourMode); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { WeightedGraphNode <double> node = (WeightedGraphNode <double>)weightedGraph[i, j]; bool cellPassable = cellFragment[i, j]; if (node == null) { if (cellPassable) { Assert.Fail($"Cell ({i}, {j}) is passable, but node does not exist"); } continue; } int connectedCellsCount = 0; foreach (var step in steps) { int xShift = i + step.X; int yShift = j + step.Y; bool stepInBounds = cellFragment.IsInBounds(xShift, yShift); bool stepPassable = stepInBounds && cellFragment.IsPassable(xShift, yShift); Debug.WriteLine($"Position: {node.Position}, Step: {step}, Neighbour: {node.Position + step}"); WeightedGraphNode <double> connection = (WeightedGraphNode <double>)GetConnection(node, step); if (stepPassable) { connectedCellsCount++; if (connection == null || double.IsInfinity(connection.GetWeight(node))) { Assert.Fail($"Node {node.Position} is not connected to position ({xShift}, {yShift}), that is passable"); } } else { if (connection != null && !double.IsInfinity(connection.GetWeight(node))) { Assert.Fail($"Node {node.Position} is connected to position ({xShift}, {yShift}), that is not passable"); } } } if (node.Connections.Count != connectedCellsCount) { Assert.Fail("Number of connected nodes is incorrect"); } } } }
static int heuristic(WeightedGraphNode <string> node) { var wcgn = (WeightedCoordinateGraphNode <string>)node; return(Math.Abs(wcgn.X - 19) + Math.Abs(wcgn.Y - 45)); }