// Copyright 2003, Trustees of Indiana University
// Please see the license in the file ../LICENSE
using GCollections;
public class null_property_map: ReadWritePropertyMap {
public B this[A a] {
get {throw new System.Exception();}
set {}
}
}
public class johnson_all_pairs_shortest_paths {
public static bool go
(Graph g, WeightMap w, WeightMap2 w2, DistanceMap distance, DistanceMatrix distance_matrix, Distance zero, Distance inf, DistanceCombine combine, DistanceNegate negate, DistanceCompare compare)
where Graph: VertexListAndIncidenceAndEdgeListGraph,
Edge: GraphEdge,
VertexIterator: IEnumerable,
OutEdgeIterator: IEnumerable,
EdgeIterator: IEnumerable,
WeightMap: ReadablePropertyMap,
WeightMap2: ReadWritePropertyMap,
DistanceMap: ReadWritePropertyMap,
DistanceMatrixElement: ReadWritePropertyMap,
DistanceMatrix: ReadablePropertyMap,
DistanceCombine: BinaryFunction,
DistanceCompare: StrictWeakOrdering,
DistanceNegate: UnaryFunction {
// Set distance to all vertices to zero (emulates special "s" vertex used in CLR)
for (IEnumerator vi = g.vertices().GetEnumerator(); vi.MoveNext();) {
Vertex v = vi.Current;
((ReadWritePropertyMap)distance)[v] = zero;
}
// Do Bellman-Ford to get factors for reweighting
bool bf_worked = bellman_ford_shortest_paths.go<
Graph,
Vertex,
Edge,
EdgeIterator,
Distance,
WeightMap,
null_property_map,
DistanceMap,
DistanceCombine,
DistanceCompare>
(g, g.num_vertices(), w, new null_property_map(), distance,
combine, compare);
if (!bf_worked) return false; // Negative-weight cycle
// Set up reweighting
for (IEnumerator ei = g.edges().GetEnumerator(); ei.MoveNext();) {
Edge e = ei.Current;
((ReadWritePropertyMap)w2)[e] = combine.op(combine.op(((ReadablePropertyMap)w)[e], ((ReadWritePropertyMap)distance)[e.source]), negate.op(((ReadWritePropertyMap)distance)[e.target]));
}
// Do Dijkstra from each vertex
for (IEnumerator vi = g.vertices().GetEnumerator(); vi.MoveNext();) {
Vertex v = vi.Current;
DistanceMatrixElement dm = ((ReadablePropertyMap)distance_matrix)[v];
dijkstra_shortest_paths.go<
Graph,
Vertex,
Edge,
VertexIterator,
OutEdgeIterator,
WeightMap2,
DistanceMatrixElement,
Distance,
null_property_map,
DistanceCombine,
DistanceCompare>
(g, v, new null_property_map(), dm, w2, compare, combine, inf, zero);
// Adjust returned distances to account for reweighting
for (IEnumerator vi2 = g.vertices().GetEnumerator(); vi2.MoveNext();) {
Vertex v2 = vi2.Current;
((ReadWritePropertyMap)dm)[v2] = combine.op(combine.op(((ReadWritePropertyMap)dm)[v2], ((ReadWritePropertyMap)distance)[v2]), negate.op(((ReadWritePropertyMap)distance)[v]));
}
}
return true;
}
}