demo/lp_maxflow_demo.cc
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
parent 1875 98698b69a902
child 2369 6ae1a97055a2
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@1560
     1
/* -*- C++ -*-
athos@1560
     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@1560
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
athos@1560
     8
 *
athos@1560
     9
 * Permission to use, modify and distribute this software is granted
athos@1560
    10
 * provided that this copyright notice appears in all copies. For
athos@1560
    11
 * precise terms see the accompanying LICENSE file.
athos@1560
    12
 *
athos@1560
    13
 * This software is provided "AS IS" with no warranty of any kind,
athos@1560
    14
 * express or implied, and with no claim as to its suitability for any
athos@1560
    15
 * purpose.
athos@1560
    16
 *
athos@1560
    17
 */
athos@1560
    18
athos@1560
    19
///\ingroup demos
athos@1560
    20
///\file
athos@1560
    21
///\brief Max flow problem solved with an LP solver (demo).
athos@1560
    22
///
athos@1583
    23
/// This demo program shows how to solve a maximum (or maximal) flow
athos@1583
    24
/// problem using the LEMON LP solver interface. We would like to lay
athos@1583
    25
/// the emphasis on the simplicity of the way one can formulate LP
athos@1583
    26
/// constraints that arise in graph theory in our library LEMON .
alpar@1641
    27
///
alpar@1641
    28
/// \include lp_maxflow_demo.cc
athos@1560
    29
alpar@1361
    30
#include<lemon/graph_reader.h>
alpar@1361
    31
#include<lemon/list_graph.h>
alpar@1610
    32
#include <lemon/lp.h>
alpar@1361
    33
athos@1560
    34
#include <fstream>
athos@1560
    35
#include <iostream>
athos@1560
    36
alpar@1381
    37
alpar@1381
    38
alpar@1361
    39
using namespace lemon;
alpar@1361
    40
alpar@1361
    41
template<class G,class C>
alpar@1361
    42
double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t)
alpar@1361
    43
{
alpar@1610
    44
  Lp lp;
alpar@1361
    45
  
alpar@1361
    46
  typedef G Graph;
alpar@1361
    47
  typedef typename G::Node Node;
alpar@1361
    48
  typedef typename G::NodeIt NodeIt;
alpar@1361
    49
  typedef typename G::Edge Edge;
alpar@1361
    50
  typedef typename G::EdgeIt EdgeIt;
alpar@1361
    51
  typedef typename G::OutEdgeIt OutEdgeIt;
alpar@1361
    52
  typedef typename G::InEdgeIt InEdgeIt;
alpar@1361
    53
  
athos@1518
    54
  //Define a map on the edges for the variables of the LP problem
alpar@1610
    55
  typename G::template EdgeMap<Lp::Col> x(g);
alpar@1361
    56
  lp.addColSet(x);
alpar@1361
    57
  
athos@1518
    58
  //Nonnegativity and capacity constraints
alpar@1361
    59
  for(EdgeIt e(g);e!=INVALID;++e) {
alpar@1361
    60
    lp.colUpperBound(x[e],cap[e]);
alpar@1361
    61
    lp.colLowerBound(x[e],0);
alpar@1361
    62
  }
alpar@1361
    63
athos@1518
    64
athos@1518
    65
  //Flow conservation constraints for the nodes (except for 's' and 't')
alpar@1361
    66
  for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
alpar@1610
    67
    Lp::Expr ex;
alpar@1361
    68
    for(InEdgeIt  e(g,n);e!=INVALID;++e) ex+=x[e];
alpar@1361
    69
    for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
alpar@1361
    70
    lp.addRow(ex==0);
alpar@1361
    71
  }
athos@1518
    72
  
athos@1518
    73
  //Objective function: the flow value entering 't'
alpar@1610
    74
  Lp::Expr obj;
alpar@1571
    75
  for(InEdgeIt  e(g,t);e!=INVALID;++e) obj+=x[e];
alpar@1571
    76
  for(OutEdgeIt e(g,t);e!=INVALID;++e) obj-=x[e];
alpar@1571
    77
  lp.setObj(obj);
alpar@1571
    78
athos@1518
    79
athos@1518
    80
  //Maximization
alpar@1361
    81
  lp.max();
alpar@1361
    82
alpar@1610
    83
#if DEFAULT_LP==GLPK
alpar@1361
    84
  lp.presolver(true);
alpar@1361
    85
  lp.messageLevel(3);
alpar@1381
    86
#endif
alpar@1361
    87
athos@1577
    88
  std::cout<<"Solver used: "<<default_solver_name<<std::endl;
athos@1577
    89
athos@1518
    90
  //Solve with the underlying solver
alpar@1361
    91
  lp.solve();
alpar@1361
    92
alpar@1361
    93
  return lp.primalValue();
alpar@1361
    94
}
alpar@1361
    95
athos@1560
    96
int main(int argc, char *argv[]) 
alpar@1361
    97
{
athos@1560
    98
  if(argc<2)
athos@1560
    99
  {
athos@1577
   100
      std::cerr << "  USAGE: lp_maxflow_demo input_file.lgf" << std::endl;
alpar@1561
   101
      std::cerr << "  The file 'input_file.lgf' has to contain a max "
alpar@1561
   102
		<< "flow instance in\n"
alpar@1561
   103
		<< "  LEMON format (e.g. sample.lgf is such a file)."
alpar@1561
   104
		<< std::endl;
athos@1560
   105
      return 0;
athos@1560
   106
  }
athos@1560
   107
athos@1560
   108
athos@1560
   109
  //input stream to read the graph from
athos@1560
   110
  std::ifstream is(argv[1]);
athos@1560
   111
athos@1560
   112
alpar@1361
   113
  ListGraph g;
alpar@1361
   114
  ListGraph::Node s;
alpar@1361
   115
  ListGraph::Node t;
alpar@1361
   116
  
alpar@1361
   117
  ListGraph::EdgeMap<double> cap(g);
alpar@1361
   118
  
athos@1560
   119
  GraphReader<ListGraph> reader(is,g);
deba@1394
   120
  reader.readNode("source",s).readNode("target",t)
deba@1394
   121
    .readEdgeMap("capacity",cap).run();
alpar@1361
   122
  
alpar@1361
   123
  std::cout << "Max flow value = " << maxFlow(g,cap,s,t) << std::endl;
alpar@1361
   124
alpar@1361
   125
}