athos@276
|
1 |
// -*- c++ -*-
|
athos@276
|
2 |
#ifndef HUGO_SUURBALLE_H
|
athos@276
|
3 |
#define HUGO_SUURBALLE_H
|
athos@276
|
4 |
|
athos@276
|
5 |
#include <iostream>
|
athos@276
|
6 |
#include <dijkstra.h>
|
athos@276
|
7 |
#include <graph_wrapper.h>
|
athos@276
|
8 |
namespace hugo {
|
athos@276
|
9 |
|
athos@276
|
10 |
|
athos@276
|
11 |
///\brief Implementation of Suurballe's algorithm
|
athos@276
|
12 |
///
|
athos@276
|
13 |
/// The class \ref hugo::Suurballe "Suurballe" implements
|
athos@276
|
14 |
/// Suurballe's algorithm which seeks for k edge-disjoint paths
|
athos@276
|
15 |
/// from a given source node to a given target node in an
|
athos@276
|
16 |
/// edge-weighted directed graph having minimal total cost.
|
athos@276
|
17 |
///
|
athos@276
|
18 |
///
|
athos@276
|
19 |
|
athos@276
|
20 |
|
athos@276
|
21 |
template <typename Graph, typename T,
|
athos@276
|
22 |
typename LengthMap=typename Graph::EdgeMap<T> >
|
athos@276
|
23 |
class Suurballe {
|
athos@276
|
24 |
|
athos@276
|
25 |
|
athos@276
|
26 |
//Writing maps
|
athos@276
|
27 |
class ConstMap {
|
athos@276
|
28 |
public :
|
athos@276
|
29 |
typedef int ValueType;
|
athos@276
|
30 |
int operator[](typename Graph::Edge e) const {
|
athos@276
|
31 |
return 1;
|
athos@276
|
32 |
}
|
athos@276
|
33 |
};
|
athos@276
|
34 |
/*
|
athos@276
|
35 |
// template <typename Graph, typename T>
|
athos@276
|
36 |
class ModLengthMap {
|
athos@276
|
37 |
typedef typename Graph::EdgeMap<T> EdgeMap;
|
athos@276
|
38 |
typedef typename Graph::NodeMap<T> NodeMap;
|
athos@276
|
39 |
|
athos@276
|
40 |
const EdgeMap &ol;
|
athos@276
|
41 |
const NodeMap &pot;
|
athos@276
|
42 |
public :
|
athos@276
|
43 |
typedef typename EdgeMap::KeyType KeyType;
|
athos@276
|
44 |
typedef typename EdgeMap::ValueType ValueType;
|
athos@276
|
45 |
|
athos@276
|
46 |
double operator[](typename Graph::EdgeIt e) const {
|
athos@276
|
47 |
return 10;//ol.get(e)-pot.get(v)-pot.get(u);
|
athos@276
|
48 |
}
|
athos@276
|
49 |
|
athos@276
|
50 |
ModLengthMap(const EdgeMap &o,
|
athos@276
|
51 |
const NodeMap &p) :
|
athos@276
|
52 |
ol(o), pot(p){};
|
athos@276
|
53 |
};
|
athos@276
|
54 |
*/
|
athos@276
|
55 |
|
athos@276
|
56 |
|
athos@276
|
57 |
typedef typename Graph::Node Node;
|
athos@276
|
58 |
typedef typename Graph::NodeIt NodeIt;
|
athos@276
|
59 |
typedef typename Graph::Edge Edge;
|
athos@276
|
60 |
typedef typename Graph::OutEdgeIt OutEdgeIt;
|
athos@276
|
61 |
typedef ResGraphWrapper< Graph,T,typename Graph::EdgeMap<int>, ConstMap > ResGraphType;
|
athos@276
|
62 |
|
athos@276
|
63 |
const Graph& G;
|
athos@276
|
64 |
const LengthMap& length;
|
athos@276
|
65 |
|
athos@276
|
66 |
|
athos@276
|
67 |
//auxiliary variables
|
athos@276
|
68 |
|
athos@276
|
69 |
typename Graph::EdgeMap<int> reversed;
|
athos@276
|
70 |
typename Graph::NodeMap<T> dijkstra_dist;
|
athos@276
|
71 |
|
athos@276
|
72 |
public :
|
athos@276
|
73 |
|
athos@276
|
74 |
|
athos@276
|
75 |
Suurballe(Graph& _G, LengthMap& _length) : G(_G),
|
athos@276
|
76 |
length(_length), reversed(_G), dijkstra_dist(_G){ }
|
athos@276
|
77 |
|
athos@276
|
78 |
///Runs Suurballe's algorithm
|
athos@276
|
79 |
///Returns true iff there are k edge-disjoint paths from s to t
|
athos@276
|
80 |
bool run(Node s, Node t, int k) {
|
athos@276
|
81 |
|
athos@276
|
82 |
LengthMap mod_length_c = length;
|
athos@276
|
83 |
ConstMap const1map;
|
athos@276
|
84 |
//ResGraphWrapper< Graph,T,typename Graph::EdgeMap<int>, ConstMap>
|
athos@276
|
85 |
ResGraphType res_graph(G, reversed, const1map);
|
athos@276
|
86 |
//ModLengthMap modified_length(length, dijkstra_dist);
|
athos@276
|
87 |
//Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, modified_length);
|
athos@276
|
88 |
//ResGraphWrapper< Graph,T,typename Graph::EdgeMap<int>, ConstMap>
|
athos@276
|
89 |
Dijkstra<ResGraphType, LengthMap> dijkstra(res_graph, mod_length_c);
|
athos@276
|
90 |
|
athos@276
|
91 |
for (int i=0; i<k; ++i){
|
athos@276
|
92 |
dijkstra.run(s);
|
athos@276
|
93 |
if (!dijkstra.reached(t)){
|
athos@276
|
94 |
//There is no k path from s to t
|
athos@276
|
95 |
return false;
|
athos@276
|
96 |
};
|
athos@276
|
97 |
{
|
athos@276
|
98 |
//We have to copy the potential
|
athos@276
|
99 |
typename ResGraphType::EdgeIt e;
|
athos@276
|
100 |
for ( res_graph.first(e) ; res_graph.valid(e) ; res_graph.next(e) ) {
|
athos@276
|
101 |
//dijkstra_dist[e] = dijkstra.distMap()[e];
|
athos@276
|
102 |
mod_length_c[Edge(e)] = mod_length_c[Edge(e)] -
|
athos@276
|
103 |
dijkstra.distMap()[res_graph.head(e)] +
|
athos@276
|
104 |
dijkstra.distMap()[res_graph.tail(e)];
|
athos@276
|
105 |
}
|
athos@276
|
106 |
}
|
athos@276
|
107 |
|
athos@276
|
108 |
//Reversing the sortest path
|
athos@276
|
109 |
Node n=t;
|
athos@276
|
110 |
Edge e;
|
athos@276
|
111 |
while (n!=s){
|
athos@276
|
112 |
e=dijkstra.pred(n);
|
athos@276
|
113 |
n=dijkstra.predNode(n);
|
athos@276
|
114 |
reversed[e] = 1-reversed[e];
|
athos@276
|
115 |
}
|
athos@276
|
116 |
|
athos@276
|
117 |
|
athos@276
|
118 |
}
|
athos@276
|
119 |
return true;
|
athos@276
|
120 |
}
|
athos@276
|
121 |
|
athos@276
|
122 |
|
athos@276
|
123 |
|
athos@276
|
124 |
|
athos@276
|
125 |
|
athos@276
|
126 |
};//class Suurballe
|
athos@276
|
127 |
|
athos@276
|
128 |
|
athos@276
|
129 |
|
athos@276
|
130 |
|
athos@276
|
131 |
} //namespace hugo
|
athos@276
|
132 |
|
athos@276
|
133 |
#endif //HUGO_SUURBALLE_H
|