Beispiel #1
0
        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();
            }
        }
Beispiel #2
0
        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");
            }
        }
Beispiel #3
0
        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);

            ;
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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());
                }
            }
        }
Beispiel #6
0
        /// <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));
            }