lemon/csp.h
author alpar
Tue, 13 Mar 2007 12:33:40 +0000
changeset 2406 0ffc78641b34
parent 2391 14a343be7a5a
child 2486 0c498f2239a8
permissions -rw-r--r--
Better doc.
alpar@2360
     1
/* -*- C++ -*-
alpar@2360
     2
 *
alpar@2360
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2360
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
alpar@2360
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2360
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2360
     8
 *
alpar@2360
     9
 * Permission to use, modify and distribute this software is granted
alpar@2360
    10
 * provided that this copyright notice appears in all copies. For
alpar@2360
    11
 * precise terms see the accompanying LICENSE file.
alpar@2360
    12
 *
alpar@2360
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2360
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2360
    15
 * purpose.
alpar@2360
    16
 *
alpar@2360
    17
 */
alpar@2360
    18
alpar@2360
    19
#ifndef LEMON_CSP_H
alpar@2360
    20
#define LEMON_CSP_H
alpar@2360
    21
deba@2376
    22
///\ingroup approx
alpar@2360
    23
///\file
alpar@2360
    24
///\brief Algorithm for the Resource Constrained Shortest Path problem.
alpar@2360
    25
///
alpar@2360
    26
///
alpar@2360
    27
///\todo dijkstraZero() solution should be revised.
alpar@2360
    28
alpar@2360
    29
#include <lemon/list_graph.h>
alpar@2360
    30
#include <lemon/graph_utils.h>
alpar@2360
    31
#include <lemon/error.h>
alpar@2360
    32
#include <lemon/maps.h>
alpar@2360
    33
#include <lemon/tolerance.h>
alpar@2360
    34
#include <lemon/dijkstra.h>
alpar@2360
    35
#include <lemon/path.h>
alpar@2360
    36
#include <lemon/counter.h>
alpar@2360
    37
namespace lemon {
deba@2377
    38
deba@2377
    39
  ///\ingroup approx
alpar@2360
    40
  
alpar@2360
    41
  ///Algorithms for the Resource Constrained Shortest Path Problem
alpar@2360
    42
  
alpar@2373
    43
  ///The Resource Constrained Shortest (Least Cost) Path problem is the
alpar@2373
    44
  ///following. We are given a directed graph with two additive weightings
alpar@2373
    45
  ///on the edges, referred as \e cost and \e delay. In addition,
alpar@2373
    46
  ///a source and a destination node \e s and \e t and a delay
alpar@2373
    47
  ///constraint \e D is given. A path \e p is called \e feasible
alpar@2373
    48
  ///if <em>delay(p)\<=D</em>. Then, the task is to find the least cost
alpar@2373
    49
  ///feasible path.
alpar@2360
    50
  ///
alpar@2360
    51
  template<class Graph,
alpar@2360
    52
	   class CM=typename Graph:: template EdgeMap<double>,
alpar@2360
    53
	   class DM=CM>
alpar@2360
    54
  class ConstrainedShortestPath 
alpar@2360
    55
  {
alpar@2360
    56
  public:
alpar@2360
    57
    
alpar@2360
    58
    GRAPH_TYPEDEFS(typename Graph);
alpar@2360
    59
    
alpar@2360
    60
    typedef SimplePath<Graph> Path;
alpar@2360
    61
    
deba@2401
    62
  private:
deba@2401
    63
    
deba@2401
    64
    const Graph &_g;
alpar@2360
    65
    Tolerance<double> tol;
alpar@2360
    66
deba@2401
    67
    const CM &_cost;
deba@2401
    68
    const DM &_delay;
alpar@2360
    69
alpar@2360
    70
    class CoMap 
alpar@2360
    71
    {
deba@2401
    72
      const CM &_cost;
deba@2401
    73
      const DM &_delay;
alpar@2360
    74
      double _lambda;
alpar@2360
    75
    public:
alpar@2360
    76
      typedef typename CM::Key Key;
alpar@2360
    77
      typedef double Value;
deba@2401
    78
      CoMap(const CM &c, const DM &d) :_cost(c), _delay(d), _lambda(0) {}
alpar@2360
    79
      double lambda() const { return _lambda; }
alpar@2360
    80
      void lambda(double l)  { _lambda=l; }
alpar@2360
    81
      Value operator[](Key &e) const 
alpar@2360
    82
      {
alpar@2360
    83
	return _cost[e]+_lambda*_delay[e];
alpar@2360
    84
      }
deba@2401
    85
    };
deba@2401
    86
deba@2401
    87
    CoMap _co_map;
alpar@2360
    88
    
alpar@2360
    89
    
alpar@2360
    90
    Dijkstra<Graph, CoMap> _dij;
deba@2401
    91
deba@2401
    92
  public:
deba@2401
    93
    
alpar@2360
    94
    ///\e
alpar@2360
    95
    
alpar@2360
    96
    ///\e
alpar@2360
    97
    ///
deba@2401
    98
    ConstrainedShortestPath(const Graph &g, const CM &ct, const DM &dl)
deba@2386
    99
      : _g(g), _cost(ct), _delay(dl),
deba@2401
   100
	_co_map(ct, dl), _dij(_g,_co_map) {}
alpar@2360
   101
    
alpar@2360
   102
alpar@2360
   103
    ///Compute the cost of a path
deba@2401
   104
    double cost(const Path &p) const
alpar@2360
   105
    {
alpar@2360
   106
      double s=0;
alpar@2360
   107
      //      Path r;  
alpar@2360
   108
      for(typename Path::EdgeIt e(p);e!=INVALID;++e) s+=_cost[e];
alpar@2360
   109
      return s;
alpar@2360
   110
    }
alpar@2360
   111
alpar@2360
   112
    ///Compute the delay of a path
deba@2401
   113
    double delay(const Path &p) const
alpar@2360
   114
    {
alpar@2360
   115
      double s=0;
alpar@2360
   116
      for(typename Path::EdgeIt e(p);e!=INVALID;++e) s+=_delay[e];
alpar@2360
   117
      return s;
alpar@2360
   118
    }
alpar@2360
   119
    
alpar@2360
   120
    ///Runs the LARAC algorithm
alpar@2360
   121
    
alpar@2360
   122
    ///This function runs a Lagrange relaxation based heuristic to find
alpar@2360
   123
    ///a delay constrained least cost path.
alpar@2360
   124
    ///\param s source node
alpar@2360
   125
    ///\param t target node
alpar@2360
   126
    ///\retval lo_bo a lower bound on the optimal solution
alpar@2360
   127
    ///\return the found path or an empty 
alpar@2360
   128
    Path larac(Node s, Node t, double delta, double &lo_bo) 
alpar@2360
   129
    {
alpar@2360
   130
      NoCounter cnt("LARAC iterations: ");
alpar@2360
   131
      double lambda=0;
alpar@2360
   132
      double cp,cq,dp,dq,cr,dr;
alpar@2360
   133
      Path p;
alpar@2360
   134
      Path q;
alpar@2360
   135
      Path r;
alpar@2360
   136
      {
alpar@2360
   137
	Dijkstra<Graph,CM> dij(_g,_cost);
alpar@2360
   138
	dij.run(s,t);
alpar@2360
   139
	cnt++;
alpar@2360
   140
	if(!dij.reached(t)) return Path();
alpar@2360
   141
	p=dij.path(t);
alpar@2360
   142
	cp=cost(p);
alpar@2360
   143
	dp=delay(p);
alpar@2360
   144
      }
alpar@2360
   145
      if(delay(p)<=delta) return p;
alpar@2360
   146
      {
alpar@2360
   147
	Dijkstra<Graph,DM> dij(_g,_delay);
alpar@2360
   148
	dij.run(s,t);
alpar@2360
   149
	cnt++;
alpar@2360
   150
	q=dij.path(t);
alpar@2360
   151
	cq=cost(q);
alpar@2360
   152
	dq=delay(q);
alpar@2360
   153
      }
alpar@2360
   154
      if(delay(q)>delta) return Path();
alpar@2360
   155
      while (true) {
alpar@2360
   156
	lambda=(cp-cq)/(dq-dp);
alpar@2360
   157
	_co_map.lambda(lambda);
alpar@2360
   158
	_dij.run(s,t);
alpar@2360
   159
	cnt++;
alpar@2360
   160
	r=_dij.path(t);
alpar@2360
   161
	cr=cost(r);
alpar@2360
   162
	dr=delay(r);
alpar@2360
   163
	if(!tol.less(cr+lambda*dr,cp+lambda*dp)) {
alpar@2360
   164
	  lo_bo=cq+lambda*(dq-delta);
alpar@2360
   165
	  return q;
alpar@2360
   166
	}
alpar@2360
   167
	else if(tol.less(dr,delta)) 
alpar@2360
   168
	  {
alpar@2360
   169
	    q=r;
alpar@2360
   170
	    cq=cr;
alpar@2360
   171
	    dq=dr;
alpar@2360
   172
	  }
alpar@2360
   173
	else if(tol.less(delta,dr))
alpar@2360
   174
	  {
alpar@2360
   175
	    p=r;
alpar@2360
   176
	    cp=cr;
alpar@2360
   177
	    dp=dr;
alpar@2360
   178
	  }
alpar@2360
   179
	else return r;
alpar@2360
   180
      }
alpar@2360
   181
    }
alpar@2360
   182
  };
alpar@2360
   183
  
alpar@2360
   184
alpar@2360
   185
} //END OF NAMESPACE LEMON
alpar@2360
   186
alpar@2360
   187
#endif