demo/sub_graph_adaptor_demo.cc
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
parent 1875 98698b69a902
child 2013 02e70e25aac5
permissions -rw-r--r--
Some classes assumed that the GraphMaps should be inherited
from an ObserverBase. These classes parents replaced with
DefaultMap which cause that the graph maps should not be
inherited from the ObserverBase.
athos@1583
     1
/* -*- C++ -*-
athos@1583
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
athos@1583
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
athos@1583
     8
 *
athos@1583
     9
 * Permission to use, modify and distribute this software is granted
athos@1583
    10
 * provided that this copyright notice appears in all copies. For
athos@1583
    11
 * precise terms see the accompanying LICENSE file.
athos@1583
    12
 *
athos@1583
    13
 * This software is provided "AS IS" with no warranty of any kind,
athos@1583
    14
 * express or implied, and with no claim as to its suitability for any
athos@1583
    15
 * purpose.
athos@1583
    16
 *
athos@1583
    17
 */
athos@1583
    18
athos@1583
    19
///\ingroup demos
athos@1583
    20
///\file
athos@1583
    21
///\brief Computing maximum number of edge-disjoint shortest paths
athos@1583
    22
///
athos@1583
    23
/// This program computes a maximum number of edge-disjoint shortest paths
athos@1583
    24
/// between nodes \c s and \c t.
alpar@1641
    25
///
alpar@1641
    26
/// \include sub_graph_adaptor_demo.cc
marci@866
    27
athos@1560
    28
// Use a DIMACS max flow file as input.
alpar@1401
    29
// sub_graph_adaptor_demo < dimacs_max_flow_file
athos@1583
    30
// Modified to eat lemon graph format! 
athos@1583
    31
marci@866
    32
marci@866
    33
#include <iostream>
marci@866
    34
#include <fstream>
marci@866
    35
alpar@921
    36
#include <lemon/smart_graph.h>
alpar@921
    37
#include <lemon/dijkstra.h>
alpar@921
    38
#include <lemon/maps.h>
alpar@1401
    39
#include <lemon/graph_adaptor.h>
alpar@921
    40
#include <lemon/dimacs.h>
alpar@921
    41
#include <lemon/preflow.h>
marci@931
    42
#include <tight_edge_filter_map.h>
marci@866
    43
athos@1583
    44
#include <lemon/graph_reader.h>
athos@1577
    45
athos@1577
    46
alpar@921
    47
using namespace lemon;
marci@866
    48
marci@866
    49
using std::cout;
marci@866
    50
using std::endl;
marci@866
    51
athos@1560
    52
int main(int argc, char *argv[]) 
athos@1560
    53
{
athos@1560
    54
  if(argc<2)
athos@1560
    55
  {
athos@1583
    56
      std::cerr << "USAGE: sub_graph_adaptor_demo input_file.lgf" << std::endl;
athos@1583
    57
      std::cerr << "The file 'input_file.lgf' has to contain a max flow "
athos@1583
    58
		<< "instance in \n LEMON format "
athos@1583
    59
		<< "(e.g. sub_gad_input.lgf is such a file)." 
athos@1583
    60
		<< std::endl;
athos@1560
    61
      return 0;
athos@1560
    62
  }
athos@1560
    63
athos@1560
    64
athos@1560
    65
  //input stream to read the graph from
athos@1560
    66
  std::ifstream is(argv[1]);
athos@1560
    67
marci@866
    68
  typedef SmartGraph Graph;
marci@866
    69
marci@866
    70
  typedef Graph::Edge Edge;
marci@866
    71
  typedef Graph::Node Node;
marci@866
    72
  typedef Graph::EdgeIt EdgeIt;
marci@866
    73
  typedef Graph::NodeIt NodeIt;
marci@866
    74
  typedef Graph::EdgeMap<int> LengthMap;
marci@866
    75
marci@866
    76
  Graph g;
marci@866
    77
  Node s, t;
marci@866
    78
  LengthMap length(g);
marci@866
    79
athos@1583
    80
  //readDimacs(is, g, length, s, t);
marci@866
    81
athos@1577
    82
athos@1583
    83
  GraphReader<SmartGraph> reader(is,g);
athos@1583
    84
  reader.readNode("source",s).readNode("target",t)
athos@1583
    85
    .readEdgeMap("length",length).run();
athos@1577
    86
alpar@986
    87
  cout << "edges with lengths (of form id, source--length->target): " << endl;
marci@866
    88
  for(EdgeIt e(g); e!=INVALID; ++e) 
alpar@986
    89
    cout << " " << g.id(e) << ", " << g.id(g.source(e)) << "--" 
alpar@986
    90
	 << length[e] << "->" << g.id(g.target(e)) << endl;
marci@866
    91
marci@866
    92
  cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
marci@866
    93
marci@866
    94
  typedef Dijkstra<Graph, LengthMap> Dijkstra;
marci@866
    95
  Dijkstra dijkstra(g, length);
marci@866
    96
  dijkstra.run(s);
marci@866
    97
marci@869
    98
  // This map returns true exactly for those edges which are 
marci@869
    99
  // tight w.r.t the length funcion and the potential 
marci@869
   100
  // given by the dijkstra algorithm.
marci@866
   101
  typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap> 
marci@866
   102
    TightEdgeFilter;
marci@866
   103
  TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
marci@866
   104
marci@932
   105
//  ConstMap<Node, bool> const_true_map(true);
marci@869
   106
  // This graph contains exaclty the tight edges.
alpar@1401
   107
// typedef SubGraphAdaptor<Graph, ConstMap<Node, bool>, TightEdgeFilter> SubGW;
alpar@1401
   108
  typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
marci@932
   109
  SubGW gw(g, tight_edge_filter);
marci@866
   110
marci@866
   111
  ConstMap<Edge, int> const_1_map(1);
marci@866
   112
  Graph::EdgeMap<int> flow(g, 0);
marci@869
   113
  // Max flow between s and t in the graph of tight edges.
marci@866
   114
  Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > 
marci@866
   115
    preflow(gw, s, t, const_1_map, flow);
marci@866
   116
  preflow.run();
marci@866
   117
athos@1544
   118
  cout << "maximum number of edge-disjoint shortest paths: " 
marci@931
   119
       << preflow.flowValue() << endl;
marci@866
   120
  cout << "edges of the maximum number of edge-disjoint shortest s-t paths: " 
marci@866
   121
       << endl;
marci@866
   122
  for(EdgeIt e(g); e!=INVALID; ++e) 
marci@866
   123
    if (flow[e])
marci@931
   124
      cout << " " << g.id(e) << ", "
alpar@986
   125
	   << g.id(g.source(e)) << "--" 
alpar@986
   126
	   << length[e] << "->" << g.id(g.target(e)) << endl;
marci@866
   127
}