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