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