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