Пример #1
0
        public void DijkstraUnconnected()
        {
            // 0 -- 1    2 -- 3
            //           |   /
            //           | /
            //      4 -- 5
            bool[,] graph2 =
            {
                { false, true,  false, false, false, false },
                { true,  false, false, false, false, false },
                { false, false, false, true,  false, true  },
                { false, false, true,  false, false, true  },
                { false, false, false, false, false, true  },
                { false, false, true,  true,  true,  false },
            };
            SearchGraph searchGraph2 = SearchGraphFromData(graph2);
            Dictionary <int, GraphNode> graphNodes2 = GetGraphNodesIdIndex(searchGraph2);
            var mstNodes2 = new List <GraphNode> {
                graphNodes2[0], graphNodes2[2], graphNodes2[4], graphNodes2[3]
            };

            var distances = new DistanceLookup(graphNodes2.Values.ToArray());

            Assert.IsNull(distances.GetShortestPath(mstNodes2[0].DistancesIndex, mstNodes2[3].DistancesIndex));
        }
Пример #2
0
        public void DijkstraUnconnected()
        {
            // 0 -- 1    2 -- 3
            //           |   /
            //           | /
            //      4 -- 5
            bool[,] graph2 =
            {
                { false, true,  false, false, false, false },
                { true,  false, false, false, false, false },
                { false, false, false, true,  false, true  },
                { false, false, true,  false, false, true  },
                { false, false, false, false, false, true  },
                { false, false, true,  true,  true,  false },
            };
            SearchGraph searchGraph2 = SearchGraphFromData(graph2);
            Dictionary <int, GraphNode> graphNodes2 = GetGraphNodesIdIndex(searchGraph2);
            var mstNodes2 = new List <GraphNode> {
                graphNodes2[0], graphNodes2[2], graphNodes2[4], graphNodes2[3]
            };

            var distances = new DistanceLookup();

            try
            {
                var _ = distances[mstNodes2[0], mstNodes2[3]];
            }
            catch (GraphNotConnectedException)
            {
                return;
            }
            Assert.Fail("No exception thrown for disconnected graph");
        }
Пример #3
0
        /// <summary>
        ///  Preprocesses the SkillTree graph into a simplified graph that omits
        ///  nodes (single pass) and contracts all skilled nodes into a single node.
        /// </summary>
        private void BuildSearchGraph()
        {
            // Make all directed edges from Scion Ascendant "Path of the ..." node undirected.
            // This is really dirty but the whole code is so dependant on the skill tree stuff that
            // I don't see a non dirty way.
            var ascendantClassStartNodes = SkillTree.Skillnodes.Values.Where(SkillTree.IsAscendantClassStartNode).ToList();

            foreach (var classStartNode in ascendantClassStartNodes)
            {
                foreach (var neighbor in classStartNode.Neighbor)
                {
                    neighbor.Neighbor.Add(classStartNode);
                }
            }

            var searchGraph = new SearchGraph();

            CreateStartNodes(searchGraph);
            CreateTargetNodes(searchGraph);
            CreateSearchGraph(searchGraph);
            AllNodes = searchGraph.NodeDict.Values.ToList();

            // Remove all added edges again.
            foreach (var classStartNode in ascendantClassStartNodes)
            {
                foreach (var neighbor in classStartNode.Neighbor)
                {
                    neighbor.Neighbor.Remove(classStartNode);
                }
            }
        }
Пример #4
0
 /// <summary>
 /// Initializes <see cref="TargetNodes"/> with all check-tagged nodes and the start node.
 /// Adds the check-tagged nodes to the provided SearchGraph.
 /// </summary>
 private void CreateTargetNodes(SearchGraph searchGraph)
 {
     TargetNodes = (from node in Settings.Checked
                    where !searchGraph.NodeDict.ContainsKey(node)
                    select searchGraph.AddNodeId(node.Id))
                   .Union(new[] { StartNode }).ToList();
 }
Пример #5
0
        // Builds a graph from an adjacency matrix.
        // Only the lower left half is checked.
        SearchGraph SearchGraphFromData(bool[,] adjacencyMatrix)
        {
            int n = adjacencyMatrix.GetUpperBound(0) + 1;
            // Don't screw this up.
            Assert.IsTrue(n == adjacencyMatrix.GetUpperBound(1) + 1);

            List<SkillNode> nodes = new List<SkillNode>();
            for (int i = 0; i < n; i++)
            {
                SkillNode node = new SkillNode();
                node.Id = (ushort)i;
                nodes.Add(node);
            }

            for (int i = 0; i < n; i++)
            {
                nodes[i].Neighbor = new List<SkillNode>();
                for (int j = 0; j < i; j++)
                {
                    if (adjacencyMatrix[i, j])
                    {
                        nodes[i].Neighbor.Add(nodes[j]);
                        // No directed edges atm.
                        nodes[j].Neighbor.Add(nodes[i]);
                    }
                }
            }

            SearchGraph graph = new SearchGraph();
            foreach (SkillNode node in nodes)
            {
                graph.AddNode(node);
            }
            return graph;
        }
Пример #6
0
        public void TestDijkstra()
        {
            // TODO: Maybe make the graphs class members.
            /// 0 -- 1 -- 2 -- 3
            ///  \        |   /
            ///    \      | /
            ///      4 -- 5
            bool[,] graph1 =
            {
                { false, true,  false, false, true,  false },
                { true,  false, true,  false, false, false },
                { false, true,  false, true,  false, true  },
                { false, false, true,  false, false, true  },
                { true,  false, false, false, false, true  },
                { false, false, true,  true,  true,  false },
            };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary <int, GraphNode> graphNodes = GetGraphNodesIdIndex(searchGraph1);


            DistanceLookup distanceLookup = new DistanceLookup();

            Assert.IsTrue(distanceLookup.GetDistance(graphNodes[0], graphNodes[0]) == 0, "Failed 0 distance test");
            Assert.IsTrue(distanceLookup.GetDistance(graphNodes[0], graphNodes[5]) == 2, "Wrong distance");
            Assert.IsTrue(distanceLookup.GetDistance(graphNodes[0], graphNodes[3]) == 3, "Wrong distance");
        }
Пример #7
0
        /// <summary>
        ///  Preprocesses the SkillTree graph into a simplified graph that omits
        ///  nodes (single pass) and contracts all skilled nodes into a single node.
        /// </summary>
        private void BuildSearchGraph()
        {
            // Make all directed edges from Scion Ascendant "Path of the ..." node undirected.
            // This is really dirty but the whole code is so dependant on the skill tree stuff that
            // I don't see a non dirty way.
            var ascendantClassStartNodes = SkillTree.Skillnodes.Values.Where(SkillTree.IsAscendantClassStartNode).ToList();

            foreach (var classStartNode in ascendantClassStartNodes)
            {
                foreach (var neighbor in classStartNode.Neighbor)
                {
                    neighbor.Neighbor.Add(classStartNode);
                }
            }

            _searchGraph = new SearchGraph();
            CreateStartNodes();
            CreateTargetNodes();
            // Set start and target nodes as the fixed nodes.
            _fixedNodes = new HashSet <ushort>(StartNodes.Nodes);
            _fixedNodes.UnionWith(_targetNodes.Select(node => node.Id));
            OnStartAndTargetNodesCreated();
            CreateSearchGraph();

            // Remove all added edges again.
            foreach (var classStartNode in ascendantClassStartNodes)
            {
                foreach (var neighbor in classStartNode.Neighbor)
                {
                    neighbor.Neighbor.Remove(classStartNode);
                }
            }
        }
Пример #8
0
        public void TestDijkstra()
        {
            // 0 -- 1 -- 2 -- 3
            //  \        |   /
            //    \      | /
            //      4 -- 5
            bool[,] graph1 =
            {
                { false, true,  false, false, true,  false },
                { true,  false, true,  false, false, false },
                { false, true,  false, true,  false, true  },
                { false, false, true,  false, false, true  },
                { true,  false, false, false, false, true  },
                { false, false, true,  true,  true,  false },
            };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary <int, GraphNode> graphNodes = GetGraphNodesIdIndex(searchGraph1);


            DistanceLookup distanceLookup = new DistanceLookup(graphNodes.Values.ToList());

            Assert.AreEqual((uint)0, distanceLookup[graphNodes[0].DistancesIndex, graphNodes[0].DistancesIndex], "Failed 0 distance test");
            Assert.AreEqual((uint)2, distanceLookup[graphNodes[0].DistancesIndex, graphNodes[5].DistancesIndex], "Wrong distance");
            Assert.AreEqual((uint)3, distanceLookup[graphNodes[0].DistancesIndex, graphNodes[3].DistancesIndex], "Wrong distance");
        }
Пример #9
0
 Dictionary<int, GraphNode> GetGraphNodesIdIndex(SearchGraph graph)
 {
     Dictionary<int, GraphNode> retval = new Dictionary<int, GraphNode>();
     foreach (GraphNode node in graph.NodeDict.Values)
     {
         retval.Add(node.Id, node);
     }
     return retval;
 }
Пример #10
0
        Dictionary <int, GraphNode> GetGraphNodesIdIndex(SearchGraph graph)
        {
            Dictionary <int, GraphNode> retval = new Dictionary <int, GraphNode>();

            foreach (GraphNode node in graph.NodeDict.Values)
            {
                retval.Add(node.Id, node);
            }
            return(retval);
        }
Пример #11
0
 /// <summary>
 ///  Preprocesses the SkillTree graph into a simplified graph that omits
 ///  nodes (single pass) and contracts all skilled nodes into a single node.
 /// </summary>
 private void BuildSearchGraph()
 {
     _searchGraph = new SearchGraph();
     CreateStartNodes();
     CreateTargetNodes();
     // Set start and target nodes as the fixed nodes.
     _fixedNodes = new HashSet <ushort>(StartNodes.Nodes);
     _fixedNodes.UnionWith(_targetNodes.Select(node => node.Id));
     OnStartAndTargetNodesCreated();
     CreateSearchGraph();
 }
Пример #12
0
 /// <summary>
 /// Initializes <see cref="StartNode"/> and sets the start node in the provided SearchGraph.
 /// </summary>
 private void CreateStartNodes(SearchGraph searchGraph)
 {
     if (Settings.SubsetTree.Count > 0 || Settings.InitialTree.Count > 0)
     {
         // if the current tree does not need to be part of the result, only skill the character node
         StartNode = searchGraph.SetStartNodes(new[] { _tree.GetCharNode() });
     }
     else
     {
         StartNode = searchGraph.SetStartNodes(_tree.SkilledNodes);
     }
 }
Пример #13
0
        public void TestMST()
        {
            // 0 -- 1 -- 2 -- 3
            //  \        |   /
            //    \      | /
            //      4 -- 5 -- 6 -- 7
            bool[,] graph1 =
            {
                { false, true,  false, false, true,  false, false, false },
                { true,  false, true,  false, false, false, false, false },
                { false, true,  false, true,  false, true,  false, false },
                { false, false, true,  false, false, true,  false, false },
                { true,  false, false, false, false, true,  false, false },
                { false, false, true,  true,  true,  false, true,  false },
                { false, false, false, false, false, true,  false, true  },
                { false, false, false, false, false, false, true,  false },
            };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary <int, GraphNode> graphNodes1 = GetGraphNodesIdIndex(searchGraph1);
            var distances = new DistanceLookup();

            var mstNodes1 = new List <GraphNode>
            {
                graphNodes1[3], graphNodes1[5], graphNodes1[7], graphNodes1[0]
            };

            distances.CalculateFully(mstNodes1);
            MinimalSpanningTree mst1 = new MinimalSpanningTree(mstNodes1, distances);

            mst1.Span(graphNodes1[0]);

            Assert.AreEqual(3, mst1.SpanningEdges.Count, "Wrong amount of spanning edges");
            var goalEdges = new []
            {
                new [] { 0, 5 }, new [] { 5, 3 }, new [] { 5, 7 }
            };

            foreach (var edge in goalEdges)
            {
                Assert.AreEqual(1,
                                mst1.SpanningEdges.Count(
                                    e =>
                                    (e.Inside.Id == edge[0] && e.Outside.Id == edge[1]) ||
                                    (e.Inside.Id == edge[1] && e.Outside.Id == edge[0])),
                                "Edge " + edge + " not contained exactly once.");
            }
            Assert.AreEqual(6, mst1.GetUsedNodes().Count, "Wrong MST length");
        }
Пример #14
0
        /// <summary>
        /// Задание 3
        /// </summary>
        private static void Task3()
        {
            CL.BeginApp("Функция обхода графа в ширину");

            string filename = @"..\..\..\TxtFiles\WorkMatrix.txt";

            int[,] matrix = ReadMatrix.Read(filename);
            CL.PrintArr(matrix);
            SearchGraph search = new SearchGraph();

            search.BFS(matrix);
            //SearchGraph.BFS(matrix);
            CL.ConsolePause();
            Menu();
        }
Пример #15
0
        public void TestMST()
        {
            // 0 -- 1 -- 2 -- 3
            //  \        |   /
            //    \      | /
            //      4 -- 5 -- 6 -- 7
            bool[,] graph1 =
            {
                { false, true,  false, false, true,  false, false, false },
                { true,  false, true,  false, false, false, false, false },
                { false, true,  false, true,  false, true,  false, false },
                { false, false, true,  false, false, true,  false, false },
                { true,  false, false, false, false, true,  false, false },
                { false, false, true,  true,  true,  false, true,  false },
                { false, false, false, false, false, true,  false, true  },
                { false, false, false, false, false, false, true,  false },
            };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary <int, GraphNode> graphNodes1 = GetGraphNodesIdIndex(searchGraph1);

            var mstNodes1 = new List <GraphNode>
            {
                graphNodes1[3], graphNodes1[5], graphNodes1[7], graphNodes1[0]
            };
            var distances = new DistanceLookup(mstNodes1);
            var mst1      = new MinimalSpanningTree(mstNodes1.Select(n => n.DistancesIndex).ToList(), distances);

            mst1.Span(graphNodes1[0].DistancesIndex);

            Assert.AreEqual(3, mst1.SpanningEdges.Count, "Wrong amount of spanning edges");
            var goalEdges = new[]
            {
                new [] { 0, 5 }, new [] { 5, 3 }, new [] { 5, 7 }
            };

            foreach (var edge in goalEdges)
            {
                Assert.AreEqual(1,
                                mst1.SpanningEdges.Select(e => new Tuple <ushort, ushort>(distances.IndexToNode(e.Inside).Id, distances.IndexToNode(e.Outside).Id)).Count(
                                    t =>
                                    (t.Item1 == edge[0] && t.Item2 == edge[1]) ||
                                    (t.Item1 == edge[1] && t.Item2 == edge[0])),
                                "Edge " + edge + " not contained exactly once.");
            }
        }
        protected internal virtual void localStart()
        {
            SearchGraph searchGraph = this.linguist.getSearchGraph();

            this.currentFrameNumber    = 0;
            this.curTokensScored.value = (double)0f;
            this.numStateOrder         = searchGraph.getNumStateOrder();
            this.activeListManager.setNumStateOrder(this.numStateOrder);
            if (this.buildWordLattice)
            {
                this.loserManager = new AlternateHypothesisManager(this.maxLatticeEdges);
            }
            SearchState initialState = searchGraph.getInitialState();

            this.activeList = this.activeListManager.getEmittingList();
            this.activeList.add(new Token(initialState, -1L));
            this.clearCollectors();
            this.growBranches();
            this.growNonEmittingBranches();
        }
Пример #17
0
        // Builds a graph from an adjacency matrix.
        // Only the lower left half is checked.
        private static SearchGraph SearchGraphFromData(bool[,] adjacencyMatrix)
        {
            int n = adjacencyMatrix.GetUpperBound(0) + 1;

            // Don't screw this up.
            Assert.IsTrue(n == adjacencyMatrix.GetUpperBound(1) + 1);

            List <SkillNode> nodes = new List <SkillNode>();

            for (ushort i = 0; i < n; i++)
            {
                var node = new SkillNode {
                    Id = i
                };
                nodes.Add(node);
            }

            for (int i = 0; i < n; i++)
            {
                nodes[i].Neighbor = new List <SkillNode>();
                for (int j = 0; j < i; j++)
                {
                    if (adjacencyMatrix[i, j])
                    {
                        nodes[i].Neighbor.Add(nodes[j]);
                        // No directed edges atm.
                        nodes[j].Neighbor.Add(nodes[i]);
                    }
                }
            }

            SearchGraph graph = new SearchGraph();

            foreach (SkillNode node in nodes)
            {
                graph.AddNode(node);
            }
            return(graph);
        }
Пример #18
0
        // Builds a graph from an adjacency matrix.
        // Only the lower left half is checked.
        private static SearchGraph SearchGraphFromData(bool[,] adjacencyMatrix)
        {
            int n = adjacencyMatrix.GetUpperBound(0) + 1;

            // Don't screw this up.
            Assert.IsTrue(n == adjacencyMatrix.GetUpperBound(1) + 1);

            List <PassiveNodeViewModel> nodes = new List <PassiveNodeViewModel>();

            for (ushort i = 0; i < n; i++)
            {
                var node = new PassiveNodeViewModel(i);
                nodes.Add(node);
            }

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (adjacencyMatrix[i, j])
                    {
                        nodes[i].NeighborPassiveNodes[nodes[j].Id] = nodes[j];
                        // No directed edges atm.
                        nodes[j].NeighborPassiveNodes[nodes[i].Id] = nodes[i];
                    }
                }
            }

            SearchGraph graph = new SearchGraph();

            foreach (PassiveNodeViewModel node in nodes)
            {
                graph.AddNode(node);
            }
            return(graph);
        }
Пример #19
0
        /// <summary>
        /// Initializes the search graph by going through all node groups
        /// of the skill tree and including those that could be part of the solution.
        /// </summary>
        private void CreateSearchGraph(SearchGraph searchGraph)
        {
            foreach (var ng in SkillTree.NodeGroups)
            {
                var mustInclude = false;

                SkillNode firstNeighbor = null;

                // Find out if this node group can be omitted.
                foreach (var node in ng.Nodes)
                {
                    // If the group contains a skilled node or a target node,
                    // it can't be omitted.
                    if (searchGraph.NodeDict.ContainsKey(node) ||
                        MustIncludeNodeGroup(node))
                    {
                        mustInclude = true;
                        break;
                    }

                    // If the group is adjacent to more than one node, it must
                    // also be fully included (since it's not isolated and could
                    // be part of a path to other nodes).
                    var ng1 = ng;
                    foreach (var neighbor in node.Neighbor.Where(neighbor => neighbor.SkillNodeGroup != ng1))
                    {
                        if (firstNeighbor == null)
                        {
                            firstNeighbor = neighbor;
                        }

                        // Does the group have more than one neighbor?
                        if (neighbor != firstNeighbor)
                        {
                            mustInclude = true;
                            break;
                        }
                    }
                    if (mustInclude)
                    {
                        break;
                    }
                }

                if (mustInclude)
                {
                    // Add the group's nodes individually
                    foreach (var node in ng.Nodes)
                    {
                        // Can't path through class starts.
                        if (node.IsRootNode
                            // Don't add nodes that are already in the graph (as
                            // target or start nodes).
                            || searchGraph.NodeDict.ContainsKey(node)
                            // Don't add nodes that should not be skilled.
                            || Settings.Crossed.Contains(node)
                            // Mastery nodes are obviously not useful.
                            || node.Type == PassiveNodeType.Mastery
                            // Ignore ascendancies for now
                            || node.ascendancyName != null)
                        {
                            continue;
                        }

                        if (IncludeNodeInSearchGraph(node))
                        {
                            searchGraph.AddNode(node);
                        }
                    }
                }
            }
        }
Пример #20
0
        public void TestMST()
        {
            /// 0 -- 1 -- 2 -- 3
            ///  \        |   /
            ///    \      | /
            ///      4 -- 5 -- 6 -- 7
            bool[,] graph1 =
            {
                { false, true,  false, false, true,  false, false, false },
                { true,  false, true,  false, false, false, false, false },
                { false, true,  false, true,  false, true,  false, false },
                { false, false, true,  false, false, true,  false, false },
                { true,  false, false, false, false, true,  false, false },
                { false, false, true,  true,  true,  false, true,  false },
                { false, false, false, false, false, true,  false, true  },
                { false, false, false, false, false, false, true,  false },
            };

            SearchGraph searchGraph1 = SearchGraphFromData(graph1);

            Dictionary <int, GraphNode> graphNodes1 = GetGraphNodesIdIndex(searchGraph1);
            DistanceLookup distanceLookup           = new DistanceLookup();

            HashSet <GraphNode> mstNodes1 = new HashSet <GraphNode>
            {
                graphNodes1[3], graphNodes1[5], graphNodes1[7]
            };
            MinimalSpanningTree mst1 = new MinimalSpanningTree(mstNodes1);

            mst1.Span(startFrom: graphNodes1[0]);

            Assert.IsTrue(mst1.SpanningEdges.Count == 3, "Wrong amount of spanning edges");
            /// This can fail even if the mst would be valid! The test only works for
            /// the current implementation of the mst algorithm, but I can't find a
            /// better way to do this with the current data structures...
            Assert.IsTrue(mst1.SpanningEdges[0].inside.Id == 0 && mst1.SpanningEdges[0].outside.Id == 5,
                          "First edge is wrong");
            Assert.IsTrue(mst1.SpanningEdges[1].inside.Id == 5 && mst1.SpanningEdges[1].outside.Id == 3,
                          "Second edge is wrong");
            Assert.IsTrue(mst1.SpanningEdges[2].inside.Id == 5 && mst1.SpanningEdges[2].outside.Id == 7,
                          "Third edge is wrong");
            Assert.IsTrue(mst1.UsedNodeCount == 5, "Wrong MST length");


            /// Test unconnected graph

            /// 0 -- 1    2 -- 3
            ///           |   /
            ///           | /
            ///      4 -- 5
            bool[,] graph2 =
            {
                { false, true,  false, false, false, false },
                { true,  false, false, false, false, false },
                { false, false, false, true,  false, true  },
                { false, false, true,  false, false, true  },
                { false, false, false, false, false, true  },
                { false, false, true,  true,  true,  false },
            };
            SearchGraph searchGraph2 = SearchGraphFromData(graph2);
            Dictionary <int, GraphNode> graphNodes2 = GetGraphNodesIdIndex(searchGraph2);
            HashSet <GraphNode>         mstNodes2   = new HashSet <GraphNode> {
                graphNodes2[0], graphNodes2[2], graphNodes2[4]
            };

            bool pass = false;

            try
            {
                MinimalSpanningTree mst = new MinimalSpanningTree(mstNodes2);
                mst.Span(graphNodes2[3]);
            }
            catch (DistanceLookup.GraphNotConnectedException)
            {
                pass = true;
            }
            Assert.IsTrue(pass, "No exception thrown for disconnected graph");
        }
Пример #21
0
 /// <summary>
 /// Initializes <see cref="StartNode"/> and sets the start node in the provided SearchGraph.
 /// </summary>
 private void CreateStartNodes(SearchGraph searchGraph)
 {
     StartNode = searchGraph.SetStartNodes(_tree.SkilledNodes);
 }
Пример #22
0
 private static Dictionary <ushort, GraphNode> GetGraphNodesIdIndex(SearchGraph graph)
 => graph.NodeDict.Values.ToDictionary(n => n.Id);