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