//================================================================================================== // G r a p h _ p r o b l e m Interface // M i n _ c o s t _ t e n s i o n // C o n f o r m i n g // 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 implements an algorithm we call "conforming" (or "out-of-kilter") to solve the minimum cost tension problem in graphs. Several versions of this algorithm are provided for linear, piecewise linear and convex costs. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/min_cost_tension/conforming.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guGraphProblemMinCostTensionConforming #define guGraphProblemMinCostTensionConforming
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_tension/algorithm.hpp> /*INCLUDE*/ #include <bpp/graph_problem/tension.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef GRAPH_PROBLEM_MIN_COST_TENSION_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostTensionConforming #define private_area graphProblemMinCostTensionConforming_private
namespace public_area { /*NAMESPACE*/ using namespace graphProblemMinCostTensionAlgorithm; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniGraphProblemMinCostTensionConforming has_initializer;
// Macrocommands //--------------------------------------------------------------------------------- /*ALIAS*/ #define tdGraph class prArcData,class prNodeData //
/*ALIAS*/ #define tuGraph prArcData,prNodeData //
// Types & Classes //------------------------------------------------------------------------------- namespace public_area {}
namespace private_area { template <tdGraph,class prConformity> class clDirectMintyColor; template <tdGraph,class prConformity> class clInverseMintyColor; }
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { template <tdGraph> void increaseFlow(clGraph<tuGraph> &,ctCycle &,tyReal); template <tdGraph> void increaseFlow(const std_map(clArc<tuGraph> *,tyInteger) &,tyReal); template <tdGraph> void nullFlow(clGraph<tuGraph> &); }
namespace private_area { template <tdGraph,class prConformity> tyInteger conformArc(clArc<tuGraph> &,const prConformity &);
template <tdGraph,class prConformity> void improveArc(clArc<tuGraph> &,const clDirectMintyColor<tuGraph,prConformity> &, const clInverseMintyColor<tuGraph,prConformity> &,const prConformity &);
template <tdGraph,class prConformity> tyReal maximumDecreaseFlow(const std_map(clArc<tuGraph> *,tyInteger) &,const prConformity &);
template <tdGraph,class prConformity> tyReal maximumIncreaseFlow(const std_map(clArc<tuGraph> *,tyInteger) &,const prConformity &);
template <tdGraph,class prConformity> tyReal maximumDecreaseTension(const std_map(clArc<tuGraph> *,tyInteger) &,const prConformity &);
template <tdGraph,class prConformity> tyReal maximumIncreaseTension(const std_map(clArc<tuGraph> *,tyInteger) &,const prConformity &);
function clOutStream & operator << (clOutStream &,tyMintyColor);
testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area { /*ERROR*/ extern_error erMaximumDecreaseFlow; /* The maximum decrease flow is negative, zero or infinite in the "conforming" algorithm. */
/*ERROR*/ extern_error erMaximumIncreaseFlow; /* The maximum increase flow is negative, zero or infinite in the "conforming" algorithm. */
/*ERROR*/ extern_error erMaximumDecreaseTension; /* The maximum decrease tension is negative, zero or infinite in the "conforming" algorithm. */
/*ERROR*/ extern_error erMaximumIncreaseTension; /* The maximum increase tension is negative, zero or infinite in the "conforming" algorithm. */ }
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// D i r e c t M i n t y C o l o r Interface //---------------------------------------------------- namespace private_area { template <tdGraph,class prConformity> class clDirectMintyColor { //-------------------------------------------------------------------------------------------Types public_property typedef clArc<tuGraph> cpArc; //-----------------------------------------------------------------------------------------Private private_property constructor clDirectMintyColor(const clDirectMintyColor &); private_property clDirectMintyColor & operator = (const clDirectMintyColor &);
private_property const prConformity & atConformity; //------------------------------------------------------------------------------------------Public public_property constructor clDirectMintyColor(const prConformity &); public_property destructor clDirectMintyColor(void) {}
public_property tyBoolean red(const cpArc &) const; public_property tyBoolean black(const cpArc &) const; public_property tyBoolean blue(const cpArc &) const; public_property tyBoolean green(const cpArc &) const; }; }
// I n v e r s e M i n t y C o l o r Interface //-------------------------------------------------- namespace private_area { template <tdGraph,class prConformity> class clInverseMintyColor { //-------------------------------------------------------------------------------------------Types public_property typedef clArc<tuGraph> cpArc; //-----------------------------------------------------------------------------------------Private private_property constructor clInverseMintyColor(const clInverseMintyColor &); private_property clInverseMintyColor & operator = (const clInverseMintyColor &);
private_property const prConformity & atConformity; //------------------------------------------------------------------------------------------Public public_property constructor clInverseMintyColor(const prConformity &); public_property destructor clInverseMintyColor(void) {}
public_property tyBoolean red(const cpArc &) const; public_property tyBoolean black(const cpArc &) const; public_property tyBoolean blue(const cpArc &) const; public_property tyBoolean green(const cpArc &) const; }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// D i r e c t M i n t y C o l o r Inline //------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor template <tdGraph,class prConformity> inline clDirectMintyColor<tuGraph,prConformity>:: clDirectMintyColor(const prConformity & agConformity) : atConformity(agConformity) {} //----------------------------------------------------------------------------------------------Red template <tdGraph,class prConformity> inline tyBoolean clDirectMintyColor<tuGraph,prConformity>::red(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::red); } //--------------------------------------------------------------------------------------------Black template <tdGraph,class prConformity> inline tyBoolean clDirectMintyColor<tuGraph,prConformity>::black(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::black); } //---------------------------------------------------------------------------------------------Blue template <tdGraph,class prConformity> inline tyBoolean clDirectMintyColor<tuGraph,prConformity>::blue(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::blue); } //--------------------------------------------------------------------------------------------Green template <tdGraph,class prConformity> inline tyBoolean clDirectMintyColor<tuGraph,prConformity>::green(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::green); } }
// I n v e r s e M i n t y C o l o r Inline //----------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor template <tdGraph,class prConformity> inline clInverseMintyColor<tuGraph,prConformity>:: clInverseMintyColor(const prConformity & agConformity) : atConformity(agConformity) {} //----------------------------------------------------------------------------------------------Red template <tdGraph,class prConformity> inline tyBoolean clInverseMintyColor<tuGraph,prConformity>::red(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::red); } //--------------------------------------------------------------------------------------------Black template <tdGraph,class prConformity> inline tyBoolean clInverseMintyColor<tuGraph,prConformity>::black(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::blue); } //---------------------------------------------------------------------------------------------Blue template <tdGraph,class prConformity> inline tyBoolean clInverseMintyColor<tuGraph,prConformity>::blue(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::black); } //--------------------------------------------------------------------------------------------Green template <tdGraph,class prConformity> inline tyBoolean clInverseMintyColor<tuGraph,prConformity>::green(const cpArc & agArc) const { return (atConformity.arcColor(agArc)==private_area::green); } }
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //-------------------------------------------------------------------------------------IncreaseFlow /*FUNCTION*/ /* Increases the flow in a cycle. */ template <tdGraph> void increaseFlow(clGraph<tuGraph> & agGraph,ctCycle & agCycle,tyReal agValue) { clCycle::const_iterator lcCurrentArc = agCycle.begin(); clCycle::const_iterator lcLastArc = agCycle.end();
while (lcCurrentArc!=lcLastArc) { if ((*lcCurrentArc).second==+1) agGraph.arc((*lcCurrentArc).first).data().flow()+=agValue; else agGraph.arc((*lcCurrentArc).first).data().flow()-=agValue;
lcCurrentArc++; } } //-------------------------------------------------------------------------------------IncreaseFlow /*FUNCTION*/ /* Increases the flow in a cycle. */ template <tdGraph> void increaseFlow(const std_map(clArc<tuGraph> *,tyInteger) & agCycle,tyReal agValue) { typedef typename std_map(clArc<tuGraph> *,tyInteger)::const_iterator cpIterator;
cpIterator lcCurrentArc = agCycle.begin(); cpIterator lcLastArc = agCycle.end();
while (lcCurrentArc!=lcLastArc) { if ((*lcCurrentArc).second==+1) (*lcCurrentArc).first->data().flow()+=agValue; else (*lcCurrentArc).first->data().flow()-=agValue;
lcCurrentArc++; } } //-----------------------------------------------------------------------------------------NullFlow /*FUNCTION*/ /* Nulls the flow of a graph. */ template <tdGraph> void nullFlow(clGraph<tuGraph> & agGraph) { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpIterator;
cpIterator lcCurrentArc = agGraph.arcs().begin(); cpIterator lcLastArc = agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { (*lcCurrentArc).second->data().flow()=0; lcCurrentArc++; } } }
namespace private_area { //---------------------------------------------------------------------------------------ConformArc template <tdGraph,class prConformity> tyInteger conformArc(clArc<tuGraph> & agArc,const prConformity & agConformity) { clDirectMintyColor<tuGraph,prConformity> lcDirectMintyColor(agConformity); clInverseMintyColor<tuGraph,prConformity> lcInverseMintyColor(agConformity);
tyInteger lcIteration = 0;
while (not agConformity.conformedArc(agArc)) { lcIteration++; improveArc(agArc,lcDirectMintyColor,lcInverseMintyColor,agConformity); }
return (lcIteration); } //---------------------------------------------------------------------------------------ImproveArc template <tdGraph,class prConformity> void improveArc(clArc<tuGraph> & agArc, const clDirectMintyColor<tuGraph,prConformity> & agDirectMintyColor, const clInverseMintyColor<tuGraph,prConformity> & agInverseMintyColor, const prConformity & agConformity) { method_name("improveArc");
std_map(clArc<tuGraph> *,tyInteger) lcCocycle; std_map(clArc<tuGraph> *,tyInteger) lcCycle; tyReal lcMaximum;
if (agConformity.arcColor(agArc)==black) { if (findMintyCycle<tuGraph,clDirectMintyColor<tuGraph,prConformity> > (agArc,agDirectMintyColor,lcCycle,lcCocycle)) { lcMaximum=maximumDecreaseFlow(lcCycle,agConformity); if (lcMaximum<=0.0 or lcMaximum==realMax()) send_error(erMaximumDecreaseFlow); increaseFlow(lcCycle,-lcMaximum); } else { lcMaximum=maximumIncreaseTension(lcCocycle,agConformity); if (lcMaximum<=0.0 or lcMaximum==realMax()) send_error(erMaximumIncreaseTension); graphProblemTension::increaseTension(lcCocycle,lcMaximum); } } else { if(findMintyCycle<tuGraph,clInverseMintyColor<tuGraph,prConformity> > (agArc,agInverseMintyColor,lcCycle,lcCocycle)) { lcMaximum=maximumIncreaseFlow(lcCycle,agConformity); if (lcMaximum<=0.0 or lcMaximum==realMax()) send_error(erMaximumIncreaseFlow); increaseFlow(lcCycle,lcMaximum); } else { lcMaximum=maximumDecreaseTension(lcCocycle,agConformity); if (lcMaximum<=0.0 or lcMaximum==realMax()) send_error(erMaximumDecreaseTension); graphProblemTension::increaseTension(lcCocycle,-lcMaximum); } } } //------------------------------------------------------------------------------MaximumDecreaseFlow template <tdGraph,class prConformity> tyReal maximumDecreaseFlow(const std_map(clArc<tuGraph> *,tyInteger) & agCycle, const prConformity & agConformity) { typedef typename std_map(clArc<tuGraph> *,tyInteger)::const_iterator cpIterator;
cpIterator lcCurrentArc = agCycle.begin(); cpIterator lcLastArc = agCycle.end();
const clArc<tuGraph> * lcArc;
tyReal lcMaximum = realMax();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).first;
if ((*lcCurrentArc).second==+1) lcMaximum=mini(lcMaximum,agConformity.maximumDecreaseFlow(*lcArc)); else lcMaximum=mini(lcMaximum,agConformity.maximumIncreaseFlow(*lcArc));
lcCurrentArc++; }
return (lcMaximum); } //------------------------------------------------------------------------------MaximumIncreaseFlow template <tdGraph,class prConformity> tyReal maximumIncreaseFlow(const std_map(clArc<tuGraph> *,tyInteger) & agCycle, const prConformity & agConformity) { typedef typename std_map(clArc<tuGraph> *,tyInteger)::const_iterator cpIterator;
cpIterator lcCurrentArc = agCycle.begin(); cpIterator lcLastArc = agCycle.end();
const clArc<tuGraph> * lcArc;
tyReal lcMaximum = realMax();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).first;
if ((*lcCurrentArc).second==+1) lcMaximum=mini(lcMaximum,agConformity.maximumIncreaseFlow(*lcArc)); else lcMaximum=mini(lcMaximum,agConformity.maximumDecreaseFlow(*lcArc));
lcCurrentArc++; }
return (lcMaximum); } //---------------------------------------------------------------------------MaximumDecreaseTension template <tdGraph,class prConformity> tyReal maximumDecreaseTension(const std_map(clArc<tuGraph> *,tyInteger) & agCocycle, const prConformity & agConformity) { typedef typename std_map(clArc<tuGraph> *,tyInteger)::const_iterator cpIterator;
cpIterator lcCurrentArc = agCocycle.begin(); cpIterator lcLastArc = agCocycle.end();
const clArc<tuGraph> * lcArc;
tyReal lcMaximum = realMax();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).first;
if ((*lcCurrentArc).second==+1) lcMaximum=mini(lcMaximum,agConformity.maximumDecreaseTension(*lcArc)); else lcMaximum=mini(lcMaximum,agConformity.maximumIncreaseTension(*lcArc));
lcCurrentArc++; }
return (lcMaximum); } //---------------------------------------------------------------------------MaximumIncreaseTension template <tdGraph,class prConformity> tyReal maximumIncreaseTension(const std_map(clArc<tuGraph> *,tyInteger) & agCocycle, const prConformity & agConformity) { typedef typename std_map(clArc<tuGraph> *,tyInteger)::const_iterator cpIterator;
cpIterator lcCurrentArc = agCocycle.begin(); cpIterator lcLastArc = agCocycle.end();
const clArc<tuGraph> * lcArc;
tyReal lcMaximum = realMax();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).first;
if ((*lcCurrentArc).second==+1) lcMaximum=mini(lcMaximum,agConformity.maximumIncreaseTension(*lcArc)); else lcMaximum=mini(lcMaximum,agConformity.maximumDecreaseTension(*lcArc));
lcCurrentArc++; }
return (lcMaximum); } }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef tdGraph #undef tuGraph #undef public_area #undef private_area #endif |
//================================================================================================== // G r a p h _ p r o b l e m Implementation // M i n _ c o s t _ t e n s i o n // C o n f o r m i n g // 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_tension/conforming.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define GRAPH_PROBLEM_MIN_COST_TENSION_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_tension/conforming.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostTensionConforming #define private_area graphProblemMinCostTensionConforming_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Graph_problem/Min_cost_tension/Conforming");
// Initialization //-------------------------------------------------------------------------------- #undef iniGraphProblemMinCostTensionConforming static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area { static_error erMaximumDecreaseFlow; static_error erMaximumIncreaseFlow; static_error erMaximumDecreaseTension; static_error erMaximumIncreaseTension; }
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area {}
namespace private_area { //------------------------------------------------------------------------Operator << (Minty Color) function clOutStream & operator << (clOutStream & agStream,tyMintyColor agColor) { if (agColor==green) agStream << "Green"; else if (agColor==black) agStream << "Black"; else if (agColor==blue) agStream << "Blue"; else agStream << "Red";
return (agStream); } }
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
erMaximumDecreaseFlow.create("Min Cost Tension - The decrease flow is not valid."); erMaximumIncreaseFlow.create("Min Cost Tension - The increase flow is not valid."); erMaximumDecreaseTension.create("Min Cost Tension - The decrease tension is not valid."); erMaximumIncreaseTension.create("Min Cost Tension - The increase tension is not valid."); }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { environment::informTermination(goModuleName); } }
// End //------------------------------------------------------------------------------------------- } |
|