/// <summary> /// assign color to each new node /// </summary> /// <param name="vertex"></param> /// <param name="colors"></param> /// <param name="progress"></param> /// <param name="visited"></param> /// <returns></returns> private Dictionary <GraphVertex <T>, C> CanColor(GraphVertex <T> vertex, C[] colors, Dictionary <GraphVertex <T>, C> progress, HashSet <GraphVertex <T> > visited) { for (int i = 0; i < colors.Length; i++) { if (isSafe(progress, vertex, colors[i])) { progress.Add(vertex, colors[i]); break; } } if (visited.Contains(vertex) == false) { visited.Add(vertex); foreach (var edge in vertex.Edges) { if (visited.Contains(edge)) { continue; } CanColor(edge, colors, progress, visited); } } return(progress); }
public void TraverseGraph(string startingVertexUniqueKey, GraphVisitor visitor) { Dictionary <string, bool> visited = new Dictionary <string, bool>(); Queue <GraphVertex> q = new Queue <GraphVertex>(); GraphVertex start = g.GetVertexByUniqueKey(startingVertexUniqueKey); q.Enqueue(start); while (q.Count > 0) { GraphVertex current = q.Dequeue(); visitor.Visit(current); visited[current.UniqueKey] = true; foreach (GraphVertex v in current.GetAdjacentVertices()) { if (!visited.ContainsKey(v.UniqueKey) && !q.Contains(v)) { q.Enqueue(v); } } } }
/// <summary> /// Solves a maze iteratively /// </summary> /// <param name="start">start vertex</param> /// <param name="end">end vertex</param> /// <returns></returns> public static List <GraphVertex> SolveMazeIter(GraphVertex start, GraphVertex end) { // parent will also be used to check whether a vertex is visited or not Dictionary <GraphVertex, GraphVertex> parent = new Dictionary <GraphVertex, GraphVertex>(); Stack <GraphVertex> st = new Stack <GraphVertex>(); st.Push(start); parent[start] = null; while (st.Count > 0) { GraphVertex vertex = st.Pop(); if (vertex == end) { // we have found the path // backtrack to get the path return(BackTrackToGetPath(parent, start, end)); } foreach (GraphVertex neighbour in vertex.NeighbourVertices) { if (!parent.ContainsKey(neighbour)) { // this vertex is not visited parent[neighbour] = vertex; st.Push(neighbour); } } } return(null); }
/// <summary> /// returns true if all vertices can be colored using the given colors /// in such a way so that no neighbours have same color /// </summary> /// <param name="graph"></param> /// <param name="colors"></param> /// <returns></returns> public MColorResult <T, C> Color(Graph <T> graph, C[] colors) { GraphVertex <T> first = graph.ReferenceVertex; var progress = CanColor(first, colors, new Dictionary <GraphVertex <T>, C>(), new HashSet <GraphVertex <T> >()); if (progress.Count == graph.VerticesCount) { var result = new Dictionary <C, List <T> >(); foreach (var vertex in progress) { if (!result.ContainsKey(vertex.Value)) { result.Add(vertex.Value, new List <T>()); } result[vertex.Value].Add(vertex.Key.Value); } return(new MColorResult <T, C>(true, result)); } return(new MColorResult <T, C>(false, null)); }
/// <summary> /// Color the vertices in a graph with 2 different colors such that no 2 connected vertices have the same color /// /// We do a BFS here and color all odd layer node with the same color /// if you encounter any node in the odd layer with the color of the even layer then return false /// </summary> /// <returns></returns> private static bool ColorVerticesWithDifferentColor(GraphVertex vertex) { Queue <GraphVertex> queueForBFS = new Queue <GraphVertex>(); queueForBFS.Enqueue(vertex); vertexColorDict[vertex] = 0; while (queueForBFS.Count > 0) { GraphVertex currentVertex = queueForBFS.Dequeue(); foreach (GraphVertex neighbour in vertex.NeighbourVertices) { if (vertexColorDict.ContainsKey(neighbour) && vertexColorDict[neighbour] == vertexColorDict[currentVertex]) { // This is a visited node // We have hit the case where we cannot meet the condition that 2 vertices of the edge has different color return(false); } else if (!vertexColorDict.ContainsKey(neighbour)) { // This is an unvisited node vertexColorDict[neighbour] = (vertexColorDict[currentVertex] + 1) % 2; queueForBFS.Enqueue(neighbour); } } } return(true); }
public void Generate(IEnumerable <GraphVertex> maze) { // Initialization Stack <GraphVertex> stack = new Stack <GraphVertex>(); IEnumerator <GraphVertex> enumerator = maze.GetEnumerator(); enumerator.MoveNext(); GraphVertex current = enumerator.Current; stack.Push(current); // Algorithm GraphVertex next; while (!(stack.Count == 0)) { current = stack.Peek(); current.SetVisited(); next = current.GetRandomMarkedNeighbour(MarkType.Unvisited); if (next == null) // dead end, every neighbour of the current cell has been visited { stack.Pop(); } else { current.RemoveBorderBetweenCells(next); stack.Push(next); } } }
private void RemoveEdge(GraphVertex from, GraphVertex to) { RemoveWayEdge(from, to); RemoveWayEdge(to, from); EdgeCount--; }
City GetNextCity(GraphVertex startVertex, GraphVertex endVertex) { var path = new List <City>(); path.Add(endVertex.City); while (startVertex != endVertex) { if (endVertex.number > infos.Length - 1) { GraphVertexInfo temp = GetVertexInfo(endVertex); if (temp != null) { GraphVertex vert = temp.Vertex; endVertex = temp.PreviousVertex; path.Add(endVertex.City); } else { return(null); } } else { endVertex = infos[endVertex.number].PreviousVertex; if (endVertex == null) { return(null); } path.Add(endVertex.City); } } return(path[path.Count - 2]); }
private GraphVertex GetVertexInDirection(GraphVertex origin, Direction direction) { int originRow = origin.Value / Cols; int originCol = origin.Value % Cols; int newRow = originRow; int newCol = originCol; switch (direction) { case Direction.North: newRow -= 1; break; case Direction.South: newRow += 1; break; case Direction.East: newCol += 1; break; case Direction.West: newCol -= 1; break; } if (newRow < 0 || newRow >= Rows || newCol < 0 || newCol >= Cols) { return(null); } else { return(vertices[newRow * Cols + newCol]); } }
private void RecoverEdge(GraphVertex fromVertex, GraphVertex toVertex) { _lists[(int)fromVertex].Insert(toVertex); _lists[(int)toVertex].Insert(fromVertex); EdgeCount++; }
/// <summary> /// We will use DFS to get all the paths from startVertex to endVertex. /// </summary> /// <param name="startVertex"></param> /// <param name="endVertex"></param> private static void GetAllPathsInGraphFromStartVertexToEndVertex(GraphVertex startVertex, GraphVertex endVertex) { if (startVertex == null) { return; } if (startVertex == endVertex) { //We have reached the end CurrentPath.Add(endVertex); // Print the path from start to end foreach (GraphVertex vertex in CurrentPath) { Console.Write(vertex.Data + " -> "); } Console.WriteLine(); // lets back track to find other paths CurrentPath.Remove(endVertex); return; } startVertex.IsVisited = true; CurrentPath.Add(startVertex); foreach (GraphVertex neighbour in startVertex.NeighbourVertices) { if (!neighbour.IsVisited) { GetAllPathsInGraphFromStartVertexToEndVertex(neighbour, endVertex); } } startVertex.IsVisited = false; // this will be used for backtracking CurrentPath.Remove(startVertex); }
// Конструктор public GraphVertexInfo(GraphVertex vertex) // vertex - Вершина { Vertex = vertex; IsUnvisited = true; EdgesWeightSum = int.MaxValue; PreviousVertex = null; }
/// <summary> /// assign color to each new node /// </summary> /// <param name="vertex"></param> /// <param name="colors"></param> /// <param name="progress"></param> /// <param name="visited"></param> /// <returns></returns> private Dictionary <GraphVertex <T>, C> canColor(GraphVertex <T> vertex, C[] colors, Dictionary <GraphVertex <T>, C> progress, HashSet <GraphVertex <T> > visited) { foreach (var item in colors) { if (!isSafe(progress, vertex, item)) { continue; } progress.Add(vertex, item); break; } if (visited.Contains(vertex) == false) { visited.Add(vertex); foreach (var edge in vertex.Edges) { if (visited.Contains(edge)) { continue; } canColor(edge, colors, progress, visited); } } return(progress); }
/// <summary> /// We can do a BFS to clone a Connected Graph. /// /// Algo: 1. CloneDict will keep track of A -->A` mapping /// 2. Visiting the neighbours in BFS is equivalent to visiting the edges. /// While visiting the edges, check if both the start and the end vertices have the clone vertices in the cloneDict. /// 3. If not, create them and Add the forward edge to the clone vertices. /// /// This code will work on directed graph, undirected graph and graph with cycles /// /// The running time is O(V+E) /// The space requirement is O(V) /// </summary> /// <param name="root"></param> /// <returns></returns> public static GraphVertex Clone(GraphVertex root) { if (root == null) { // Error case return(null); } // This will have key as the actual vertex A and the value as its Clone A` Dictionary <GraphVertex, GraphVertex> cloneDict = new Dictionary <GraphVertex, GraphVertex>(new GraphVertexComparer()); Queue <GraphVertex> queue = new Queue <GraphVertex>(); queue.Enqueue(root); cloneDict[root] = new GraphVertex(root.Data); while (queue.Count > 0) { GraphVertex v = queue.Dequeue(); foreach (GraphVertex neighbour in v.NeighbourVertices) { if (!cloneDict.ContainsKey(neighbour)) { cloneDict[neighbour] = new GraphVertex(neighbour.Data); queue.Enqueue(neighbour); } // Add the forward edges to the clone vertices cloneDict[v].NeighbourVertices.Add(cloneDict[neighbour]); } } return(cloneDict[root]); }
private void RemoveWayEdge(GraphVertex fromVertex, GraphVertex toVertex) { int fromVertexInt = (int)fromVertex; if (!_lists[fromVertexInt].ReadFirst()) { return; } GraphVertex vertex = _lists[fromVertexInt].CurrentNode.Data; if (vertex == toVertex) { _lists[fromVertexInt].RemoveData(vertex); return; } while (_lists[fromVertexInt].ReadNext()) { vertex = _lists[fromVertexInt].CurrentNode.Data; if (vertex != toVertex) { continue; } _lists[fromVertexInt].RemoveData(vertex); return; } }
/// <summary> /// Coloring the graph is an NP complete problem. We will solve this in the similar way we solve the Sudoku problem /// Color node with each of the available color and check whether all the other nodes can be colored with one of the colors in maxColors /// /// The running time of this algo is O(maxColors^(n)) where n is the number of vertices /// Recurence relation T(n) = maxColors*T(n-1) /// </summary> /// <param name="vertex">start vertex of a graph. This can be any vertex in the graph</param> /// <returns>whether the whole graph can be colored using MaxColors different color</returns> public bool ColorGraph(GraphVertex vertex, int maxColors) { for (int index = 0; index < maxColors; index++) { if (CanColor(vertex, index)) { vertex.Color = index; bool allNeighboursCanBeColored = true; foreach (GraphVertex neighbour in vertex.Neighbours) { if (neighbour.Color == -1 && !ColorGraph(neighbour, maxColors)) { allNeighboursCanBeColored = false; break; } } if (allNeighboursCanBeColored) { return(true); } } } vertex.Color = -1; // Need for back tracking return(false); }
public void TraverseGraph(string startingVertexUniqueKey, GraphVisitor visitor) { GraphVertex start = g.GetVertexByUniqueKey(startingVertexUniqueKey); Dictionary <string, bool> visited = new Dictionary <string, bool>(); InternalTraverseGraph(start, visitor, visited); }
public void GivenMultipleEqualDistancePaths_ExpectOutput3() { // A -> B -> C // A -> D -> C // C -> E var vertexA = new GraphVertex("A"); var vertexB = new GraphVertex("B"); var vertexC = new GraphVertex("C"); var vertexD = new GraphVertex("D"); var vertexE = new GraphVertex("E"); vertexA.AddConnectionToVertex(vertexB); vertexB.AddConnectionToVertex(vertexC); vertexA.AddConnectionToVertex(vertexD); vertexD.AddConnectionToVertex(vertexC); vertexD.AddConnectionToVertex(vertexC); vertexC.AddConnectionToVertex(vertexE); var solution = Dijkstra.Solve(vertexA, vertexE); solution.Should().Be(3); }
private List <Cell> ReconstructPath(GraphVertex start, GraphVertex finish) { GraphVertex current = finish.СameFrom; var _way = new List <GraphVertex>(); int fuse = 0; while (!current.Equals(start)) { fuse++; if (fuse == 1000000) { throw new Exception("Ходим по кругу"); } current.Cell.SetLight(true); _way.Add(current); current = current.СameFrom; } _way.Reverse(); var ReconstructPath = _way.Select(s => s.Cell).ToList(); foreach (var item in ReconstructPath) { } return(ReconstructPath); }
// Removes the wall between 2 cells by looking a their cornerPoints // Once the common corner points are found, we set them as "non-neighbours" public void RemoveBorderBetweenCells(GraphVertex otherGraphVertex) { RegularCell otherCell = (RegularCell)otherGraphVertex; foreach (RegularCell c in this.connectedCells) { // We look for the adjacent cell to remove the border if (c.Equals(otherCell)) { // We look for the corner points which are common to the two cells List <Vertex> commonVertices = new List <Vertex> (); foreach (Vertex v1 in this.cornerPoints) { foreach (Vertex v2 in otherCell.cornerPoints) { if (v1.Equals(v2)) { commonVertices.Add(v1); } } } // We disconnect all the border points which are common to the 2 cells so that the way is open foreach (Vertex v1 in commonVertices) { foreach (Vertex v2 in commonVertices) { v1.RemoveNeighbour(v2); } } } } }
public City FindIntermediateCity(GraphVertex startVertex, GraphVertex finishVertex) { GraphVertexInfo temp = null; if (startVertex == null || startVertex.number > infos.Length - 1) { return(null); } GraphVertexInfo first = infos[startVertex.number]; if (first != null && finishVertex != null) { first.EdgesWeightSum = 0; while (true) { GraphVertexInfo current = FindUnvisitedVertexWithMinSum(temp); if (current == null) { break; } SetSumToNextVertex(current); } return(GetNextCity(startVertex, finishVertex)); } else { return(null); } }
/// <summary> /// /// </summary> /// <param name="vertex"></param> public GraphVertexInfo(GraphVertex vertex) { Vertex = vertex; IsUnvisited = true; EdgesWeightSum = double.MaxValue; PreviousVertex = null; }
public void GivenSingleVertexGraph_ExpectDistance0() { var startEnd = new GraphVertex("A"); var solution = Dijkstra.Solve(startEnd, startEnd); solution.Should().Be(0); }
/// <summary> /// Recursive DFS /// </summary> /// <param name="current"></param> /// <param name="visited"></param> /// <param name="searchVetex"></param> /// <returns></returns> private bool dfs(GraphVertex <T> current, HashSet <T> visited, T searchVetex) { visited.Add(current.Value); if (current.Value.Equals(searchVetex)) { return(true); } foreach (var edge in current.Edges) { if (visited.Contains(edge.Value)) { continue; } if (dfs(edge, visited, searchVetex)) { return(true); } } return(false); }
/// <summary> /// BFS implementation /// </summary> /// <param name="referenceVertex"></param> /// <param name="HashSet"></param> /// <param name="searchVertex"></param> /// <returns></returns> private bool bfs(GraphVertex <T> referenceVertex, HashSet <T> visited, T searchVertex) { var bfsQueue = new Queue <GraphVertex <T> >(); bfsQueue.Enqueue(referenceVertex); visited.Add(referenceVertex.Value); while (bfsQueue.Count > 0) { var current = bfsQueue.Dequeue(); if (current.Value.Equals(searchVertex)) { return(true); } foreach (var edge in current.Edges) { if (visited.Contains(edge.Value)) { continue; } visited.Add(edge.Value); bfsQueue.Enqueue(edge); } } return(false); }
/// <summary> /// A graph is bi partite if the graph can be colored by 2 colors. /// This is similar to the approach in the ColorVertices.cs file. /// /// We will assign a color to source and do BFS on the graph. /// the next level will be colored via the second color and so on. /// While coloring a neighbour if we encounter a node which is colored with the same color as the vertex, /// then we cannot color the whole graph using 2 colors and hence the graph is not BiPartite. /// /// /// Instead of color we can just add the graph vertex to the dictionary as the key and the set number as the value. /// /// The running time is O(V+E) /// </summary> /// <returns></returns> public static bool IsBiPartiteGraph(GraphVertex source) { Queue <GraphVertex> queue = new Queue <GraphVertex>(); queue.Enqueue(source); // We can also use this dictionary to get which vertices are visited Dictionary <GraphVertex, int> vertexSetMap = new Dictionary <GraphVertex, int>(); vertexSetMap[source] = 0; while (queue.Count > 0) { GraphVertex vertex = queue.Dequeue(); foreach (GraphVertex neighbour in vertex.NeighbourVertices) { if (!vertexSetMap.ContainsKey(neighbour)) { queue.Enqueue(neighbour); vertexSetMap[neighbour] = vertexSetMap[vertex] + 1 % 2; } else { // We have already visted this vertex, make sure that the color is correct if (vertexSetMap[neighbour] == vertexSetMap[vertex]) { // 2 coloring is not possible return(false); } } } } return(true); }
public async Task <object> PatchGraphVertex(GraphVertex graphcontent) { try { var result = (dynamic)null; dynamic content = JsonConvert.DeserializeObject <dynamic>(graphcontent.Content); string type = graphcontent.VertexType; StringBuilder builder = new StringBuilder(); foreach (var item in content) { string query = $".property('{item.Name}','{item.Value}')"; builder.Append(query); } var queryString = string.Concat($"g.addV('{type}')", builder); result = await _client.SubmitAsync <dynamic>(queryString); var responsemessage = JsonConvert.SerializeObject(result); return(this.Content(responsemessage, "application/json")); } catch (Exception ex) { return(Content(ex.Message)); } }
public List <GraphVertex> PathAstar(GraphVertex A, GraphVertex B) { GraphVertex vert = AStar(A, B); if (vert == null) { return(null); } List <GraphVertex> path = new List <GraphVertex>(); GraphVertex current = vert; while (true) { path.Add(current); if (current.prev != null) { current = current.prev; } else { break; } } path.Reverse(); return(path); }
public List <GraphVertex> PathDijkstra(GraphVertex A, GraphVertex B) { int[] distance = Dijkstra(A); if (distance[B.Region.number] == int.MaxValue) { return(null); } List <GraphVertex> path = new List <GraphVertex>(); GraphVertex current = B; while (true) { path.Add(current); if (current.prev != null) { current = current.prev; } else { break; } } path.Reverse(); return(path); }
public GraphVertex FindNode(GraphVertex src, string val, List <string> path = null) { GraphVertex node = null; Queue <GraphVertex> queue = new Queue <GraphVertex>(); queue.Enqueue(src); HashSet <GraphVertex> visited = new HashSet <GraphVertex>(); while (queue.Count != 0) { var vertex = queue.Dequeue(); if (vertex.Value == val) { node = vertex; break; } // Add all unvisited neighbors vertex.Neighbors.Where(x => !visited.Contains(x)).ToList().ForEach(x => queue.Enqueue(x)); // mark as visited if (!visited.Contains(vertex)) { visited.Add(vertex); } } return(node); }
static GraphVertex[] CreateVertices(GMFileContent content, CodeInfo code) { var blocks = SplitBlocks(code); var instr = code.Instructions; var firstI = (long)instr[0]; // only one block -> just return it as a single vertex if (blocks.Length == 1) return new[] { new GraphVertex { Branches = EmptyGBArray, Instructions = blocks[0].Instructions } }; var vertices = new GraphVertex[blocks.Length]; // create list of vertices for (int i = 0; i < blocks.Length; i++) { var blk = blocks[i]; var hasNext = i < blocks.Length - 1 && blk.Type != BranchType.Unconditional /* no need to check if uncond */; vertices[i] = new GraphVertex { Instructions = blk.Instructions, Branches = new GraphBranch[hasNext ? 2 : 1] }; vertices[i].Branches[0] = new GraphBranch { BranchTo = blk.BranchTo, Type = blk.Type }; if (hasNext) vertices[i].Branches[1] = new GraphBranch { BranchTo = blocks[i + 1].Instructions[0], Type = blk.Type.Invert() }; } // connect vertex branches to target vertices for (int i = 0; i < vertices.Length; i++) { var v = vertices[i]; for (int j = 0; j < v.Branches.Length; j++) v.Branches[j].ToVertex = vertices.FirstOrDefault(ve => ve.Instructions[0] == v.Branches[j].BranchTo) ?? (i == vertices.Length - 1 ? null : vertices[i + 1]); } return vertices; }
void WireHydrogenBond(GraphComponent component, Domain d, GraphVertex from, GraphVertex to, GraphVertex fromAux, GraphVertex toAux) { if (!WiredHydrogenBondsOf(from).Contains(to)) { Debug.Assert(!WiredHydrogenBondsOf(to).Contains(from)); WiredHydrogenBondsOf(from).Add(to); WiredHydrogenBondsOf(to).Add(from); double length = this.HydrogenBondLength(d, d.Connection); GraphEdge edge = new GraphEdge(component, from, to, length, Constants.StyleLineHydrogenBond); // edge.Visualization.Shaft = VisualGraphEdge.SHAFT.Full; // we don't show the end line of domains as we now shade the double stranded region entirely SpringForce.CreateSymmetricalSpringForces(component, edge.A, edge.B, Constants.SpringConstantHydrogenBond, length); IntersectionForce.Create(component, edge, Constants.IntersectionForceStrength); new RightAngleForce(component, fromAux, from, to, Constants.RightAngleStrength); new RightAngleForce(component, toAux, to, from, Constants.RightAngleStrength); } }
List<GraphVertex> WiredHydrogenBondsOf(GraphVertex v) { List<GraphVertex> result; if (!mpVertexWiredHydrogenBonds.TryGetValue(v, out result)) { result = new List<GraphVertex>(); mpVertexWiredHydrogenBonds.Add(v, result); } return result; }
GraphEdge EdgeFromDomain(GraphComponent component, Domain d, bool fMustExist=false) // Return the edge for the indicated domain along its strand. We create this // edge if it doesn't already exist. The returned edge has edge.A on the 5' // side of d and edge.B on the 3' side. { GraphEdge edge; if (!this.mpDomainEdge.TryGetValue(d, out edge)) { Debug.Assert(!fMustExist); // // If there's another domain 5' of this one, and he already has // an edge, then we use the B vertex from that guy; otherwise, // we make one fresh anew. // GraphVertex to5 = null; if (d.CircularNextTo5 != null) { GraphEdge edgeTo5; if (this.mpDomainEdge.TryGetValue(d.CircularNextTo5, out edgeTo5)) { to5 = edgeTo5.B; } } if (null == to5) { to5 = new GraphVertex(component, "[" + d.DisplayName + ">", d); } // // Ditto, but in the 3' direction // GraphVertex to3 = null; if (d.CircularNextTo3 != null) { GraphEdge edgeTo3; if (this.mpDomainEdge.TryGetValue(d.CircularNextTo3, out edgeTo3)) { to3 = edgeTo3.A; } } if (null == to3) { to3 = new GraphVertex(component, "<" + d.DisplayName + "]", d); } // // Make the new edge // double length = this.DomainRenderingLength(d); edge = new GraphEdge(component, to5, to3, length, Constants.StyleLineDomain); // // Apply appropriate forces to the edge // SpringForce.CreateSymmetricalSpringForces(component, edge.A, edge.B, Constants.SpringConstantDomain, length); IntersectionForce.Create(component, edge, Constants.IntersectionForceStrength); // // Remember this edge // edge.Domain = d; this.mpDomainEdge[d] = edge; } return edge; }
public bool IncidentTo(GraphVertex v) { return Object.ReferenceEquals(this.A, v) || Object.ReferenceEquals(this.B, v); }
//---------------------------------------------------------------------------------------- // Construction //---------------------------------------------------------------------------------------- public GraphEdge(GraphComponent component, GraphVertex a, GraphVertex b, double length, string style) { a.Edges.Add(this); b.Edges.Add(this); component.Edges.Add(this); this.Component = component; this.A = a; this.B = b; this.PreferredLength = length; }