//================================================================================================== // G r a p h _ p r o b l e m Interface // M i n _ c o s t _ f l o w // L i n e a r _ s y s t e m // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides facilities to solve the minimum cost flow problem (with linear costs) in graphs using linear program modeling. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/min_cost_flow/linear_system.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guGraphProblemMinCostFlowLinearSystem #define guGraphProblemMinCostFlowLinearSystem
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_flow/algorithm.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef GRAPH_PROBLEM_MIN_COST_FLOW_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostFlowLinearSystem #define private_area graphProblemMinCostFlowLinearSystem_private
namespace public_area { /*NAMESPACE*/ using namespace graphProblemMinCostFlowAlgorithm; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //--------------------------------------------------------------------------------
// Macrocommands //--------------------------------------------------------------------------------- /*ALIAS*/ #define tdGraph class prArcData,class prNodeData //
/*ALIAS*/ #define tuGraph prArcData,prNodeData //
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------------Classes template <tdGraph> class clSolveAlgo; }
namespace private_area {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area {} namespace private_area { testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// S o l v e A l g o Interface //------------------------------------------------------------------ namespace public_area { /*CLASS clSolveAlgo */ /* Represents a linear program solver for the minimum cost flow problem in a graph. */ template <tdGraph> class clSolveAlgo : public clSolver<tuGraph> { //-------------------------------------------------------------------------------------------Types /*TYPE clSolveAlgo */ /* Type of the linear program solver used to solve the problem. */ public_property typedef linearSystemSolver::clSolver<public_area::clVariableContent> clLinearSolver; //-----------------------------------------------------------------------------------------Private private_property constructor clSolveAlgo(const clSolveAlgo &); private_property clSolveAlgo & operator = (const clSolveAlgo &); //------------------------------------------------------------------------------------------Public public_property constructor clSolveAlgo(void); public_property virtual destructor clSolveAlgo(void);
public_property void buildLinearSystem(clFlowSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,const clLinearSolver &) const; public_property tyInteger run(clGraph<tuGraph> &) const; }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// S o l v e A l g o Inline //--------------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clSolveAlgo */ /* Builds a linear program solver for the minimum cost flow problem in a graph. */ template <tdGraph> inline clSolveAlgo<tuGraph>::clSolveAlgo(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clSolveAlgo */ /* Destructs the algorithm. */ template <tdGraph> inline clSolveAlgo<tuGraph>::~clSolveAlgo(void) {} //----------------------------------------------------------------------------------------------Run /*METHOD clSolveAlgo */ /* Solves the minimum cost flow problem using the default linear program solver. */ template <tdGraph> inline tyInteger clSolveAlgo<tuGraph>::run(clGraph<tuGraph> & agGraph) const { return (run(agGraph,clLinearSolver::defaultSolver())); } }
// S o l v e A l g o Implementation //------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clSolveAlgo */ /* Builds a linear program equivalent to the minimum cost flow problem of a graph. */ template <tdGraph> void clSolveAlgo<tuGraph>::buildLinearSystem(clFlowSystem & agSystem, clGraph<tuGraph> & agGraph) const { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator1; typedef typename clNode<tuGraph>::cpArcX::const_iterator cpArcIterator2; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;
typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation; typedef linearSystem::tyVariableKey tyKey;
tyKey lcCounter = 0; cpArcIterator1 lcCurrentArc1 = agGraph.arcs().begin(); cpNodeIterator lcCurrentNode = agGraph.nodes().begin(); cpArcIterator1 lcLastArc1 = agGraph.arcs().end(); cpNodeIterator lcLastNode = agGraph.nodes().end();
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clFlowConstraint * lcConstraint; cpArcIterator2 lcCurrentArc2; tyKey lcKey; cpArcIterator2 lcLastArc2; clFlowVariable * lcVariable1; clFlowVariable * lcVariable2;
// Capacity Constraints & Objective Function // while (lcCurrentArc1!=lcLastArc1) { lcArc=(*lcCurrentArc1).second;
lcVariable1=new_object(clFlowVariable(agSystem,lcCounter++, linearSystem::realVariable,lcArc->key()));
lcVariable2=new_object(clFlowVariable(agSystem,lcCounter++, linearSystem::realVariable,lcArc->key()));
lcAssociation.insert(std_make_pair(lcArc->key(),lcVariable1->key())); lcConstraint=new_object(clFlowConstraint(agSystem,linearSystem::superiority)); lcConstraint->setCoefficient(lcVariable1->key(),1.0); lcConstraint->setCoefficient(lcVariable2->key(),-1.0); lcConstraint->boundary()=lcArc->data().minimum(); lcConstraint=new_object(clFlowConstraint(agSystem,linearSystem::inferiority)); lcConstraint->setCoefficient(lcVariable1->key(),1.0); lcConstraint->setCoefficient(lcVariable2->key(),-1.0); lcConstraint->boundary()=lcArc->data().maximum(); agSystem.objective().setCoefficient(lcVariable1->key(),lcArc->data().unitCost()); agSystem.objective().setCoefficient(lcVariable2->key(),-lcArc->data().unitCost()); lcCurrentArc1++; }
new_object(clFlowVariable(agSystem,lcCounter,linearSystem::realVariable,nilArc())); new_object(clFlowVariable(agSystem,lcCounter+1,linearSystem::realVariable,nilArc())); agSystem.objective().kind()=linearSystem::minimum;
// Flow Constraints // while (lcCurrentNode!=lcLastNode) { lcConstraint=new_object(clFlowConstraint(agSystem,linearSystem::equality)); lcConstraint->boundary()=0.0;
lcCurrentArc2=(*lcCurrentNode).second->incomingArcs().begin(); lcLastArc2=(*lcCurrentNode).second->incomingArcs().end();
if (lcCurrentArc2==lcLastArc2) { lcConstraint->setCoefficient(lcCounter,1.0); lcConstraint->setCoefficient(lcCounter+1,-1.0); }
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second; lcKey=lcAssociation[lcArc->key()]; lcConstraint->setCoefficient(lcKey,1.0); lcConstraint->setCoefficient(lcKey+1,-1.0); lcCurrentArc2++; }
lcCurrentArc2=(*lcCurrentNode).second->outgoingArcs().begin(); lcLastArc2=(*lcCurrentNode).second->outgoingArcs().end();
if (lcCurrentArc2==lcLastArc2) { lcConstraint->setCoefficient(lcCounter,-1.0); lcConstraint->setCoefficient(lcCounter+1,1.0); }
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second; lcKey=lcAssociation[lcArc->key()]; lcConstraint->setCoefficient(lcKey,-1.0); lcConstraint->setCoefficient(lcKey+1,1.0); lcCurrentArc2++; }
lcCurrentNode++; } } //----------------------------------------------------------------------------------------------Run /*METHOD clSolveAlgo */ /* Solves the minimum cost flow problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clSolveAlgo<tuGraph>::run(clGraph<tuGraph> & agGraph, const clLinearSolver & agSolver) const { typename clGraph<tuGraph>::cpArc * lcArc; clFlowSystem::cpVariableX::const_iterator lcCurrentVariable; clFlowSystem::cpVariableX::const_iterator lcLastVariable; tyInteger lcNbIteration; clFlowSystem lcSystem; clFlowVariable * lcVariable1; clFlowVariable * lcVariable2;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (lcNbIteration);
// Connection With The Graph // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { lcVariable1=(*lcCurrentVariable).second; lcCurrentVariable++; lcVariable2=(*lcCurrentVariable).second;
if (lcVariable1->content().arc()!=nilArc()) { lcArc=&(agGraph.arc(lcVariable1->content().arc())); lcArc->data().flow()=lcVariable1->value()-lcVariable2->value(); }
lcCurrentVariable++; }
return (lcNbIteration); } }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #undef tdGraph #undef tuGraph #endif |
//================================================================================================== // G r a p h _ p r o b l e m Implementation // M i n _ c o s t _ f l o w // L i n e a r _ s y s t e m // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/min_cost_flow/linear_system.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define GRAPH_PROBLEM_MIN_COST_FLOW_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_flow/linear_system.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostFlowLinearSystem #define private_area graphProblemMinCostFlowLinearSystem_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Graph_problem/Min_cost_flow/Linear_system");
// Initialization //--------------------------------------------------------------------------------
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// X X X Implementation //------------------------------------------------------------------------- namespace {}
// End //------------------------------------------------------------------------------------------- } |
|