示例#1
0
        public void CreateEmptyGraphAndAddVertices()
        {
            var graph = new UndirectedGraph();

            Assert.AreEqual(0, graph.Vertices());
            Assert.AreEqual(0, graph.Edges());

            int vertex1id = graph.AddVertex();
            int vertex2id = graph.AddVertex();

            Assert.AreEqual(0, vertex1id);
            Assert.AreEqual(1, vertex2id);

            graph.AddEdge(0, 1);
            Assert.AreEqual(2, graph.Vertices());
            Assert.AreEqual(1, graph.Edges());
            Assert.IsTrue(graph.AdjacentVertices(0).Contains(1));
            Assert.IsTrue(graph.AdjacentVertices(1).Contains(0));

            // add the same edge again
            graph.AddEdge(0, 1);
            Assert.AreEqual(2, graph.Vertices());
            Assert.AreEqual(2, graph.Edges());
            Assert.IsTrue(graph.AdjacentVertices(0).Contains(1));
            Assert.IsTrue(graph.AdjacentVertices(1).Contains(0));
        }
        private List <UndirectedGraph <int, IEdge <int> > > FindComponents(UndirectedGraph <int, IEdge <int> > g)
        {
            List <UndirectedGraph <int, IEdge <int> > > components = new List <UndirectedGraph <int, IEdge <int> > >();
            HashSet <int> vertices = g.Vertices.ToHashSet();

            while (vertices.Count > 0)
            {
                UndirectedGraph <int, IEdge <int> > component = new UndirectedGraph <int, IEdge <int> >(false);
                Queue <int> queue = new Queue <int>();
                int         v     = vertices.First();
                vertices.Remove(v);
                queue.Enqueue(v);
                component.AddVertex(v);
                while (queue.Count > 0)
                {
                    v = queue.Dequeue();
                    foreach (int n in g.AdjacentVertices(v))
                    {
                        if (vertices.Contains(n))
                        {
                            component.AddVertex(n);
                            queue.Enqueue(n);
                            vertices.Remove(n);
                        }
                        component.AddEdge(new Edge <int>(v, n));
                    }
                }
                components.Add(component);
            }
            return(components);
        }
示例#3
0
            private bool TryColors(int vertex)
            {
                if (vertex == graph.VertexCount)
                {
                    return(true);
                }
                var available = new SortedSet <GraphColor> {
                    GraphColor.White, GraphColor.Gray, GraphColor.Black
                };

                foreach (int v in graph.AdjacentVertices(vertex))
                {
                    if (coloring[v] is not null)
                    {
                        available.Remove(coloring[v].Value);
                    }
                }

                var next = vertex + 1;

                foreach (GraphColor c in available)
                {
                    coloring[vertex] = c;
                    if (TryColors(next))
                    {
                        return(true);
                    }
                }
                coloring[vertex] = null;
                return(false);
            }
示例#4
0
        public void CreateGraphWithSelfLoops()
        {
            var graph = new UndirectedGraph(1);

            Assert.AreEqual(1, graph.Vertices());
            Assert.AreEqual(0, graph.Edges());

            graph.AddEdge(0, 0);
            Assert.AreEqual(1, graph.Edges());
            Assert.IsTrue(graph.AdjacentVertices(0).Contains(0));
        }
        Triangulate(UndirectedGraph <int, IEdge <int> > tree, int root = 0)
        {
            Dictionary <(int source, int target), int> innerVerticesCount = new Dictionary <(int source, int target), int>();
            UndirectedGraph <int, IEdge <int> >        res = new UndirectedGraph <int, IEdge <int> >();

            if (tree.IsVerticesEmpty)
            {
                return(res, innerVerticesCount);
            }
            if (!tree.ContainsVertex(root))
            {
                throw new ArgumentException("root");
            }

            // create counter-clockwise combinatorial embedding
            // assumes vertices are numbered as in BFS
            // so it's proper to add them to list in order they are stored internally
            UndirectedGraph <int, IEdge <int> > G         = tree.Clone();
            Dictionary <int, List <int> >       embedding = new Dictionary <int, List <int> >(); // TODO: what if graph vertices are only subgraph? this assumption may be wrong

            foreach (int i in G.Vertices)
            {
                embedding.Add(i, new List <int>());
                foreach (int v in G.AdjacentVertices(i))
                {
                    embedding[i].Add(v);
                }
            }

            foreach (int v in tree.Vertices)
            {
                int[] neighbors = new int[embedding[v].Count];
                embedding[v].CopyTo(neighbors);

                int prev = neighbors[0];
                for (int i = 1; i < neighbors.Length; i++)
                {
                    int curr = neighbors[i];
                    TryAddEdge(prev, curr, v, ref G, ref res, ref embedding, ref innerVerticesCount);
                    prev = curr;
                }
                if (neighbors.Length > 2)
                {
                    TryAddEdge(prev, neighbors[0], v, ref G, ref res, ref embedding, ref innerVerticesCount);
                }
            }

            return(res, innerVerticesCount);
        }
示例#6
0
 private bool existsInGraph(List <TVertex> path)
 {
     if (path.Count > 1)
     {
         path.Add(path[0]);      // make cycle, not simple path
     }
     for (int i = 0; i < path.Count() - 1; i++)
     {
         if (!graph.AdjacentVertices(path[i]).Contains(path[i + 1]))
         {
             return(false);
         }
     }
     return(true);
 }
示例#7
0
        public void AdjacentVertices()
        {
            var graph = new UndirectedGraph <int, Edge <int> >();

            var edge12    = new Edge <int>(1, 2);
            var edge13    = new Edge <int>(1, 3);
            var edge13Bis = new Edge <int>(1, 3);
            var edge14    = new Edge <int>(1, 4);
            var edge24    = new Edge <int>(2, 4);
            var edge31    = new Edge <int>(3, 1);
            var edge33    = new Edge <int>(3, 3);
            var edge51    = new Edge <int>(5, 1);
            var edge65    = new Edge <int>(6, 5);
            var edge66    = new Edge <int>(6, 6);

            graph.AddVertex(7);
            graph.AddVerticesAndEdgeRange(new[]
            {
                edge12, edge13, edge13Bis,
                edge14, edge24, edge31, edge33,
                edge51, edge65, edge66
            });

            CollectionAssert.AreEquivalent(
                new[] { 2, 3, 4, 5 },
                graph.AdjacentVertices(1));

            CollectionAssert.AreEquivalent(
                new[] { 1, 4 },
                graph.AdjacentVertices(2));

            CollectionAssert.AreEquivalent(
                new[] { 1 },
                graph.AdjacentVertices(3));

            CollectionAssert.AreEquivalent(
                new[] { 1, 2 },
                graph.AdjacentVertices(4));

            CollectionAssert.AreEquivalent(
                new[] { 1, 6 },
                graph.AdjacentVertices(5));

            CollectionAssert.AreEquivalent(
                new[] { 5 },
                graph.AdjacentVertices(6));

            CollectionAssert.IsEmpty(graph.AdjacentVertices(7));
        }
示例#8
0
        private bool ExistsInGraph([NotNull, ItemNotNull] List <TVertex> path)
        {
            if (path.Count > 1)
            {
                path.Add(path[0]);      // Make cycle, not simple path
            }

            for (int i = 0; i < path.Count - 1; i++)
            {
                if (!_graph.AdjacentVertices(path[i]).Contains(path[i + 1]))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#9
0
        public void CreateGraphWithPresetAmountOfVertices()
        {
            // a cube
            var graph = new UndirectedGraph(4);

            graph.AddEdge(0, 1);
            graph.AddEdge(1, 2);
            graph.AddEdge(2, 3);
            graph.AddEdge(3, 0);

            Assert.AreEqual(4, graph.Vertices());
            Assert.AreEqual(4, graph.Edges());
            Assert.IsTrue(graph.AdjacentVertices(0).Contains(1));
            Assert.IsTrue(graph.AdjacentVertices(0).Contains(3));
            Assert.IsTrue(graph.AdjacentVertices(1).Contains(0));
            Assert.IsTrue(graph.AdjacentVertices(1).Contains(2));
            Assert.IsTrue(graph.AdjacentVertices(2).Contains(1));
            Assert.IsTrue(graph.AdjacentVertices(2).Contains(3));
            Assert.IsTrue(graph.AdjacentVertices(3).Contains(2));
            Assert.IsTrue(graph.AdjacentVertices(3).Contains(0));
        }
示例#10
0
        List <List <string> > PathsToEnd(string from, List <List <string> > paths, List <string> path, bool checkCount = false)
        {
            var thisPath = path.ToList();

            thisPath.Add(from);

            var nodes = _graph.AdjacentVertices(from);

            foreach (var node in nodes)
            {
                if (char.IsLower(node[0]) && thisPath.Contains(node))
                {
                    if (!checkCount)
                    {
                        continue;
                    }

                    var maxCountReached = thisPath.Where(c => char.IsLower(c[0])).GroupBy(s => s).Any(g => g.Count() == 2);

                    if (node == "start" || node == "end" || maxCountReached)
                    {
                        continue;
                    }
                }

                if (node == "end")
                {
                    var x = thisPath.ToList();
                    x.Add(node);
                    paths.Add(x);
                    continue;
                }

                PathsToEnd(node, paths, thisPath, checkCount);
            }

            return(paths);
        }
示例#11
0
        public void AdjacentVertices_Throws()
        {
            var graph = new UndirectedGraph <int, Edge <int> >();

            Assert.Throws <VertexNotFoundException>(() => graph.AdjacentVertices(10));
        }
    void GenerateLanes()
    {
        foreach (Node node in graph.Vertices)
        {
            IOrderedEnumerable <Node> orderedNodes    = graph.Vertices.OrderBy(nodeToOrder => CartezianPosition.CalculateDistance(node.position, nodeToOrder.position));
            IEnumerator <Node>        enumeratorNodes = orderedNodes.GetEnumerator();
            enumeratorNodes.MoveNext();
            enumeratorNodes.MoveNext();
            if (CartezianPosition.CalculateDistance(enumeratorNodes.Current.position, node.position) > galaxy.maxDistanceBetweenNodesToConnect)
            {
                Node     reference = enumeratorNodes.Current;
                Starlane newEdge   = new Starlane(node, reference);
                graph.AddEdge(newEdge);
                edgeCosts.Add(newEdge, CartezianPosition.CalculateDistance(enumeratorNodes.Current.position, node.position));
                //node.starlanes.Add(new Starlane(new CartezianLine(node.position,orderedNodes.ElementAt(1).position),node, orderedNodes.ElementAt(1)));
                //orderedNodes.ElementAt(1).starlanes.Add(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(1).position), orderedNodes.ElementAt(1), node));
                //graph.AddEdge(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(1).position), node, orderedNodes.ElementAt(1)));
                //graph.AddEdge(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(1).position), orderedNodes.ElementAt(1), node));
            }
            else
            {
                for (int j = 1; j < 6; j++)
                {
                    if (graph.AdjacentEdges(node).Count() < galaxy.maxConnectionsPerNode && graph.AdjacentEdges(enumeratorNodes.Current).Count() < galaxy.maxConnectionsPerNode)
                    {
                        bool foundIntersection = false;

                        foreach (Node linkNode in graph.AdjacentVertices(enumeratorNodes.Current))
                        {
                            foreach (Node linkOfLinkNode in graph.AdjacentVertices(linkNode))
                            {
                                if (CartezianLine.LineSegmentsIntersect(new CartezianLine(node.position, enumeratorNodes.Current.position), new CartezianLine(linkNode.position, linkOfLinkNode.position)))
                                {
                                    foundIntersection = true;
                                }
                            }
                        }
                        foreach (Node linkNode in graph.AdjacentVertices(node))
                        {
                            foreach (Node linkOfLinkNode in graph.AdjacentVertices(linkNode))
                            {
                                if (CartezianLine.LineSegmentsIntersect(new CartezianLine(node.position, enumeratorNodes.Current.position), new CartezianLine(linkNode.position, linkOfLinkNode.position)))
                                {
                                    foundIntersection = true;
                                }
                            }
                        }

                        if (foundIntersection == false)
                        {
                            Node     reference = enumeratorNodes.Current;
                            Starlane newEdge   = new Starlane(node, reference);
                            graph.AddEdge(newEdge);
                            edgeCosts.Add(newEdge, CartezianPosition.CalculateDistance(enumeratorNodes.Current.position, node.position));
                            //node.starlanes.Add(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(j).position), node, orderedNodes.ElementAt(j)));
                            //orderedNodes.ElementAt(j).starlanes.Add(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(j).position), orderedNodes.ElementAt(j), node));
                            //graph.AddEdge(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(j).position), node, orderedNodes.ElementAt(j)));
                            //graph.AddEdge(new Starlane(new CartezianLine(node.position, orderedNodes.ElementAt(j).position), orderedNodes.ElementAt(j), node));
                        }
                    }
                    enumeratorNodes.MoveNext();
                }
            }
        }
    }
示例#13
0
        Triangulate(UndirectedGraph <int, IEdge <int> > tree, int root = 0)
        {
            UndirectedGraph <int, IEdge <int> >        res = new UndirectedGraph <int, IEdge <int> >();
            Dictionary <(int source, int target), int> innerVerticesCount = new Dictionary <(int source, int target), int>();

            if (tree.IsVerticesEmpty)
            {
                return(res, innerVerticesCount);
            }
            if (!tree.ContainsVertex(root))
            {
                throw new ArgumentException("root");
            }

            UndirectedGraph <int, IEdge <int> > G = tree.Clone();
            // create counter-clockwise combinatorial embedding
            // assumes vertices are numbered as in BFS
            // so it's proper to add them to list in order they are stored internally
            Dictionary <int, List <int> > embedding = new Dictionary <int, List <int> >();

            for (int i = 0; i < G.VertexCount; i++)
            {
                embedding.Add(i, new List <int>());
                foreach (int v in G.AdjacentVertices(i))
                {
                    embedding[i].Add(v);
                }
            }

            // BFS
            Queue <int> q = new Queue <int>();

            bool[] enqueued = new bool[G.VertexCount];
            q.Enqueue(root);
            enqueued[root] = true;
            while (q.Count > 0)
            {
                int p = q.Dequeue();

                int[] neighbors = new int[embedding[p].Count];
                embedding[p].CopyTo(neighbors);

                int first = neighbors[0];
                if (!enqueued[first])
                {
                    q.Enqueue(first);
                    enqueued[first] = true;
                }
                int prev = first;
                int curr = -1;
                for (int i = 1; i < neighbors.Length; i++)
                {
                    curr = neighbors[i];
                    TryAddEdge(prev, curr, p, ref G, ref res, ref embedding, ref innerVerticesCount);
                    prev = curr;

                    if (!enqueued[curr])
                    {
                        q.Enqueue(curr);
                        enqueued[curr] = true;
                    }
                }
                if (neighbors.Length > 2)
                {
                    TryAddEdge(curr, first, p, ref G, ref res, ref embedding, ref innerVerticesCount);
                }
            }
            return(res, innerVerticesCount);
        }
        private bool DnCColoring(List <UndirectedGraph <int, IEdge <int> > > components, HashSet <int> s)
        {
            //Separator colored
            if (s.Count == 0)
            {
                foreach (UndirectedGraph <int, IEdge <int> > component in components)
                {
                    if (component.VertexCount < 15)
                    {
                        //Can't find separator for component - color using bruteforce
                        if (!DnCColoring(new List <UndirectedGraph <int, IEdge <int> > >(),
                                         new HashSet <int>(component.Vertices)))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        HashSet <int> sPrim = PlanarSeparator.FindSeparator(component);
                        UndirectedGraph <int, IEdge <int> > componentCopy = component.Clone();
                        foreach (int vPrim in sPrim)
                        {
                            componentCopy.RemoveVertex(vPrim);
                        }
                        List <UndirectedGraph <int, IEdge <int> > > componentsPrim = FindComponents(componentCopy);
                        if (!DnCColoring(componentsPrim, sPrim))
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }

            //Separator still not colored
            int v = s.First();

            s.Remove(v);
            foreach (GraphColor color in (GraphColor[])Enum.GetValues(typeof(GraphColor)))
            {
                if (!_availableColors[v].Contains(color))
                {
                    continue;
                }

                //Color v with color
                _coloring[v] = color;
                bool       moveToNextColor        = false;
                List <int> verticesWithTakenColor = new List <int>();

                foreach (int n in _graph.AdjacentVertices(v))
                {
                    if (_availableColors[n].Contains(color))
                    {
                        //Adjacent not colored vertex has no available color - invalid coloring
                        if (_availableColors[n].Count == 1)
                        {
                            //Reverse changes
                            foreach (int vertex in verticesWithTakenColor)
                            {
                                _availableColors[vertex].Add(color);
                            }
                            //Move to next v coloring
                            moveToNextColor = true;
                            break;
                        }

                        //Adjacent vertices cannot be colored with color
                        _availableColors[n].Remove(color);
                        verticesWithTakenColor.Add(n);
                    }
                }

                if (moveToNextColor)
                {
                    continue;
                }

                if (DnCColoring(components, s))
                {
                    return(true);
                }

                //Reverse changes
                foreach (int vertex in verticesWithTakenColor)
                {
                    _availableColors[vertex].Add(color);
                }
            }
            s.Add(v);
            return(false);
        }