Beispiel #1
0
        /**
         * Concatenates the specified GraphWalk to the end of this GraphWalk. This action can only be
         * performed if the end vertex of this GraphWalk is the same as the start vertex of the
         * extending GraphWalk
         *
         * @param extension GraphPath used for the concatenation.
         * @param walkWeightCalculator Function used to calculate the weight of the GraphWalk obtained
         *        after the concatenation.
         * @return a GraphWalk that represents the concatenation of this object's walk followed by the
         *         walk specified in the extension argument.
         */
        public GraphWalk <V, E> concat(
            GraphWalk <V, E> extension, Func <GraphWalk <V, E>, Double> walkWeightCalculator)
        {
            if (this.isEmpty())
            {
                throw new ArgumentException("An empty path cannot be extended");
            }
            if (!this.endVertex.Equals(extension.getStartVertex()))
            {
                throw new ArgumentException(
                          "This path can only be extended by another path if the end vertex of the orginal path and the start vertex of the extension are equal.");
            }

            List <V> concatVertexList = null;
            List <E> concatEdgeList   = null;

            if (vertexList != null)
            {
                concatVertexList = new List <V>(this.vertexList);
                List <V> vertexListExtension = extension.getVertexList();
                concatVertexList.AddRange(vertexListExtension.Skip(1));
            }

            if (edgeList != null)
            {
                concatEdgeList = new List <E>(this.edgeList);
                concatEdgeList.AddRange(extension.getEdgeList());
            }

            GraphWalk <V, E> gw = new GraphWalk <V, E>(
                this.graph, startVertex, extension.getEndVertex(), concatVertexList, concatEdgeList, 0);

            gw.setWeight(walkWeightCalculator(gw));
            return(gw);
        }
Beispiel #2
0
        public bool Equals(GraphWalk <V, E> o)
        {
            if (o == null || !(o is GraphWalk <V, E>))
            {
                return(false);
            }
            else if (this == o)
            {
                return(true);
            }
            GraphWalk <V, E> other = (GraphWalk <V, E>)o;

            if (this.isEmpty() && other.isEmpty())
            {
                return(true);
            }
            if (!this.startVertex.Equals(other.getStartVertex()) ||
                !this.endVertex.Equals(other.getEndVertex()))
            {
                return(false);
            }
            // If this path is expressed as a vertex list, we may get away by comparing the other path's
            // vertex list
            // This only works if its vertexList identifies a unique path in the graph
            if (this.edgeList == null && !other.getGraph().getType().isAllowingMultipleEdges())
            {
                return(this.vertexList.Equals(other.getVertexList()));
            }
            else // Unlucky, we need to compare the edge lists,
            {
                return(this.getEdgeList().Equals(other.getEdgeList()));
            }
        }
Beispiel #3
0
        /**
         * {@inheritDoc}
         */
        public GraphPath <V, E> getPath(V targetVertex)
        {
            if (source.Equals(targetVertex))
            {
                return(GraphWalk <V, E> .singletonWalk(g, source, 0d));
            }

            List <E> edgeList = new List <E>();

            V cur = targetVertex;
            KeyValuePair <Double, E> p;
            bool find = map.TryGetValue(cur, out p);

            if (!find || p.Key.Equals(Double.PositiveInfinity))
            {
                return(null);
            }

            double weight = 0d;

            while (find && !p.Equals(source))
            {
                E e = p.Value;
                if (e == null)
                {
                    break;
                }
                edgeList.Insert(0, e);
                weight += g.getEdgeWeight(e);
                cur     = Graphs.getOppositeVertex(g, e, cur);
                find    = map.TryGetValue(cur, out p);
            }

            return(new GraphWalk <V, E>(g, source, targetVertex, null, edgeList, weight));
        }
 /**
  * Create an empty path. Returns null if the source vertex is different than the target vertex.
  *
  * @param source the source vertex
  * @param sink the sink vertex
  * @return an empty path or null null if the source vertex is different than the target vertex
  */
 protected GraphPath <V, E> createEmptyPath(V source, V sink)
 {
     if (source.Equals(sink))
     {
         return(GraphWalk <V, E> .singletonWalk(graph, source, 0d));
     }
     else
     {
         return(null);
     }
 }
Beispiel #5
0
        /**
         * {@inheritDoc}
         */
        public GraphPath <V, E> getPath(V targetVertex)
        {
            GraphPath <V, E> p = paths[targetVertex];

            if (p == null)
            {
                if (source.Equals(targetVertex))
                {
                    return(GraphWalk <V, E> .singletonWalk(graph, source, 0d));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                return(p);
            }
        }
Beispiel #6
0
        /**
         * Reverses the direction of the walk. In case of directed/mixed graphs, the arc directions will
         * be reversed. An exception is thrown if reversing an arc (u,v) is impossible because arc (v,u)
         * is not present in the graph.
         *
         * @param walkWeightCalculator Function used to calculate the weight of the reversed GraphWalk
         * @throws InvalidGraphWalkException if the path is invalid
         * @return a reversed GraphWalk
         */
        public GraphWalk <V, E> reverse(Func <GraphWalk <V, E>, Double> walkWeightCalculator)
        {
            List <V> revVertexList = null;
            List <E> revEdgeList   = null;
            double   revWeight     = 0;

            if (vertexList != null)
            {
                revVertexList = new List <V>(this.vertexList);
                revVertexList.Reverse();
                if (graph.getType().isUndirected())
                {
                    revWeight = this.weight;
                }

                // Check validity of the path. If the path is invalid, then calculating its weight may
                // result in an undefined exception.
                // If an edgeList is provided, then this check can be postponed to the construction of
                // the reversed edge list
                if (!graph.getType().isUndirected() && edgeList == null)
                {
                    for (int i = 0; i < revVertexList.Count - 1; i++)
                    {
                        V u    = revVertexList[i];
                        V v    = revVertexList[i + 1];
                        E edge = graph.getEdge(u, v);
                        if (edge == null)
                        {
                            throw new ArgumentException(
                                      "this walk cannot be reversed. The graph does not contain a reverse arc for arc "
                                      + graph.getEdge(v, u));
                        }
                        else
                        {
                            revWeight += graph.getEdgeWeight(edge);
                        }
                    }
                }
            }

            if (edgeList != null)
            {
                revEdgeList = new List <E>(this.edgeList.Count);

                if (graph.getType().isUndirected())
                {
                    revEdgeList.AddRange(this.edgeList);
                    revEdgeList.Reverse();
                    revWeight = this.weight;
                }
                else
                {
                    var listIterator = edgeList.GetEnumerator();
                    while (listIterator.MoveNext())
                    {
                        E e       = listIterator.Current;
                        V u       = graph.getEdgeSource(e);
                        V v       = graph.getEdgeTarget(e);
                        E revEdge = graph.getEdge(v, u);
                        if (revEdge == null)
                        {
                            throw new ArgumentException(
                                      "this walk cannot be reversed. The graph does not contain a reverse arc for arc "
                                      + e);
                        }
                        revEdgeList.Add(revEdge);
                        revWeight += graph.getEdgeWeight(revEdge);
                    }
                }
            }
            // Update weight of reversed walk
            GraphWalk <V, E> gw = new GraphWalk <V, E>(
                this.graph, this.endVertex, this.startVertex, revVertexList, revEdgeList, 0);

            if (walkWeightCalculator == null)
            {
                gw.weight = revWeight;
            }
            else
            {
                gw.weight = walkWeightCalculator(gw);
            }
            return(gw);
        }