demo/lp_maxflow_demo.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Mon, 01 Mar 2010 02:27:36 +0100
changeset 55 edb7d5759e0d
permissions -rw-r--r--
Greatly extend LP section
kpeter@54
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@54
     2
 *
kpeter@54
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@54
     4
 *
kpeter@54
     5
 * Copyright (C) 2003-2010
kpeter@54
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@54
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@54
     8
 *
kpeter@54
     9
 * Permission to use, modify and distribute this software is granted
kpeter@54
    10
 * provided that this copyright notice appears in all copies. For
kpeter@54
    11
 * precise terms see the accompanying LICENSE file.
kpeter@54
    12
 *
kpeter@54
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@54
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@54
    15
 * purpose.
kpeter@54
    16
 *
kpeter@54
    17
 */
kpeter@54
    18
kpeter@54
    19
///\file
kpeter@54
    20
///\brief Demo program that solves maximum flow problems using the LP interface
kpeter@54
    21
///
kpeter@54
    22
/// This demo program shows how to solve the maximum flow problem using
kpeter@54
    23
/// the LEMON LP solver interface. We would like to lay the emphasis on the
kpeter@54
    24
/// simplicity of the way one can formulate LP constraints that arise in graph
kpeter@54
    25
/// theory using LEMON.
kpeter@54
    26
///
kpeter@54
    27
/// \include lp_maxflow_demo.cc
kpeter@54
    28
kpeter@54
    29
#include <iostream>
kpeter@54
    30
#include <lemon/smart_graph.h>
kpeter@54
    31
#include <lemon/lgf_reader.h>
kpeter@54
    32
#include <lemon/lp.h>
kpeter@54
    33
kpeter@54
    34
using namespace lemon;
kpeter@54
    35
kpeter@54
    36
template <typename GR, typename CAP>
kpeter@54
    37
double maxFlow(const GR &g, const CAP &capacity,
kpeter@54
    38
               typename GR::Node source, typename GR::Node target)
kpeter@54
    39
{
kpeter@54
    40
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
kpeter@54
    41
  
kpeter@54
    42
  // Create an instance of the default LP solver
kpeter@54
    43
  Lp lp;
kpeter@54
    44
kpeter@54
    45
  // Add a column to the problem for each arc
kpeter@54
    46
  typename GR::template ArcMap<Lp::Col> f(g);
kpeter@54
    47
  lp.addColSet(f);
kpeter@54
    48
kpeter@54
    49
  // Capacity constraints
kpeter@54
    50
  for (ArcIt a(g); a != INVALID; ++a) {
kpeter@54
    51
    lp.colLowerBound(f[a], 0);
kpeter@54
    52
    lp.colUpperBound(f[a], capacity[a]);
kpeter@54
    53
  }
kpeter@54
    54
kpeter@54
    55
  // Flow conservation constraints
kpeter@54
    56
  for (NodeIt n(g); n != INVALID; ++n) {
kpeter@54
    57
    if (n == source || n == target) continue;
kpeter@54
    58
    Lp::Expr e;
kpeter@54
    59
    for (OutArcIt a(g, n); a != INVALID; ++a) e += f[a];
kpeter@54
    60
    for (InArcIt a(g, n); a != INVALID; ++a) e -= f[a];
kpeter@54
    61
    lp.addRow(e == 0);
kpeter@54
    62
  }
kpeter@54
    63
kpeter@54
    64
  // Objective function
kpeter@54
    65
  Lp::Expr o;
kpeter@54
    66
  for (OutArcIt a(g, source); a != INVALID; ++a) o += f[a];
kpeter@54
    67
  for (InArcIt a(g, source); a != INVALID; ++a) o -= f[a];
kpeter@54
    68
  lp.max();
kpeter@54
    69
  lp.obj(o);
kpeter@54
    70
kpeter@54
    71
  // Solve the LP problem
kpeter@54
    72
  lp.solve();
kpeter@54
    73
kpeter@54
    74
  return lp.primal();
kpeter@54
    75
}
kpeter@54
    76
kpeter@54
    77
kpeter@54
    78
int main(int argc, char *argv[])
kpeter@54
    79
{
kpeter@54
    80
  // Check the arguments
kpeter@54
    81
  if (argc < 2) {
kpeter@54
    82
    std::cerr << "Usage:" << std::endl;
kpeter@54
    83
    std::cerr << "  lp_maxflow_demo <input_file>" << std::endl;
kpeter@54
    84
    std::cerr << "The given input file has to contain a maximum flow\n"
kpeter@54
    85
              << "problem in LGF format (like 'maxflow.lgf')."
kpeter@54
    86
              << std::endl;
kpeter@54
    87
    return 0;
kpeter@54
    88
  }
kpeter@54
    89
  
kpeter@54
    90
  // Read the input file
kpeter@54
    91
  SmartDigraph g;
kpeter@54
    92
  SmartDigraph::ArcMap<double> cap(g);
kpeter@54
    93
  SmartDigraph::Node s, t;
kpeter@54
    94
kpeter@54
    95
  digraphReader(g, argv[1])
kpeter@54
    96
    .arcMap("capacity", cap)
kpeter@54
    97
    .node("source", s)
kpeter@54
    98
    .node("target", t)
kpeter@54
    99
    .run();
kpeter@54
   100
kpeter@54
   101
  // Solve the problem and print the result
kpeter@54
   102
  std::cout << "Max flow value: " << maxFlow(g, cap, s, t) << std::endl;
kpeter@54
   103
 
kpeter@54
   104
  return 0;
kpeter@54
   105
}