// Copyright 2003, Trustees of Indiana University // Please see the license in the file ../LICENSE // dijkstra_shortest_paths algorithm from BFS using GCollections; public class negative_edge: System.Exception {} public class indirect_cmp< Vertex, Distance, DistanceMap, DistanceCompare> : StrictWeakOrdering where DistanceMap: ReadablePropertyMap, DistanceCompare: StrictWeakOrdering { private DistanceMap m_distance; private DistanceCompare m_compare; public indirect_cmp(DistanceMap distance, DistanceCompare compare) { m_distance = distance; m_compare = compare; } public bool less(Vertex a, Vertex b) { return m_compare.less(((ReadablePropertyMap)m_distance)[a], ((ReadablePropertyMap)m_distance)[b]); } } public class dijkstra_visitor< Graph, QueueType, WeightMap, PredecessorMap, DistanceMap, DistanceCombine, DistanceCompare, Vertex, Edge, Distance> : Visitor where QueueType: MutableQueue, WeightMap: ReadablePropertyMap, PredecessorMap: ReadWritePropertyMap, DistanceMap: ReadWritePropertyMap, DistanceCombine: BinaryFunction, DistanceCompare: StrictWeakOrdering, Edge: GraphEdge { private WeightMap m_weight; private DistanceCompare m_compare; private DistanceCombine m_combine; private Distance m_zero; private DistanceMap m_distance; private PredecessorMap m_predecessor; private QueueType m_Q; public dijkstra_visitor(QueueType Q, WeightMap weight, PredecessorMap predecessor, DistanceMap distance, DistanceCombine combine, DistanceCompare compare, Distance zero) { m_Q = Q; m_weight = weight; m_predecessor = predecessor; m_distance = distance; m_combine = combine; m_compare = compare; m_zero = zero; } public void initialize_vertex(Vertex u, Graph g) {} public void discover_vertex(Vertex u, Graph g) {} public void examine_edge(Edge e, Graph g) { if (m_compare.less(((ReadablePropertyMap)m_weight)[e], m_zero)) throw new negative_edge(); } public void tree_edge(Edge e, Graph g) { relax.go(e, m_weight, m_distance, m_predecessor, m_combine, m_compare); } public void non_tree_edge(Edge e, Graph g) {} public void gray_target(Edge e, Graph g) { bool relaxed = relax.go(e, m_weight, m_distance, m_predecessor, m_combine, m_compare); if (relaxed) m_Q.update(e.target); } public void black_target(Edge e, Graph g) {} public void finish_vertex(Vertex u, Graph g) {} } public class dijkstra_shortest_paths { public static void go< GraphT, Vertex, Edge, VertexIterator, OutEdgeIterator, WeightMap, DistanceMap, Distance, PredecessorMap, DistanceCombine, DistanceCompare> (GraphT g, Vertex s, PredecessorMap predecessor, DistanceMap distance, WeightMap weight, DistanceCompare compare, DistanceCombine combine, Distance inf, Distance zero) where GraphT: VertexListAndIncidenceGraph, Edge: GraphEdge, VertexIterator: IEnumerable, OutEdgeIterator: IEnumerable, WeightMap: ReadablePropertyMap, DistanceMap: ReadWritePropertyMap, PredecessorMap: ReadWritePropertyMap, DistanceCombine: BinaryFunction, DistanceCompare: StrictWeakOrdering { for (IEnumerator ui = g.vertices().GetEnumerator(); ui.MoveNext();) { Vertex u = ui.Current; ((ReadWritePropertyMap)distance)[u] = inf; ((ReadWritePropertyMap)predecessor)[u] = u; } ((ReadWritePropertyMap)distance)[s] = zero; indirect_cmp icmp = new indirect_cmp(distance, compare); mutable_queue > Q = new mutable_queue >(icmp); dijkstra_visitor >, WeightMap, PredecessorMap, DistanceMap, DistanceCombine, DistanceCompare, Vertex, Edge, Distance> vis = new dijkstra_visitor >, WeightMap, PredecessorMap, DistanceMap, DistanceCombine, DistanceCompare, Vertex, Edge, Distance>(Q, weight, predecessor, distance, combine, compare, zero); hash_property_map color = new hash_property_map(); // Initialize color map for (IEnumerator ui = g.vertices().GetEnumerator(); ui.MoveNext();) { Vertex v = ui.Current; color[v] = ColorValue.white; } graph_search.go< GraphT, Vertex, Edge, VertexIterator, OutEdgeIterator, dijkstra_visitor< GraphT, mutable_queue< Vertex, indirect_cmp >, WeightMap, PredecessorMap, DistanceMap, DistanceCombine, DistanceCompare, Vertex, Edge, Distance>, hash_property_map, mutable_queue > > (g, s, vis, color, Q); } }