src/work/athos/minlengthpaths.h
author alpar
Sat, 17 Apr 2004 13:15:53 +0000
changeset 348 b63ea19e502e
parent 329 0dade87d013b
child 430 60e4627e8c74
permissions -rw-r--r--
A bool Edge Map with iterators that goes through the true or the false edges.
athos@276
     1
// -*- c++ -*-
athos@306
     2
#ifndef HUGO_MINLENGTHPATHS_H
athos@306
     3
#define HUGO_MINLENGTHPATHS_H
athos@276
     4
alpar@294
     5
///\file
athos@306
     6
///\brief An algorithm for finding k paths of minimal total length.
alpar@294
     7
athos@276
     8
#include <iostream>
athos@276
     9
#include <dijkstra.h>
athos@276
    10
#include <graph_wrapper.h>
athos@306
    11
#include <maps.h>
athos@322
    12
#include <vector>
athos@322
    13
athos@306
    14
athos@276
    15
namespace hugo {
athos@276
    16
athos@276
    17
athos@322
    18
klao@310
    19
  ///\brief Implementation of an algorithm for finding k paths between 2 nodes 
athos@306
    20
  /// of minimal total length 
klao@310
    21
  ///
klao@310
    22
  /// The class \ref hugo::MinLengthPaths "MinLengthPaths" implements
klao@310
    23
  /// an algorithm which finds k edge-disjoint paths
klao@310
    24
  /// from a given source node to a given target node in an
klao@310
    25
  /// edge-weighted directed graph having minimal total weigth (length).
athos@276
    26
klao@310
    27
  template <typename Graph, typename LengthMap>
athos@306
    28
  class MinLengthPaths {
athos@276
    29
klao@310
    30
    typedef typename LengthMap::ValueType Length;
athos@276
    31
athos@276
    32
    typedef typename Graph::Node Node;
athos@276
    33
    typedef typename Graph::NodeIt NodeIt;
athos@276
    34
    typedef typename Graph::Edge Edge;
athos@276
    35
    typedef typename Graph::OutEdgeIt OutEdgeIt;
athos@306
    36
    typedef typename Graph::EdgeMap<int> EdgeIntMap;
athos@306
    37
athos@306
    38
    typedef ConstMap<Edge,int> ConstMap;
athos@306
    39
marci@330
    40
    typedef ResGraphWrapper<const Graph,int,ConstMap,EdgeIntMap> ResGraphType;
athos@276
    41
athos@306
    42
athos@306
    43
    class ModLengthMap {   
klao@310
    44
      typedef typename ResGraphType::NodeMap<Length> NodeMap;
athos@306
    45
      const ResGraphType& G;
klao@310
    46
      const EdgeIntMap& rev;
klao@310
    47
      const LengthMap &ol;
klao@310
    48
      const NodeMap &pot;
athos@306
    49
    public :
athos@306
    50
      typedef typename LengthMap::KeyType KeyType;
athos@306
    51
      typedef typename LengthMap::ValueType ValueType;
athos@306
    52
athos@306
    53
      ValueType operator[](typename ResGraphType::Edge e) const {     
athos@322
    54
	//if ( (1-2*rev[e])*ol[e]-(pot[G.head(e)]-pot[G.tail(e)] ) <0 ){
athos@322
    55
	//  std::cout<<"Negative length!!"<<std::endl;
athos@322
    56
	//}
athos@306
    57
	return (1-2*rev[e])*ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
athos@306
    58
      }     
athos@306
    59
klao@310
    60
      ModLengthMap(const ResGraphType& _G, const EdgeIntMap& _rev, 
klao@310
    61
		   const LengthMap &o,  const NodeMap &p) : 
athos@306
    62
	G(_G), rev(_rev), ol(o), pot(p){}; 
athos@306
    63
    };
athos@306
    64
    
athos@306
    65
athos@276
    66
    const Graph& G;
athos@276
    67
    const LengthMap& length;
athos@276
    68
alpar@328
    69
    //auxiliary variables
athos@322
    70
athos@314
    71
    //The value is 1 iff the edge is reversed. 
athos@314
    72
    //If the algorithm has finished, the edges of the seeked paths are 
athos@314
    73
    //exactly those that are reversed 
athos@306
    74
    EdgeIntMap reversed; 
athos@276
    75
    
athos@322
    76
    //Container to store found paths
athos@322
    77
    std::vector< std::vector<Edge> > paths;
athos@322
    78
athos@276
    79
  public :
klao@310
    80
athos@276
    81
athos@306
    82
    MinLengthPaths(Graph& _G, LengthMap& _length) : G(_G), 
athos@306
    83
      length(_length), reversed(_G)/*, dijkstra_dist(_G)*/{ }
athos@276
    84
alpar@294
    85
    
alpar@329
    86
    ///Runs the algorithm.
alpar@329
    87
alpar@329
    88
    ///Runs the algorithm.
athos@306
    89
    ///Returns k if there are at least k edge-disjoint paths from s to t.
alpar@329
    90
    ///Otherwise it returns the number of found edge-disjoint paths from s to t.
athos@306
    91
    int run(Node s, Node t, int k) {
athos@306
    92
      ConstMap const1map(1);
athos@276
    93
athos@314
    94
      //We need a residual graph, in which some of the edges are reversed
marci@330
    95
      ResGraphType res_graph(G, const1map, reversed);
athos@306
    96
athos@306
    97
      //Initialize the copy of the Dijkstra potential to zero
klao@310
    98
      typename ResGraphType::NodeMap<Length> dijkstra_dist(res_graph);
klao@310
    99
      ModLengthMap mod_length(res_graph, reversed, length, dijkstra_dist);
athos@306
   100
athos@306
   101
      Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
athos@322
   102
athos@322
   103
      int i;
athos@322
   104
      for (i=0; i<k; ++i){
athos@276
   105
	dijkstra.run(s);
athos@276
   106
	if (!dijkstra.reached(t)){
athos@314
   107
	  //There are no k paths from s to t
athos@322
   108
	  break;
athos@276
   109
	};
athos@306
   110
	
athos@306
   111
	{
athos@306
   112
	  //We have to copy the potential
athos@306
   113
	  typename ResGraphType::NodeIt n;
athos@306
   114
	  for ( res_graph.first(n) ; res_graph.valid(n) ; res_graph.next(n) ) {
athos@306
   115
	      dijkstra_dist[n] += dijkstra.distMap()[n];
athos@306
   116
	  }
athos@306
   117
	}
athos@306
   118
athos@306
   119
athos@276
   120
	//Reversing the sortest path
athos@276
   121
	Node n=t;
athos@276
   122
	Edge e;
athos@276
   123
	while (n!=s){
athos@291
   124
	  e = dijkstra.pred(n);
athos@291
   125
	  n = dijkstra.predNode(n);
athos@276
   126
	  reversed[e] = 1-reversed[e];
athos@276
   127
	}
athos@276
   128
athos@276
   129
	  
athos@276
   130
      }
athos@322
   131
      
athos@322
   132
      //Let's find the paths
athos@322
   133
      //We put the paths into vectors (just for now). In the meantime we lose 
athos@322
   134
      //the information stored in 'reversed'
athos@322
   135
      //We suppose the lengths to be positive now.
athos@322
   136
      paths.clear();
athos@322
   137
      paths.resize(k);
athos@322
   138
      for (int j=0; j<i; ++j){
athos@322
   139
	Node n=s;
athos@322
   140
	OutEdgeIt e;
athos@322
   141
athos@322
   142
	while (n!=t){
athos@322
   143
athos@322
   144
athos@322
   145
	  G.first(e,n);
athos@322
   146
	  
athos@322
   147
	  while (!reversed[e]){
athos@322
   148
	    G.next(e);
athos@322
   149
	  }
athos@322
   150
	  n = G.head(e);
athos@322
   151
	  paths[j].push_back(e);
athos@322
   152
	  reversed[e] = 1-reversed[e];
athos@322
   153
	}
athos@322
   154
	
athos@322
   155
      }
athos@322
   156
athos@322
   157
      return i;
athos@276
   158
    }
athos@276
   159
athos@276
   160
klao@310
   161
  }; //class MinLengthPaths
athos@276
   162
athos@276
   163
athos@276
   164
} //namespace hugo
athos@276
   165
athos@306
   166
#endif //HUGO_MINLENGTHPATHS_H