/// <summary> /// Finalizes the result of the operation. /// </summary> /// <returns>The resulting object.</returns> protected override IGeometryGraph FinalizeResult() { // if the path is not valid, there is no result if (!_isValidPath) { return(Result); } // generate a graph from the path _parent.Remove(_sourceVertex); // removing the source, we really don't want an edge between a vertex and a null. foreach (IGraphVertex vertex in _parent.Keys) { IGraphVertex sourceVertex = Result.GetVertex(_parent[vertex].Coordinate); IGraphVertex targetVertex = Result.GetVertex(vertex.Coordinate); if (sourceVertex == null) { sourceVertex = Result.AddVertex(_parent[vertex].Coordinate); sourceVertex["Distance"] = _distance[_parent[vertex]]; } if (targetVertex == null) { targetVertex = Result.AddVertex(vertex.Coordinate); targetVertex["Distance"] = _distance[vertex]; } Result.AddEdge(sourceVertex, targetVertex); } return(Result); }
/// <summary> /// Assign color to each new node. /// </summary> private Dictionary <IGraphVertex <T>, C> canColor(IGraphVertex <T> vertex, C[] colors, Dictionary <IGraphVertex <T>, C> progress, HashSet <IGraphVertex <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.TargetVertex)) { continue; } canColor(edge.TargetVertex, colors, progress, visited); } } return(progress); }
/// <summary> /// Do DFS to find all unique edges. /// </summary> private void dfs(IGraphVertex <T> currentVertex, HashSet <T> visitedVertices, Dictionary <T, HashSet <T> > visitedEdges, List <MSTEdge <T, W> > result) { if (!visitedVertices.Contains(currentVertex.Key)) { visitedVertices.Add(currentVertex.Key); foreach (var edge in currentVertex.Edges) { if (!visitedEdges.ContainsKey(currentVertex.Key) || !visitedEdges[currentVertex.Key].Contains(edge.TargetVertexKey)) { result.Add(new MSTEdge <T, W>(currentVertex.Key, edge.TargetVertexKey, edge.Weight <W>())); //update visited edge if (!visitedEdges.ContainsKey(currentVertex.Key)) { visitedEdges.Add(currentVertex.Key, new HashSet <T>()); } visitedEdges[currentVertex.Key].Add(edge.TargetVertexKey); //update visited back edge if (!visitedEdges.ContainsKey(edge.TargetVertexKey)) { visitedEdges.Add(edge.TargetVertexKey, new HashSet <T>()); } visitedEdges[edge.TargetVertexKey].Add(currentVertex.Key); } dfs(edge.TargetVertex, visitedVertices, visitedEdges, result); } } }
/// <summary> /// BFS implementation. /// </summary> private bool bfs(IGraphVertex <T> referenceVertex, HashSet <T> visited, T searchVertex) { var bfsQueue = new Queue <IGraphVertex <T> >(); bfsQueue.Enqueue(referenceVertex); visited.Add(referenceVertex.Key); while (bfsQueue.Count > 0) { var current = bfsQueue.Dequeue(); if (current.Key.Equals(searchVertex)) { return(true); } foreach (var edge in current.Edges) { if (visited.Contains(edge.TargetVertexKey)) { continue; } visited.Add(edge.TargetVertexKey); bfsQueue.Enqueue(edge.TargetVertex); } } return(false); }
public static string BFS(IGraphVertex startVertex, List <IGraphVertex> destinationVertices, IGraph graph) { IBFSSearcher searcher = new BFSSearcher(startVertex, destinationVertices, graph); searcher.BFS(); return(searcher.PathToString()); }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _minQ = new Heap <double, IGraphVertex>(); _distance = new Dictionary <IGraphVertex, double>(); _parent = new Dictionary <IGraphVertex, IGraphVertex>(); _visitedVertices = new HashSet <IGraphVertex>(); foreach (IGraphVertex v in Source.Vertices.Except(new List <IGraphVertex> { _sourceVertex })) { _minQ.Insert(Double.MaxValue, v); _distance.Add(v, Double.MaxValue); } _minQ.Insert(0, _sourceVertex); _distance.Add(_sourceVertex, 0); while (_minQ.Count > 0) { IGraphVertex u = _minQ.RemovePeek(); _visitedVertices.Add(u); if (_parent.ContainsKey(u)) { _spanningEdges.Add(Source.GetEdge(_parent[u], u)); } foreach (IGraphVertex v in GetAdjacentVertices(u)) { if (!_visitedVertices.Contains(v) && _weightMetric(Source.GetEdge(u, v)) < _distance[v]) { _distance[v] = _weightMetric(Source.GetEdge(u, v)); _minQ.Insert(_distance[v], v); _parent[v] = u; } } } }
public static IGraph ConvertMatrixToGraph(IMatrix matrix) { IGraph graph = new Graph(); foreach (IMatrixLine line in matrix.MatrixInstance) { foreach (IMatrixElement element in line.Line) { IGraphVertex vertex = ConvertMatrixElementToVertex(element); IMatrixElement elementAtRight = line.GetElementAtRight(element); IMatrixElement elementAtLeft = line.GetElementAtLeft(element); IMatrixElement elementAbove = matrix.GetElementAbove(line, element); IMatrixElement elementBelow = matrix.GetElementBelow(line, element); if (!elementAtLeft.IsEmpty()) { vertex.ConnectedVertices.Add(ConvertMatrixElementToVertex(elementAtLeft)); } if (!elementAtRight.IsEmpty()) { vertex.ConnectedVertices.Add(ConvertMatrixElementToVertex(elementAtRight)); } if (!elementAbove.IsEmpty()) { vertex.ConnectedVertices.Add(ConvertMatrixElementToVertex(elementAbove)); } if (!elementBelow.IsEmpty()) { vertex.ConnectedVertices.Add(ConvertMatrixElementToVertex(elementBelow)); } graph.GraphInstance.Add(vertex); } } return(graph); }
// Recursive DFS. private bool dfs(IGraphVertex <T> current, HashSet <T> visited, T searchVetex) { visited.Add(current.Key); if (current.Key.Equals(searchVetex)) { return(true); } foreach (var edge in current.Edges) { if (visited.Contains(edge.TargetVertexKey)) { continue; } if (dfs(edge.TargetVertex, visited, searchVetex)) { return(true); } } return(false); }
public void DijkstrasSinglePathAlgorithmExecuteTest() { Func <IGraphEdge, Double> weightFunction = edge => Convert.ToDouble(edge["Weight"]); IDictionary <OperationParameter, Object> parameters = new Dictionary <OperationParameter, Object>(); parameters[GraphOperationParameters.SourceVertex] = _sourceVertex; parameters[GraphOperationParameters.TargetVertex] = _targetVertex; parameters[GraphOperationParameters.WeightMetric] = weightFunction; DijkstrasSinglePathAlgorithm operation = new DijkstrasSinglePathAlgorithm(_sourceGraph, parameters); operation.Execute(); Assert.AreEqual(_resultGraph.VertexCount, operation.Result.VertexCount); Assert.AreEqual(_resultGraph.EdgeCount, operation.Result.EdgeCount); foreach (IGraphVertex resultVertex in operation.Result.Vertices) { IGraphVertex vertex = _resultGraph.GetVertex(resultVertex.Coordinate); Assert.IsNotNull(vertex); Assert.AreEqual(vertex["Distance"], resultVertex["Distance"]); Assert.IsTrue(operation.Result.OutEdges(resultVertex).All(edge => _resultGraph.GetAllEdges(edge.Source.Coordinate, edge.Target.Coordinate).Count == 1)); } }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _priorityQueue.Insert(0, _sourceVertex); _distance.Add(_sourceVertex, 0); _parent.Add(_sourceVertex, null); while (_priorityQueue.Count > 0) { IGraphVertex currentVertex = _priorityQueue.RemovePeek(); foreach (IGraphEdge edge in Source.OutEdges(currentVertex)) { if (_finished.Contains(edge.Target)) { continue; } _finished.Add(currentVertex); if (!_distance.ContainsKey(edge.Target)) { _distance[edge.Target] = _distance[currentVertex] + _weightMetric(edge); _parent[edge.Target] = currentVertex; _priorityQueue.Insert(_distance[edge.Target], edge.Target); } else if (_distance[edge.Target] > _distance[currentVertex] + _weightMetric(edge)) { _distance[edge.Target] = _distance[currentVertex] + _weightMetric(edge); _parent[edge.Target] = currentVertex; _priorityQueue.Insert(_distance[edge.Target], edge.Target); } } } }
/// <summary> /// Initializes a new instance of the <see cref="ShortestPathAlgorithm" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="method">The method.</param> /// <param name="parameters">The parameters.</param> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The method is null. /// or /// The method requires parameters which are not specified. /// </exception> /// <exception cref="System.ArgumentException"> /// The parameters do not contain a required parameter value. /// or /// The type of a parameter does not match the type specified by the method. /// or /// The value of a parameter is not within the expected range. /// or /// The specified source and result are the same objects, but the method does not support in-place operations. /// </exception> protected ShortestPathAlgorithm(IGeometryGraph source, IGeometryGraph target, OperationMethod method, IDictionary <OperationParameter, Object> parameters) : base(source, target, method, parameters) { _sourceVertex = ResolveParameter <IGraphVertex>(GraphOperationParameters.SourceVertex); _targetVertex = ResolveParameter <IGraphVertex>(GraphOperationParameters.TargetVertex); _weightMetric = ResolveParameter <Func <IGraphEdge, Double> >(GraphOperationParameters.WeightMetric); }
/// <summary> /// Initializes a new instance of the <see cref="MaximumFlowComputation"/> class. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="method">The method.</param> /// <param name="parameters">The parameters.</param> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The method is null. /// or /// The method requires parameters which are not specified. /// </exception> /// <exception cref="System.ArgumentException"> /// The parameters do not contain a required parameter value. /// or /// The type of a parameter does not match the type specified by the method. /// or /// The parameter value does not satisfy the conditions of the parameter. /// or /// The specified source and result are the same objects, but the method does not support in-place operations. /// </exception> protected MaximumFlowComputation(IGeometryGraph source, IGeometryGraph target, OperationMethod method, IDictionary <OperationParameter, Object> parameters) : base(source, target, method, parameters) { _sourceVertex = ResolveParameter <IGraphVertex>(GraphOperationParameters.SourceVertex); _targetVertex = ResolveParameter <IGraphVertex>(GraphOperationParameters.TargetVertex); _capacityMetric = ResolveParameter <Func <IGraphEdge, Int32> >(GraphOperationParameters.CapacityMetric); }
internal BFSSearcher(IGraphVertex startVertex, List <IGraphVertex> destinationVertices, IGraph graph) { InitialStartVertex = startVertex; DestinationVertices = destinationVertices; Graph = graph; MatrixFactory = new MatrixFactory(); Path = new List <IGraphVertex>(); }
public void SetUp() { // source: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm IGeometryFactory factory = new GeometryFactory(); // source graph _sourceGraph = factory.CreateNetwork(); // vertices IGraphVertex vertex1 = _sourceGraph.AddVertex(new Coordinate(0, 0)); IGraphVertex vertex2 = _sourceGraph.AddVertex(new Coordinate(1, 0)); IGraphVertex vertex3 = _sourceGraph.AddVertex(new Coordinate(1, 1)); IGraphVertex vertex4 = _sourceGraph.AddVertex(new Coordinate(2, 1)); IGraphVertex vertex5 = _sourceGraph.AddVertex(new Coordinate(1, 2)); IGraphVertex vertex6 = _sourceGraph.AddVertex(new Coordinate(0, 2)); // forward edges _sourceGraph.AddEdge(vertex1, vertex2, CreateWeightMetadata(7)); _sourceGraph.AddEdge(vertex1, vertex3, CreateWeightMetadata(9)); _sourceGraph.AddEdge(vertex1, vertex6, CreateWeightMetadata(14)); _sourceGraph.AddEdge(vertex2, vertex3, CreateWeightMetadata(10)); _sourceGraph.AddEdge(vertex2, vertex4, CreateWeightMetadata(15)); _sourceGraph.AddEdge(vertex3, vertex4, CreateWeightMetadata(11)); _sourceGraph.AddEdge(vertex3, vertex6, CreateWeightMetadata(2)); _sourceGraph.AddEdge(vertex4, vertex5, CreateWeightMetadata(6)); _sourceGraph.AddEdge(vertex5, vertex6, CreateWeightMetadata(9)); // reverse edges _sourceGraph.AddEdge(vertex2, vertex1, CreateWeightMetadata(7)); _sourceGraph.AddEdge(vertex3, vertex1, CreateWeightMetadata(9)); _sourceGraph.AddEdge(vertex6, vertex1, CreateWeightMetadata(14)); _sourceGraph.AddEdge(vertex3, vertex2, CreateWeightMetadata(10)); _sourceGraph.AddEdge(vertex4, vertex2, CreateWeightMetadata(15)); _sourceGraph.AddEdge(vertex4, vertex3, CreateWeightMetadata(11)); _sourceGraph.AddEdge(vertex6, vertex3, CreateWeightMetadata(2)); _sourceGraph.AddEdge(vertex5, vertex4, CreateWeightMetadata(6)); _sourceGraph.AddEdge(vertex6, vertex5, CreateWeightMetadata(9)); // source and target vertices _sourceVertex = vertex1; _targetVertex = vertex5; // result graph _resultGraph = factory.CreateNetwork(); // vertices vertex1 = _resultGraph.AddVertex(new Coordinate(0, 0), CreateDistanceMetadata(0)); vertex3 = _resultGraph.AddVertex(new Coordinate(1, 1), CreateDistanceMetadata(9)); vertex5 = _resultGraph.AddVertex(new Coordinate(1, 2), CreateDistanceMetadata(20)); vertex6 = _resultGraph.AddVertex(new Coordinate(0, 2), CreateDistanceMetadata(11)); // edges _resultGraph.AddEdge(vertex1, vertex3); _resultGraph.AddEdge(vertex3, vertex6); _resultGraph.AddEdge(vertex6, vertex5); }
public IGraphVertex GetGraphVertexFromNeighbourVertex(IGraphVertex neighbourVertex) { foreach (IGraphVertex vertex in GraphInstance) { if (vertex.MatrixElement.Equals(neighbourVertex.MatrixElement)) { return(vertex); } } return(new GraphVertex()); }
private List <PathResult> dfs(IGraphVertex <T> current, Dictionary <T, T> leftMatch, Dictionary <T, T> rightMatch, HashSet <T> visitPath, bool isRightSide) { if (!leftMatch.ContainsKey(current.Key) && !isRightSide) { return(new List <PathResult>()); } foreach (var edge in current.Edges) { //do not re-visit ancestors in current DFS tree if (visitPath.Contains(edge.TargetVertexKey)) { continue; } if (!visitPath.Contains(edge.TargetVertexKey)) { visitPath.Add(edge.TargetVertexKey); } var pathResult = dfs(edge.TargetVertex, leftMatch, rightMatch, visitPath, !isRightSide); if (pathResult == null) { continue; } //XOR (partially done here by removing same edges) //other part of XOR (adding new ones) is done after DFS method is finished if (leftMatch.ContainsKey(current.Key) && leftMatch[current.Key].Equals(edge.TargetVertexKey)) { leftMatch.Remove(current.Key); rightMatch.Remove(edge.TargetVertexKey); } else if (rightMatch.ContainsKey(current.Key) && rightMatch[current.Key].Equals(edge.TargetVertexKey)) { rightMatch.Remove(current.Key); leftMatch.Remove(edge.TargetVertexKey); } else { pathResult.Add(new PathResult(current.Key, edge.TargetVertexKey, isRightSide)); } return(pathResult); } return(null); }
public IEdge <T> GetEdge(IGraphVertex <T> targetVertex) { if (!vertexIndices.ContainsKey(targetVertex.Key)) { throw new ArgumentException("vertex is not in this graph."); } var index = vertexIndices[targetVertex.Key]; var key = targetVertex as GraphVertex <T>; return(new Edge <T, int>(targetVertex, 1)); }
public IEdge <T> GetOutEdge(IGraphVertex <T> targetVertex) { if (!vertexIndices.ContainsKey(targetVertex.Key)) { throw new ArgumentException("vertex is not in this graph."); } var index = vertexIndices[targetVertex.Key]; var key = targetVertex as WeightedGraphVertex <T, TW>; return(new Edge <T, TW>(targetVertex, matrix[vertexIndex, index])); }
/// <summary> /// Is it safe to assign this color to this vertex? /// </summary> private bool isSafe(Dictionary <IGraphVertex <T>, C> progress, IGraphVertex <T> vertex, C color) { foreach (var edge in vertex.Edges) { if (progress.ContainsKey(edge.TargetVertex) && progress[edge.TargetVertex].Equals(color)) { return(false); } } return(true); }
/// <summary> /// Executes a breath first-search on the graph. /// </summary> protected Boolean BreadthFirstSearch(out Int32 capacity, out Dictionary <IGraphVertex, IGraphVertex> parent) { capacity = 0; parent = new Dictionary <IGraphVertex, IGraphVertex>(Source.VertexComparer); Dictionary <IGraphVertex, Int32> pathCapacity = new Dictionary <IGraphVertex, Int32>(Source.VertexComparer); Queue <IGraphVertex> vertexQueue = new Queue <IGraphVertex>(); vertexQueue.Enqueue(_sourceVertex); while (vertexQueue.Count > 0) { IGraphVertex currentVertex = vertexQueue.Dequeue(); foreach (IGraphEdge edge in Source.OutEdges(currentVertex)) { if (!_usedCapacity.ContainsKey(edge)) { _usedCapacity.Add(edge, 0); } // if there is available capacity, and target is not seen before in search if (_capacityMetric(edge) - _usedCapacity[edge] > 0 && !parent.ContainsKey(edge.Target)) { parent.Add(edge.Target, currentVertex); if (pathCapacity.ContainsKey(currentVertex)) { pathCapacity.Add(edge.Target, Math.Min(pathCapacity[currentVertex], _capacityMetric(edge) - _usedCapacity[edge])); } else { pathCapacity.Add(edge.Target, _capacityMetric(edge) - _usedCapacity[edge]); } if (Source.VertexComparer.Equals(_targetVertex, edge.Target)) { capacity = pathCapacity[edge.Target]; return(true); } else { vertexQueue.Enqueue(edge.Target); } } } } return(false); }
private W findMinWeight(IGraphVertex <T> sourceVertex, IGraphVertex <T> tgtVertex, int remainingVertexCount, HashSet <IGraphVertex <T> > visited, Dictionary <string, W> cache) { var cacheKey = $"{sourceVertex.Key}-{remainingVertexCount}"; if (cache.ContainsKey(cacheKey)) { return(cache[cacheKey]); } visited.Add(sourceVertex); var results = new List <W>(); foreach (var edge in sourceVertex.Edges) { //base case if (edge.TargetVertex.Equals(tgtVertex) && remainingVertexCount == 1) { results.Add(edge.Weight <W>()); break; } if (!visited.Contains(edge.TargetVertex)) { var result = findMinWeight(edge.TargetVertex, tgtVertex, remainingVertexCount - 1, visited, cache); if (!result.Equals(@operator.MaxValue)) { results.Add(@operator.Sum(result, edge.Weight <W>())); } } } visited.Remove(sourceVertex); if (results.Count == 0) { return(@operator.MaxValue); } var min = results.Min(); cache.Add(cacheKey, min); return(min); }
/// <summary> /// Do a depth first search to find Bridge edges by keeping track of /// discovery nodes and checking for back edges using low/discovery time maps. /// </summary> private List <Bridge <T> > dfs(IGraphVertex <T> currentVertex, List <Bridge <T> > result, Dictionary <T, int> discoveryTimeMap, Dictionary <T, int> lowTimeMap, Dictionary <T, T> parent, ref int discoveryTime) { discoveryTimeMap.Add(currentVertex.Key, discoveryTime); lowTimeMap.Add(currentVertex.Key, discoveryTime); //discovery childs in this iteration foreach (var edge in currentVertex.Edges) { if (!discoveryTimeMap.ContainsKey(edge.TargetVertexKey)) { parent.Add(edge.TargetVertexKey, currentVertex.Key); discoveryTime++; dfs(edge.TargetVertex, result, discoveryTimeMap, lowTimeMap, parent, ref discoveryTime); //propogate lowTime index of neighbour so that ancestors can see check for back edge lowTimeMap[currentVertex.Key] = Math.Min(lowTimeMap[currentVertex.Key], lowTimeMap[edge.TargetVertexKey]); //if neighbours lowTime is less than current //then this is an Bridge point //because neighbour never had a chance to propogate any ancestors low value //since this is an isolated componant if (discoveryTimeMap[currentVertex.Key] < lowTimeMap[edge.TargetVertexKey]) { result.Add(new Bridge <T>(currentVertex.Key, edge.TargetVertexKey)); } } else { //check if this edge target vertex is not in the current DFS path //even if edge target vertex was already visisted //update discovery so that ancestors can see it if (parent.ContainsKey(currentVertex.Key) == false || !edge.TargetVertexKey.Equals(parent[currentVertex.Key])) { lowTimeMap[currentVertex.Key] = Math.Min(lowTimeMap[currentVertex.Key], discoveryTimeMap[edge.TargetVertexKey]); } } } return(result); }
/// <summary> /// Do DFS to pick smallest weight neighbour edges /// of current spanning tree one by one. /// </summary> /// <param name="spanTreeNeighbours"> Use Fibonacci Min Heap to pick smallest edge neighbour </param> /// <param name="spanTreeEdges">result MST edges</param> private void dfs(IGraph <T> graph, IGraphVertex <T> currentVertex, BHeap <MSTEdge <T, W> > spanTreeNeighbours, HashSet <T> spanTreeVertices, List <MSTEdge <T, W> > spanTreeEdges) { while (true) { //add all edges to Fibonacci Heap //So that we can pick the min edge in next step foreach (var edge in currentVertex.Edges) { spanTreeNeighbours.Insert(new MSTEdge <T, W>(currentVertex.Key, edge.TargetVertexKey, edge.Weight <W>())); } //pick min edge var minNeighbourEdge = spanTreeNeighbours.Extract(); //skip edges already in MST while (spanTreeVertices.Contains(minNeighbourEdge.Source) && spanTreeVertices.Contains(minNeighbourEdge.Destination)) { minNeighbourEdge = spanTreeNeighbours.Extract(); //if no more neighbours to explore //time to end exploring if (spanTreeNeighbours.Count == 0) { return; } } //keep track of visited vertices //do not duplicate vertex if (!spanTreeVertices.Contains(minNeighbourEdge.Source)) { spanTreeVertices.Add(minNeighbourEdge.Source); } //Destination vertex will never be a duplicate //since this is an unexplored Vertex spanTreeVertices.Add(minNeighbourEdge.Destination); //add edge to result spanTreeEdges.Add(minNeighbourEdge); //now explore the destination vertex var graph1 = graph; currentVertex = graph1.GetVertex(minNeighbourEdge.Destination); } }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _priorityQueue = new Heap <Double, IGraphVertex>(); _distance = new Dictionary <IGraphVertex, Double>(); _priorityQueue.Insert(0, _sourceVertex); _distance.Add(_sourceVertex, 0); _parent.Add(_sourceVertex, null); Double limit = _heuristicMetric(_sourceVertex, _targetVertex) * _heuristicLimitMultiplier; // the direct distance used for search space limitation while (_priorityQueue.Count > 0 && !_isTargetReached) { IGraphVertex currentVertex = _priorityQueue.RemovePeek(); _finished.Add(currentVertex); if (Source.VertexComparer.Equals(currentVertex, _targetVertex)) // the target vertex is found { _isTargetReached = true; return; } foreach (IGraphEdge edge in Source.OutEdges(currentVertex)) { if (_finished.Contains(edge.Target)) { continue; } if (!_distance.ContainsKey(edge.Target)) { if (_distance[currentVertex] < limit * _heuristicLimitMultiplier) { _distance[edge.Target] = _distance[currentVertex] + _weightMetric(edge); _parent[edge.Target] = currentVertex; _priorityQueue.Insert(_distance[edge.Target] + _heuristicMetric(edge.Target, _targetVertex), edge.Target); } } else if (_distance[edge.Target] > _distance[currentVertex] + _weightMetric(edge)) { _distance[edge.Target] = _distance[currentVertex] + _weightMetric(edge); _parent[edge.Target] = currentVertex; _priorityQueue.Insert(_distance[edge.Target] + _heuristicMetric(edge.Target, _targetVertex), edge.Target); } } } }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _edgeSet = new HashSet <IGraphEdge>(); _forest = new DisjointSetForest <IGraphVertex>(Source.Vertices); while (_forest.SetCount > 1) { IGraphVertex currentRep = null; foreach (IGraphVertex vertex in _forest.OrderedEnumerator) { if (currentRep != _forest.Find(vertex)) { //new component currentRep = _forest.Find(vertex); if (_edgeSet.Count > 0) { _spanningEdges.Add(_edgeSet.MinBy(x => _weightMetric(x)).First()); } _edgeSet.Clear(); } if (Source.OutEdges(vertex).Any(x => _forest.Find(x.Target) != currentRep)) { _edgeSet.Add( Source.OutEdges(vertex) .Where(x => _forest.Find(x.Target) != currentRep) .MinBy(y => _weightMetric(y)) .First()); } } if (_edgeSet.Count > 0) { //on the last element there is no component change _spanningEdges.Add(_edgeSet.MinBy(x => _weightMetric(x)).First()); } _edgeSet.Clear(); foreach (IGraphEdge spanningEdge in _spanningEdges) { _forest.Union(spanningEdge.Source, spanningEdge.Target); } } }
/// <summary> /// Gets the adjacent vertices of the given vertex /// </summary> /// <param name="vertex">The vertex</param> /// <returns>The adjacent vertices</returns> List <IGraphVertex> GetAdjacentVertices(IGraphVertex vertex) { List <IGraphVertex> adjacentVertices = new List <IGraphVertex>(); foreach (IGraphEdge edge in Source.OutEdges(vertex)) { if (edge.Source == vertex) { adjacentVertices.Add(edge.Target); } else { adjacentVertices.Add(edge.Source); } } return(adjacentVertices); }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { // source: http://en.wikipedia.org/wiki/Edmonds%E2%80%93Karp_algorithm Int32 capacity; Dictionary <IGraphVertex, IGraphVertex> parent; while (BreadthFirstSearch(out capacity, out parent)) { _maximumFlow += capacity; // backtrack search IGraphVertex currentVertex = _targetVertex; while (!Source.VertexComparer.Equals(currentVertex, _sourceVertex)) { IGraphVertex parentVertex = parent[currentVertex]; IGraphEdge forwardEdge = Source.GetEdge(parentVertex, currentVertex); IGraphEdge reverseEdge = Source.GetEdge(currentVertex, parentVertex); // modify used capacity if (!_usedCapacity.ContainsKey(forwardEdge)) { _usedCapacity.Add(forwardEdge, 0); } _usedCapacity[forwardEdge] += capacity; if (reverseEdge != null) { if (!_usedCapacity.ContainsKey(reverseEdge)) { _usedCapacity.Add(reverseEdge, 0); } _usedCapacity[reverseEdge] -= capacity; } currentVertex = parentVertex; } _isTargetReached = true; } }
public void GeometryGraphDepthFirstEnumeratorResetTest() { // simple reset GeometryGraph graph = new GeometryGraph(PrecisionModel.Default, null, null); IGraphVertex v1 = graph.AddVertex(new Coordinate(10, 10)); IGraphVertex v2 = graph.AddVertex(new Coordinate(0, 0)); IGraphVertex v3 = graph.AddVertex(new Coordinate(5, 5)); IGraphVertex v4 = graph.AddVertex(new Coordinate(15, 15)); graph.AddEdge(v1, v2); graph.AddEdge(v2, v1); graph.AddEdge(v3, v4); IEnumerator <IGraphVertex> enumerator = graph.GetEnumerator(EnumerationStrategy.DepthFirst); List <IGraphVertex> list = new List <IGraphVertex>(); while (enumerator.MoveNext()) { list.Add(enumerator.Current); } Assert.AreEqual(list.Count, graph.VertexCount); Assert.IsTrue(list.All(vertex => graph.Vertices.Contains(vertex))); enumerator.Reset(); list = new List <IGraphVertex>(); while (enumerator.MoveNext()) { list.Add(enumerator.Current); } Assert.AreEqual(list.Count, graph.VertexCount); Assert.IsTrue(list.All(vertex => graph.Vertices.Contains(vertex))); // modified collection graph.AddVertex(new Coordinate(20, 20)); Assert.Throws <InvalidOperationException>(() => enumerator.Reset()); }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _priorityQueue = new Heap <Double, IGraphVertex>(); _priorityQueue.Insert(0, _sourceVertex); _distance.Add(_sourceVertex, 0); _parent.Add(_sourceVertex, null); while (_priorityQueue.Count > 0 && !_isTargetReached) { IGraphVertex currentVertex = _priorityQueue.RemovePeek(); _finished.Add(currentVertex); if (Source.VertexComparer.Equals(currentVertex, _targetVertex)) // the target vertex is found { _isTargetReached = true; return; } foreach (IGraphEdge edge in Source.OutEdges(currentVertex)) { if (_finished.Contains(edge.Target)) { continue; } if (!_distance.ContainsKey(edge.Target)) { _distance[edge.Target] = _distance[currentVertex] + _weightMetric(edge); _parent[edge.Target] = currentVertex; _priorityQueue.Insert(_distance[edge.Target], edge.Target); } else if (_distance[edge.Target] > _distance[currentVertex] + _weightMetric(edge)) { _distance[edge.Target] = _distance[currentVertex] + _weightMetric(edge); _parent[edge.Target] = currentVertex; _priorityQueue.Insert(_distance[edge.Target], edge.Target); } } } }
/// <summary> /// An approximation algorithm for NP complete vertex cover problem. /// Add a random edge vertices until done visiting all edges. /// </summary> private List <IGraphVertex <T> > getMinVertexCover(IGraphVertex <T> vertex, HashSet <IGraphVertex <T> > visited, List <IGraphVertex <T> > cover) { visited.Add(vertex); foreach (var edge in vertex.Edges) { if (!cover.Contains(vertex) && !cover.Contains(edge.TargetVertex)) { cover.Add(vertex); cover.Add(edge.TargetVertex); } if (!visited.Contains(edge.TargetVertex)) { getMinVertexCover(edge.TargetVertex, visited, cover); } } return(cover); }