/** * 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); }
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())); } }
/** * {@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); } }
/** * {@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); } }
/** * 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); }