Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
        /// <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);
                }
            }
        }
Exemplo n.º 4
0
        /// <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);
        }
Exemplo n.º 5
0
        public static string BFS(IGraphVertex startVertex, List <IGraphVertex> destinationVertices, IGraph graph)
        {
            IBFSSearcher searcher = new BFSSearcher(startVertex, destinationVertices, graph);

            searcher.BFS();
            return(searcher.PathToString());
        }
Exemplo n.º 6
0
        /// <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;
                    }
                }
            }
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        // 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);
        }
Exemplo n.º 9
0
        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));
            }
        }
Exemplo n.º 10
0
        /// <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);
 }
Exemplo n.º 12
0
 /// <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);
 }
Exemplo n.º 13
0
 internal BFSSearcher(IGraphVertex startVertex, List <IGraphVertex> destinationVertices, IGraph graph)
 {
     InitialStartVertex  = startVertex;
     DestinationVertices = destinationVertices;
     Graph         = graph;
     MatrixFactory = new MatrixFactory();
     Path          = new List <IGraphVertex>();
 }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
0
 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);
        }
Exemplo n.º 17
0
            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));
            }
Exemplo n.º 18
0
            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]));
            }
Exemplo n.º 19
0
        /// <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);
        }
Exemplo n.º 20
0
        /// <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);
        }
Exemplo n.º 22
0
        /// <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);
        }
Exemplo n.º 23
0
        /// <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);
            }
        }
Exemplo n.º 24
0
        /// <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);
                    }
                }
            }
        }
Exemplo n.º 25
0
        /// <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);
                }
            }
        }
Exemplo n.º 26
0
        /// <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);
        }
Exemplo n.º 27
0
        /// <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;
            }
        }
Exemplo n.º 28
0
            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);
        }