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); }
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); }
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); }
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); }
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)); }
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); }
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)); }
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); }
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(); } } } }
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); }