//================================================================================================== // 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 // 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 tension problem in graphs using linear program modeling. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/min_cost_tension/linear_system.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guGraphProblemMinCostTensionLinearSystem #define guGraphProblemMinCostTensionLinearSystem
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_tension/algorithm.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 graphProblemMinCostTensionLinearSystem #define private_area graphProblemMinCostTensionLinearSystem_private
namespace public_area { /*NAMESPACE*/ using namespace graphProblemMinCostTensionAlgorithm; } 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 clBinarySolveAlgo; template <tdGraph> class clBinarySolveAlgoI; template <tdGraph> class clBinarySolveAlgoII;
template <tdGraph> class clDiscreteSolveAlgo; template <tdGraph> class clDiscreteSolveAlgoI; template <tdGraph> class clDiscreteSolveAlgoII;
template <tdGraph> class clLinearSolveAlgo; template <tdGraph> class clLinearSolveAlgoI; template <tdGraph> class clLinearSolveAlgoII; template <tdGraph> class clLinearSolveAlgoIII; }
namespace private_area {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area {}
namespace private_area { template <tdGraph> void findCycles(clGraph<tuGraph> &,clCycleS &,tyBoolean); testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// B i n a r y S o l v e A l g o Interface //------------------------------------------------------ namespace public_area { /*CLASS clBinarySolveAlgo */ /* Represents an algorithm to solve the minimum binary cost tension problem in a graph using a linear program modeling. It is an abstract class. The cost functions of the arcs in the graph must be binary as defined by the <CODE>clBinaryArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> class clBinarySolveAlgo { //-----------------------------------------------------------------------------------------Private private_property constructor clBinarySolveAlgo(const clBinarySolveAlgo &); private_property clBinarySolveAlgo & operator = (const clBinarySolveAlgo &); //------------------------------------------------------------------------------------------Public public_property constructor clBinarySolveAlgo(void); public_property virtual destructor clBinarySolveAlgo(void);
/*AMETHOD clBinarySolveAlgo */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. Abstract method. */ public_property virtual void buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const = 0;
/*AMETHOD clBinarySolveAlgo */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. Abstract method. */ public_property virtual tyInteger run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const = 0;
public_property tyInteger run(clGraph<tuGraph> &) const; public_property static tyInteger defaultRun(clGraph<tuGraph> &);
public_property void buildLinearRelaxation(clTensionSystem &,clGraph<tuGraph> &) const;
public_property tyInteger solveLinearRelaxation(clGraph<tuGraph> &,ctTensionSystemSolver &,tyReal &) const;
/*AMETHOD clBinarySolveAlgo */ /* Builds a Lagrangean relaxation of the linear program equivalent to the minimum binary cost tension problem of a graph. Lagrangean coefficients for the relaxed constraints must be given. Abstract method. */ public_property virtual void buildLagrangeanRelaxation(clTensionSystem & agSystem,clGraph<tuGraph> & agGraph, std_map(clArc<tuGraph> *,tyPairReal) & agCoefficientX) const = 0;
public_property tyInteger solveLagrangeanRelaxation(clGraph<tuGraph> &,ctTensionSystemSolver &, tyCardinal,tyReal &) const;
public_property tyInteger solveLagrangeanRelaxation(clGraph<tuGraph> &, ctTensionSystemSolver &,tyCardinal, tyCardinal,tyReal &,tyReal &, std_map(clArc<tuGraph> *,tyPairReal) &) const; }; }
// D i s c r e t e S o l v e A l g o Interface //-------------------------------------------------- namespace public_area { /*CLASS clDiscreteSolveAlgo */ /* Represents an algorithm to solve the minimum cost discrete tension problem in a graph using a linear program modeling. It is an abstract class. The cost functions of the arcs in the graph must be linear as defined by the <CODE>clDiscreteArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> class clDiscreteSolveAlgo { //-----------------------------------------------------------------------------------------Private private_property constructor clDiscreteSolveAlgo(const clDiscreteSolveAlgo &); private_property clDiscreteSolveAlgo & operator = (const clDiscreteSolveAlgo &); //------------------------------------------------------------------------------------------Public public_property constructor clDiscreteSolveAlgo(void); public_property virtual destructor clDiscreteSolveAlgo(void);
/*AMETHOD clDiscreteSolveAlgo */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. Abstract method. */ public_property virtual void buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const = 0;
/*AMETHOD clDiscreteSolveAlgo */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. Abstract method. */ public_property virtual tyInteger run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const = 0;
public_property tyInteger run(clGraph<tuGraph> &) const; public_property static tyInteger defaultRun(clGraph<tuGraph> &); }; }
// L i n e a r S o l v e A l g o Interface //------------------------------------------------------ namespace public_area { /*CLASS clLinearSolveAlgo */ /* Represents an algorithm to solve the minimum linear cost tension problem in a graph using a linear program modeling. It is an abstract class. The cost functions of the arcs in the graph must be linear as defined by the <CODE>clLinearArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> class clLinearSolveAlgo { //-----------------------------------------------------------------------------------------Private private_property constructor clLinearSolveAlgo(const clLinearSolveAlgo &); private_property clLinearSolveAlgo & operator = (const clLinearSolveAlgo &); //------------------------------------------------------------------------------------------Public public_property constructor clLinearSolveAlgo(void); public_property virtual destructor clLinearSolveAlgo(void);
/*AMETHOD clLinearSolveAlgo */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. Abstract method. */ public_property virtual void buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const = 0;
/*AMETHOD clLinearSolveAlgo */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. Abstract method. */ public_property virtual tyInteger run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const = 0;
public_property tyInteger run(clGraph<tuGraph> &) const; public_property static tyInteger defaultRun(clGraph<tuGraph> &); }; }
// B i n a r y S o l v e A l g o I Interface //---------------------------------------------------- namespace public_area { /*CLASS clBinarySolveAlgoI */ /* Represents an algorithm to solve the minimum cost tension problem with binary costs in a graph using the linear program modeling I (using a cycle base). */ template <tdGraph> class clBinarySolveAlgoI : public clBinarySolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clBinarySolveAlgoI(const clBinarySolveAlgoI &); private_property clBinarySolveAlgoI & operator = (const clBinarySolveAlgoI &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clBinarySolveAlgoI */ /* Indicates if short cycles must be used for the base. */ read_only_attribute(tyBoolean,atShortCycles,shortCycles);
public_property constructor clBinarySolveAlgoI(tyBoolean=true); public_property destructor clBinarySolveAlgoI(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const;
public_property void buildLagrangeanRelaxation(clTensionSystem &,clGraph<tuGraph> &, std_map(clArc<tuGraph> *,tyPairReal) &) const; }; }
// D i s c r e t e S o l v e A l g o I Interface //------------------------------------------------ namespace public_area { /*CLASS clDiscreteSolveAlgoI */ /* Represents an algorithm to solve the minimum cost discrete tension problem in a graph using the linear program modeling I (using a cycle base). */ template <tdGraph> class clDiscreteSolveAlgoI : public clDiscreteSolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clDiscreteSolveAlgoI(const clDiscreteSolveAlgoI &); private_property clDiscreteSolveAlgoI & operator = (const clDiscreteSolveAlgoI &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clDiscreteSolveAlgoI */ /* Indicates if short cycles must be used for the base. */ read_only_attribute(tyBoolean,atShortCycles,shortCycles);
public_property constructor clDiscreteSolveAlgoI(tyBoolean=true); public_property destructor clDiscreteSolveAlgoI(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const; }; }
// L i n e a r S o l v e A l g o I Interface //---------------------------------------------------- namespace public_area { /*CLASS clLinearSolveAlgoI */ /* Represents an algorithm to solve the minimum cost tension problem with linear costs in a graph using the linear program modeling I (using a cycle base). */ template <tdGraph> class clLinearSolveAlgoI : public clLinearSolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clLinearSolveAlgoI(const clLinearSolveAlgoI &); private_property clLinearSolveAlgoI & operator = (const clLinearSolveAlgoI &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clLinearSolveAlgoI */ /* Indicates if short cycles must be used for the base. */ read_only_attribute(tyBoolean,atShortCycles,shortCycles);
public_property constructor clLinearSolveAlgoI(tyBoolean=true); public_property destructor clLinearSolveAlgoI(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const; }; }
// B i n a r y S o l v e A l g o I I Interface //-------------------------------------------------- namespace public_area { /*CLASS clBinarySolveAlgoII */ /* Represents an algorithm to solve the minimum cost tension problem with binary costs in a graph using the linear program modeling II (using the incidence matrix). */ template <tdGraph> class clBinarySolveAlgoII : public clBinarySolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clBinarySolveAlgoII(const clBinarySolveAlgoII &); private_property clBinarySolveAlgoII & operator = (const clBinarySolveAlgoII &); //------------------------------------------------------------------------------------------Public public_property constructor clBinarySolveAlgoII(void); public_property destructor clBinarySolveAlgoII(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const;
public_property void buildLagrangeanRelaxation(clTensionSystem &,clGraph<tuGraph> &, std_map(clArc<tuGraph> *,tyPairReal) &) const; }; }
// D i s c r e t e S o l v e A l g o I I Interface //---------------------------------------------- namespace public_area { /*CLASS clDiscreteSolveAlgoII */ /* Represents an algorithm to solve the minimum cost discrete tension problem in a graph using the linear program modeling II (using the incidence matrix). */ template <tdGraph> class clDiscreteSolveAlgoII : public clDiscreteSolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clDiscreteSolveAlgoII(const clDiscreteSolveAlgoII &); private_property clDiscreteSolveAlgoII & operator = (const clDiscreteSolveAlgoII &); //------------------------------------------------------------------------------------------Public public_property constructor clDiscreteSolveAlgoII(void); public_property destructor clDiscreteSolveAlgoII(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const; }; }
// L i n e a r S o l v e A l g o I I Interface //-------------------------------------------------- namespace public_area { /*CLASS clLinearSolveAlgoII */ /* Represents an algorithm to solve the minimum cost tension problem with linear costs in a graph using the linear program modeling II (using a cycle base). */ template <tdGraph> class clLinearSolveAlgoII : public clLinearSolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clLinearSolveAlgoII(const clLinearSolveAlgoII &); private_property clLinearSolveAlgoII & operator = (const clLinearSolveAlgoII &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clLinearSolveAlgoII */ /* Indicates if short cycles must be used for the base. */ read_only_attribute(tyBoolean,atShortCycles,shortCycles);
public_property constructor clLinearSolveAlgoII(tyBoolean=true); public_property destructor clLinearSolveAlgoII(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const; }; }
// L i n e a r S o l v e A l g o I I I Interface //------------------------------------------------ namespace public_area { /*CLASS clLinearSolveAlgoIII */ /* Represents an algorithm to solve the minimum linear cost tension problem with linear costs in a graph using the linear program modeling III (using the incidence matrix). */ template <tdGraph> class clLinearSolveAlgoIII : public clLinearSolveAlgo<tuGraph> { //-----------------------------------------------------------------------------------------Private private_property constructor clLinearSolveAlgoIII(const clLinearSolveAlgoIII &); private_property clLinearSolveAlgoIII & operator = (const clLinearSolveAlgoIII &); //------------------------------------------------------------------------------------------Public public_property constructor clLinearSolveAlgoIII(void); public_property destructor clLinearSolveAlgoIII(void);
public_property void buildLinearSystem(clTensionSystem &,clGraph<tuGraph> &) const; public_property tyInteger run(clGraph<tuGraph> &,ctTensionSystemSolver &) const; }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// B i n a r y S o l v e A l g o Inline //--------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clBinarySolveAlgo */ /* Builds an algorithm to solve the minimum cost tension problem. */ template <tdGraph> inline clBinarySolveAlgo<tuGraph>::clBinarySolveAlgo(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clBinarySolveAlgo */ /* Destructs the algorithm. */ template <tdGraph> inline clBinarySolveAlgo<tuGraph>::~clBinarySolveAlgo(void) {} //----------------------------------------------------------------------------------------------Run /*METHOD clBinarySolveAlgo */ /* Solves the minimum cost tension problem using the default linear program solver. */ template <tdGraph> inline tyInteger clBinarySolveAlgo<tuGraph>::run(clGraph<tuGraph> & agGraph) const { return (run(agGraph,clTensionSystemSolver::defaultSolver())); } //---------------------------------------------------------------------------------------DefaultRun /*METHOD clBinarySolveAlgo */ /* Solves the minimum cost tension problem of a graph using the default version of the algorithm (modeling I) with the default linear program solver. Static method. */ template <tdGraph> inline tyInteger clBinarySolveAlgo<tuGraph>::defaultRun(clGraph<tuGraph> & agGraph) { return (clBinarySolveAlgoI<tuGraph>().clBinarySolveAlgo<tuGraph>::run(agGraph)); } }
// D i s c r e t e S o l v e A l g o Inline //----------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clDiscreteSolveAlgo */ /* Builds an algorithm to solve the minimum cost tension problem. */ template <tdGraph> inline clDiscreteSolveAlgo<tuGraph>::clDiscreteSolveAlgo(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clDiscreteSolveAlgo */ /* Destructs the algorithm. */ template <tdGraph> inline clDiscreteSolveAlgo<tuGraph>::~clDiscreteSolveAlgo(void) {} //----------------------------------------------------------------------------------------------Run /*METHOD clDiscreteSolveAlgo */ /* Solves the minimum cost tension problem using the default linear program solver. */ template <tdGraph> inline tyInteger clDiscreteSolveAlgo<tuGraph>::run(clGraph<tuGraph> & agGraph) const { return (run(agGraph,clTensionSystemSolver::defaultSolver())); } //---------------------------------------------------------------------------------------DefaultRun /*METHOD clDiscreteSolveAlgo */ /* Solves the minimum cost tension problem of a graph using the default version of the algorithm (modeling I) with the default linear program solver. Static method. */ template <tdGraph> inline tyInteger clDiscreteSolveAlgo<tuGraph>::defaultRun(clGraph<tuGraph> & agGraph) { return (clDiscreteSolveAlgoI<tuGraph>().clDiscreteSolveAlgo<tuGraph>::run(agGraph)); } }
// L i n e a r S o l v e A l g o Inline //--------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clLinearSolveAlgo */ /* Builds an algorithm to solve the minimum cost tension problem. */ template <tdGraph> inline clLinearSolveAlgo<tuGraph>::clLinearSolveAlgo(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clLinearSolveAlgo */ /* Destructs the algorithm. */ template <tdGraph> inline clLinearSolveAlgo<tuGraph>::~clLinearSolveAlgo(void) {} //----------------------------------------------------------------------------------------------Run /*METHOD clLinearSolveAlgo */ /* Solves the minimum cost tension problem using the default linear program solver. */ template <tdGraph> inline tyInteger clLinearSolveAlgo<tuGraph>::run(clGraph<tuGraph> & agGraph) const { return (run(agGraph,clTensionSystemSolver::defaultSolver())); } //---------------------------------------------------------------------------------------DefaultRun /*METHOD clLinearSolveAlgo */ /* Solves the minimum cost tension problem of a graph using the default version of the algorithm (modeling II) with the default linear program solver. Static method. */ template <tdGraph> inline tyInteger clLinearSolveAlgo<tuGraph>::defaultRun(clGraph<tuGraph> & agGraph) { return (clLinearSolveAlgoII<tuGraph>().clLinearSolveAlgo<tuGraph>::run(agGraph)); } }
// B i n a r y S o l v e A l g o I Inline //------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clBinarySolveAlgoI */ /* Builds an algorithm to solve the minimum cost tension problem. Short or long cycles can be chosen to create the cycle base used by the linear program model (default is short). */ template <tdGraph> inline clBinarySolveAlgoI<tuGraph>::clBinarySolveAlgoI(tyBoolean agShortCycles) : atShortCycles(agShortCycles) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clBinarySolveAlgoI */ /* Destructs the algorithm. */ template <tdGraph> inline clBinarySolveAlgoI<tuGraph>::~clBinarySolveAlgoI(void) {} }
// D i s c r e t e S o l v e A l g o I Inline //--------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clDiscreteSolveAlgoI */ /* Builds an algorithm to solve the minimum cost tension problem. Short or long cycles can be chosen to create the cycle base used by the linear program model (default is short). */ template <tdGraph> inline clDiscreteSolveAlgoI<tuGraph>::clDiscreteSolveAlgoI(tyBoolean agShortCycles) : atShortCycles(agShortCycles) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clDiscreteSolveAlgoI */ /* Destructs the algorithm. */ template <tdGraph> inline clDiscreteSolveAlgoI<tuGraph>::~clDiscreteSolveAlgoI(void) {} }
// L i n e a r S o l v e A l g o I Inline //------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clLinearSolveAlgoI */ /* Builds an algorithm to solve the minimum cost tension problem. Short or long cycles can be chosen to create the cycle base used by the linear program model (default is short). */ template <tdGraph> inline clLinearSolveAlgoI<tuGraph>::clLinearSolveAlgoI(tyBoolean agShortCycles) : atShortCycles(agShortCycles) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clLinearSolveAlgoI */ /* Destructs the algorithm. */ template <tdGraph> inline clLinearSolveAlgoI<tuGraph>::~clLinearSolveAlgoI(void) {} }
// B i n a r y S o l v e A l g o I I Inline //----------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clBinarySolveAlgoII */ /* Builds an algorithm to solve the minimum cost tension problem. */ template <tdGraph> inline clBinarySolveAlgoII<tuGraph>::clBinarySolveAlgoII(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clBinarySolveAlgoII */ /* Destructs the algorithm. */ template <tdGraph> inline clBinarySolveAlgoII<tuGraph>::~clBinarySolveAlgoII(void) {} }
// D i s c r e t e S o l v e A l g o I I Inline //------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clDiscreteSolveAlgoII */ /* Builds an algorithm to solve the minimum cost tension problem. */ template <tdGraph> inline clDiscreteSolveAlgoII<tuGraph>::clDiscreteSolveAlgoII(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clDiscreteSolveAlgoII */ /* Destructs the algorithm. */ template <tdGraph> inline clDiscreteSolveAlgoII<tuGraph>::~clDiscreteSolveAlgoII(void) {} }
// L i n e a r S o l v e A l g o I I Inline //----------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clLinearSolveAlgoII */ /* Builds an algorithm to solve the minimum cost tension problem. Short or long cycles can be chosen to create the cycle base used by the linear program model (default is short). */ template <tdGraph> inline clLinearSolveAlgoII<tuGraph>::clLinearSolveAlgoII(tyBoolean agShortCycles) : atShortCycles(agShortCycles) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clLinearSolveAlgoII */ /* Destructs the algorithm. */ template <tdGraph> inline clLinearSolveAlgoII<tuGraph>::~clLinearSolveAlgoII(void) {} }
// L i n e a r S o l v e A l g o I I I Inline //--------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clLinearSolveAlgoIII */ /* Builds an algorithm to solve the minimum cost tension problem. */ template <tdGraph> inline clLinearSolveAlgoIII<tuGraph>::clLinearSolveAlgoIII(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clLinearSolveAlgoIII */ /* Destructs the algorithm. */ template <tdGraph> inline clLinearSolveAlgoIII<tuGraph>::~clLinearSolveAlgoIII(void) {} }
// Functions Implementation //---------------------------------------------------------------------- namespace public_area {}
namespace private_area { //---------------------------------------------------------------------------------------FindCycles template <tdGraph> void findCycles(clGraph<tuGraph> & agGraph,clCycleS & agCycleS,tyBoolean atShortCycles) { typedef clCycleS::const_iterator clCycleIterator;
clCycleIterator lcCurrentCycle; clCycleS lcCycleS; clCycleIterator lcLastCycle;
tyCardinal lcCounter1 = 0; tyCardinal lcCounter2 = 0;
if (atShortCycles) { graphAlgorithm::findCycles(agGraph,agCycleS,true); lcCurrentCycle=agCycleS.begin(); lcLastCycle=agCycleS.end();
while (lcCurrentCycle!=lcLastCycle) { lcCounter1+=(*lcCurrentCycle).size(); ++lcCurrentCycle; }
graphAlgorithm::findCycles(agGraph,lcCycleS,true); lcCurrentCycle=lcCycleS.begin(); lcLastCycle=lcCycleS.end();
while (lcCurrentCycle!=lcLastCycle) { lcCounter2+=(*lcCurrentCycle).size(); ++lcCurrentCycle; }
if (lcCounter2<lcCounter1) { agCycleS.erase(agCycleS.begin(),agCycleS.end()); agCycleS=lcCycleS; } } else graphAlgorithm::findCycles(agGraph,agCycleS,false); } }
// B i n a r y S o l v e A l g o Implementation //------------------------------------------------- namespace public_area { //----------------------------------------------------------------------------BuildLinearRelaxation /*METHOD clBinarySolveAlgo */ /* Builds a linear relaxation of the linear program equivalent to the minimum binary cost tension problem of a graph. */ template <tdGraph> void clBinarySolveAlgo<tuGraph>::buildLinearRelaxation(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
clVariableIterator lcCurrentVariable; clVariableIterator lcLastVariable; clTensionVariable * lcVariable;
buildLinearSystem(agSystem,agGraph); lcCurrentVariable=agSystem.variables().begin(); lcLastVariable=agSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { lcVariable=(*lcCurrentVariable).second; if (lcVariable->content().significance()==binary) lcVariable->kind()=linearSystem::realVariable; ++lcCurrentVariable; } } //----------------------------------------------------------------------------SolveLinearRelaxation /*METHOD clBinarySolveAlgo */ /* Solves the linear relaxation of the minimum binary cost tension problem of a graph using a given linear program solver. A lower bound for the original problem can be collected. */ template <tdGraph> tyInteger clBinarySolveAlgo<tuGraph>::solveLinearRelaxation(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver, tyReal & agLowerBound) const { typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
clArc<tuGraph> * lcArc; clVariableIterator lcCurrentVariable; tyInteger lcIteration; clVariableIterator lcLastVariable; clTensionSystem lcSystem; clTensionVariable * lcVariable;
agGraph.solved()=false; buildLinearRelaxation(lcSystem,agGraph); lcIteration=agLinearSolver.run(lcSystem); if (not lcSystem.solved()) return (-1); lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { lcVariable=(*lcCurrentVariable).second;
if (lcVariable->content().significance()==tension) { lcArc=&(agGraph.arc(lcVariable->content().arc())); lcArc->data().expected()=lcVariable->value(); }
++lcCurrentVariable; }
agLowerBound=lcSystem.objective().value(); agGraph.solved()=true; return (lcIteration); } //------------------------------------------------------------------------SolveLagrangeanRelaxation /*METHOD clBinarySolveAlgo */ /* Solves the Lagrangean relaxation of the minimum binary cost tension problem of a graph using a given linear program solver. The maximum number of iterations to solve the relaxation with the subgradient method must be given. A lower bound for the original problem can be collected. */ template <tdGraph> tyInteger clBinarySolveAlgo<tuGraph>::solveLagrangeanRelaxation(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver, tyCardinal agMaxIteration, tyReal & agLowerBound) const { typedef clArc<tuGraph> cpArc; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_map(cpArc *,tyPairReal) cpCoefficientX;
cpArc * lcArc; cpCoefficientX lcCoefficientX;
tyCardinal lcBlockIteration = agGraph.arcs().size(); cpArcIterator lcCurrentArc = agGraph.arcs().begin(); cpArcIterator lcLastArc = agGraph.arcs().end(); tyReal lcStep = 2.0;
agLowerBound=0.0;
// Lagrangean Coefficients Initialization // while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcCoefficientX.insert(std_make_pair(lcArc,standard::make_pair(0.0,0.0))); ++lcCurrentArc; }
// Lagrangean Relaxation Resolution // return (solveLagrangeanRelaxation(agGraph,agLinearSolver,agMaxIteration,lcBlockIteration, lcStep,agLowerBound,lcCoefficientX)); } //------------------------------------------------------------------------SolveLagrangeanRelaxation /*METHOD clBinarySolveAlgo */ /* Solves the Lagrangean relaxation of the minimum binary cost tension problem of a graph using a given linear program solver. The maximum and per-block numbers of iterations to solve the relaxation with the subgradient method and its step must be given. A lower bound for the original problem can be collected. The starting Lagrangean coefficients must also be provided. */ template <tdGraph> tyInteger clBinarySolveAlgo<tuGraph>::solveLagrangeanRelaxation(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver, tyCardinal agMaxIteration,tyCardinal agBlockIteration, tyReal & agStep,tyReal & agLowerBound, std_map(clArc<tuGraph> *,tyPairReal) & agCoefficientX) const { typedef clArc<tuGraph> cpArc; typedef std_map(cpArc *,tyPairReal) cpCoefficientX; typedef typename cpCoefficientX::iterator cpCoefficientIterator; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
typedef graphProblemMinCostTensionStructure::clVariableContent clVariableContent;
cpArc * lcArc; clVariableContent * lcContent; cpCoefficientIterator lcCurrentCoefficient; clVariableIterator lcCurrentVariable; cpCoefficientIterator lcLastCoefficient; clVariableIterator lcLastVariable; clTensionSystem lcSystem;
tyReal lcCoefficient1; tyReal lcCoefficient2; tyReal lcCost; tyReal lcDelta; tyReal lcImprovement; tyInteger lcIteration; tyReal lcMaxImprovement; tyReal lcMaximum; tyReal lcMinimum; tyReal lcOptimum; tyInteger lcSelection;
tyReal lcRate = 0.5; tyCardinal lcSubgradientIteration = 0; tyInteger lcTotalIteration = 0;
agGraph.solved()=false;
do { // Relaxed System Resolution // lcSystem.removeConstraints(); lcSystem.removeVariables(); buildLagrangeanRelaxation(lcSystem,agGraph,agCoefficientX); lcIteration=agLinearSolver.run(lcSystem); if (not lcSystem.solved()) return (-1); lcTotalIteration+=lcIteration;
// Connection With The Graph // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { lcContent=&((*lcCurrentVariable).second->content());
if (lcContent->significance()==tension) { lcArc=&(agGraph.arc(lcContent->arc())); lcArc->data().expected()=(*lcCurrentVariable).second->value(); }
++lcCurrentVariable; }
// Subgradient Iteration // lcCurrentCoefficient=agCoefficientX.begin(); lcLastCoefficient=agCoefficientX.end(); lcMaxImprovement=0.0; agLowerBound=0.0;
while (lcCurrentCoefficient!=lcLastCoefficient) { lcArc=(*lcCurrentCoefficient).first; lcCoefficient1=(*lcCurrentCoefficient).second.first; lcCoefficient2=(*lcCurrentCoefficient).second.second; lcMinimum=lcArc->data().minimum(); lcMaximum=lcArc->data().maximum(); lcOptimum=lcArc->data().optimum();
lcCost=lcArc->data().weight()-lcCoefficient1*(lcOptimum-lcMinimum) -lcCoefficient2*(lcMaximum-lcOptimum);
lcSelection=(lcCost<0 ? 1 : 0); lcDelta=lcArc->data().tension()+lcSelection*(lcOptimum-lcMinimum)-lcOptimum;
if (not isEqual(lcDelta,0.0)) { (*lcCurrentCoefficient).second.first-=agStep*lcDelta; if ((*lcCurrentCoefficient).second.first<0.0) (*lcCurrentCoefficient).second.first=0.0; lcImprovement=std::fabs((*lcCurrentCoefficient).second.first-lcCoefficient1); lcMaxImprovement=maxi(lcMaxImprovement,lcImprovement); }
if (lcMaximum<lcArc->data().positiveInfinity()) { lcDelta=-lcArc->data().tension()+lcSelection*(lcMaximum-lcOptimum)+lcOptimum;
if (not isEqual(lcDelta,0.0)) { (*lcCurrentCoefficient).second.second-=agStep*lcDelta; if ((*lcCurrentCoefficient).second.second<0.0) (*lcCurrentCoefficient).second.second=0.0; lcImprovement=std::fabs((*lcCurrentCoefficient).second.second-lcCoefficient2); lcMaxImprovement=maxi(lcMaxImprovement,lcImprovement); } }
lcCost*=lcSelection; lcCost+=(lcCoefficient2-lcCoefficient1)*lcArc->data().tension(); lcCost+=(lcCoefficient1-lcCoefficient2)*lcOptimum; agLowerBound+=lcCost; ++lcCurrentCoefficient; }
++lcSubgradientIteration; if (lcSubgradientIteration%agBlockIteration==0) agStep*=lcRate; } while (lcSubgradientIteration<agMaxIteration and lcMaxImprovement>1e-6);
agGraph.solved()=true; return (lcTotalIteration); } }
// B i n a r y S o l v e A l g o I Implementation //----------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clBinarySolveAlgoI */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clBinarySolveAlgoI<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("binarySolveAlgoI::buildLinearSystem");
typedef clCycle::const_iterator clArcIterator; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clCycleS::const_iterator clCycleIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBalanceConstraint; clTensionConstraint * lcBoundaryConstraint; clCycleS lcCycleS; clTensionConstraint * lcMeetingConstraint; clTensionVariable * lcSelectionVariable; tyReal lcTempo; clTensionVariable * lcTensionVariable;
tyMark lcArcsMark; clArcIterator lcCurrentArc; cpArcIterator lcCurrentArc2; clCycleIterator lcCurrentCycle; clArcIterator lcLastArc; cpArcIterator lcLastArc2; clCycleIterator lcLastCycle;
// Cycles Search // agSystem.objective().kind()=linearSystem::minimum; private_area::findCycles(agGraph,lcCycleS,atShortCycles); lcCurrentCycle=lcCycleS.begin(); lcLastCycle=lcCycleS.end(); lcArcsMark=++(agGraph.mark());
// Constrained Arcs // while (lcCurrentCycle!=lcLastCycle) { lcMeetingConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcCurrentArc=(*lcCurrentCycle).begin(); lcLastArc=(*lcCurrentCycle).end();
while (lcCurrentArc!=lcLastArc) { lcArc=&(agGraph.arc((*lcCurrentArc).first));
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { // Tension Variable // lcArc->mark()=lcArcsMark; lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->key(),lcTensionVariable->key())); lcTensionVariable->content().significance()=tension; lcTensionVariable->content().arc()=lcArc->key();
// Selection Variable // lcSelectionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcSelectionVariable->kind()=linearSystem::integralVariable; lcSelectionVariable->content().significance()=binary; lcSelectionVariable->content().arc()=lcArc->key(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->boundary()=1.0; lcBoundaryConstraint->setCoefficient(lcSelectionVariable->key(),+1.0);
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcTempo=lcArc->data().optimum()-lcArc->data().minimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::superiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->setCoefficient(lcSelectionVariable->key(),lcTempo); lcBoundaryConstraint->boundary()=lcArc->data().optimum();
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcTempo=lcArc->data().maximum()-lcArc->data().optimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->setCoefficient(lcSelectionVariable->key(),-lcTempo); lcBoundaryConstraint->boundary()=lcArc->data().optimum(); }
// Objective // agSystem.objective().setCoefficient(lcSelectionVariable->key(),(lcArc->data().weight())); }
// Direction in the cycle // lcMeetingConstraint->setCoefficient(lcAssociation[lcArc->key()],(*lcCurrentArc).second);
lcCurrentArc++; }
lcCurrentCycle++; }
// Unconstrained Arcs // lcCurrentArc2=agGraph.arcs().begin(); lcLastArc2=agGraph.arcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second;
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcTensionVariable->content().significance()=tension; lcTensionVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Variable Is Equal To Optimum // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBalanceConstraint->boundary()=lcArc->data().optimum(); }
lcCurrentArc2++; } } //----------------------------------------------------------------------------------------------Run /*METHOD clBinarySolveAlgoI */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clBinarySolveAlgoI<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef clArc<tuGraph> cpArc; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
typedef graphProblemMinCostTensionStructure::clVariableContent clVariableContent;
cpArc * lcArc; clVariableContent * lcContent; clVariableIterator lcCurrentVariable; clVariableIterator lcLastVariable; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Connection With The Graph // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { lcContent=&((*lcCurrentVariable).second->content());
if (lcContent->significance()==tension) { lcArc=&(agGraph.arc(lcContent->arc())); lcArc->data().expected()=(*lcCurrentVariable).second->value(); }
++lcCurrentVariable; }
return (lcNbIteration); } //------------------------------------------------------------------------BuildLagrangeanRelaxation /*METHOD clBinarySolveAlgoI */ /* Builds a Lagrangean relaxation of the linear program equivalent to the minimum binary cost tension problem of a graph. Lagrangean coefficients for the relaxed constraints must be given. */ template <tdGraph> void clBinarySolveAlgoI<tuGraph>::buildLagrangeanRelaxation(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph, std_map(clArc<tuGraph> *,tyPairReal) & agCoefficientX) const { method_name("binarySolveAlgoI::buildLagrangeanRelaxation");
typedef clCycle::const_iterator clArcIterator; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clCycleS::const_iterator clCycleIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBalanceConstraint; clTensionConstraint * lcBoundaryConstraint; clCycleS lcCycleS; clTensionConstraint * lcMeetingConstraint; clTensionVariable * lcTensionVariable; tyReal lcTempo;
tyMark lcArcsMark; clArcIterator lcCurrentArc; cpArcIterator lcCurrentArc2; clCycleIterator lcCurrentCycle; clArcIterator lcLastArc; cpArcIterator lcLastArc2; clCycleIterator lcLastCycle;
agSystem.objective().kind()=linearSystem::minimum; private_area::findCycles(agGraph,lcCycleS,atShortCycles); lcCurrentCycle=lcCycleS.begin(); lcLastCycle=lcCycleS.end(); lcArcsMark=++(agGraph.mark());
// Constrained Arcs // while (lcCurrentCycle!=lcLastCycle) { lcMeetingConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcCurrentArc=(*lcCurrentCycle).begin(); lcLastArc=(*lcCurrentCycle).end();
while (lcCurrentArc!=lcLastArc) { lcArc=&(agGraph.arc((*lcCurrentArc).first));
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { // Tension Variable // lcArc->mark()=lcArcsMark; lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->key(),lcTensionVariable->key())); lcTensionVariable->content().significance()=tension; lcTensionVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::superiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->boundary()=lcArc->data().minimum();
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->boundary()=lcArc->data().maximum(); lcTempo=agCoefficientX[lcArc].second-agCoefficientX[lcArc].first; } else lcTempo=-agCoefficientX[lcArc].first;
// Objective // agSystem.objective().setCoefficient(lcTensionVariable->key(),lcTempo); }
// Direction In The Cycle // lcMeetingConstraint->setCoefficient(lcAssociation[lcArc->key()],(*lcCurrentArc).second);
lcCurrentArc++; }
lcCurrentCycle++; }
// Unconstrained Arcs // lcCurrentArc2=agGraph.arcs().begin(); lcLastArc2=agGraph.arcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second;
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcTensionVariable->content().significance()=tension; lcTensionVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Variable Is Equal To Optimum // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBalanceConstraint->boundary()=lcArc->data().optimum(); }
lcCurrentArc2++; } } }
// D i s c r e t e S o l v e A l g o I Implementation //------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clDiscreteSolveAlgoI */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clDiscreteSolveAlgoI<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("discreteSolveAlgoI::buildLinearSystem");
typedef clArc<tuGraph> cpArc; typedef clCycle::const_iterator clArcIterator; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clCycleS::const_iterator clCycleIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
cpArc * lcArc; clAssociation lcAssociation1; clAssociation lcAssociation2; clTensionConstraint * lcBalanceConstraint; clTensionConstraint * lcBoundaryConstraint; tyCardinal lcCounter; clCycleS lcCycleS; clTensionConstraint * lcExclusivityConstraint; clTensionConstraint * lcMeetingConstraint; clTensionVariable * lcShrinkVariable; clTensionVariable * lcStretchVariable; tyReal lcTempo; clTensionConstraint * lcTensionConstraint; clTensionVariable * lcTensionVariable;
tyMark lcArcsMark; clArcIterator lcCurrentArc; cpArcIterator lcCurrentArc2; clCycleIterator lcCurrentCycle; clArcIterator lcLastArc; cpArcIterator lcLastArc2; clCycleIterator lcLastCycle;
// Cycles Search // agSystem.objective().kind()=linearSystem::minimum; private_area::findCycles(agGraph,lcCycleS,atShortCycles); lcCurrentCycle=lcCycleS.begin(); lcLastCycle=lcCycleS.end(); lcArcsMark=++(agGraph.mark());
// Constrained Arcs // while (lcCurrentCycle!=lcLastCycle) { lcMeetingConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcCurrentArc=(*lcCurrentCycle).begin(); lcLastArc=(*lcCurrentCycle).end();
while (lcCurrentArc!=lcLastArc) { lcArc=&(agGraph.arc((*lcCurrentArc).first));
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { // Stretching & Shrinking Tensions // lcArc->mark()=lcArcsMark; lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation1.insert(std_make_pair(lcArc->key(),lcShrinkVariable->key())); lcAssociation2.insert(std_make_pair(lcArc->key(),lcStretchVariable->key()));
lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
// Feasible Tensions // lcCounter=0; lcTensionConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcTensionConstraint->boundary()=lcArc->data().optimum(); lcTensionConstraint->setCoefficient(lcShrinkVariable->key(),1.0); lcTensionConstraint->setCoefficient(lcStretchVariable->key(),-1.0); lcExclusivityConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcExclusivityConstraint->boundary()=1.0;
while (lcCounter<lcArc->data().feasibles().size()) { lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcTensionVariable->content().significance()=binary; lcTensionVariable->content().arc()=lcArc->key(); lcTensionVariable->kind()=linearSystem::integralVariable; lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->boundary()=1.0; lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),1.0); lcTempo=lcArc->data().feasibles()[lcCounter]; lcTensionConstraint->setCoefficient(lcTensionVariable->key(),lcTempo); lcExclusivityConstraint->setCoefficient(lcTensionVariable->key(),1.0); ++lcCounter; }
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Objective // agSystem.objective().setCoefficient(lcShrinkVariable->key(),(lcArc->data().shrinkingCost())); agSystem.objective().setCoefficient(lcStretchVariable->key(),lcArc->data().stretchingCost()); }
// Direction In The Cycle // lcMeetingConstraint->setCoefficient(lcAssociation1[lcArc->key()],-(*lcCurrentArc).second); lcMeetingConstraint->setCoefficient(lcAssociation2[lcArc->key()],(*lcCurrentArc).second); ((*lcMeetingConstraint).boundary())-=(*lcCurrentArc).second*(lcArc->data().optimum());
lcCurrentArc++; }
lcCurrentCycle++; }
// Unconstrained Arcs // lcCurrentArc2=agGraph.arcs().begin(); lcLastArc2=agGraph.arcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second;
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Shrink Variable Is Null // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcBalanceConstraint->boundary()=0.0;
// Stretch Variable Is Null // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcStretchVariable->key(),+1.0); lcBalanceConstraint->boundary()=0.0; }
lcCurrentArc2++; } } //----------------------------------------------------------------------------------------------Run /*METHOD clDiscreteSolveAlgoI */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clDiscreteSolveAlgoI<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef clArc<tuGraph> cpArc; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
typedef graphProblemMinCostTensionStructure::clVariableContent clVariableContent;
cpArc * lcArc; clVariableContent * lcContent; clVariableIterator lcCurrentVariable; clVariableIterator lcLastVariable; tyMark lcMark; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Connection With The Graph // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end(); lcMark=++(agGraph.mark());
while (lcCurrentVariable!=lcLastVariable) { lcContent=&((*lcCurrentVariable).second->content());
if (lcContent->significance()==shrinking or lcContent->significance()==stretching) { lcArc=&(agGraph.arc(lcContent->arc()));
if (lcArc->mark()!=lcMark) { lcArc->data().expected()=lcArc->data().optimum(); lcArc->mark()=lcMark; }
if (lcContent->significance()==shrinking) lcArc->data().expected()-=(*lcCurrentVariable).second->value(); else lcArc->data().expected()+=(*lcCurrentVariable).second->value(); }
++lcCurrentVariable; }
return (lcNbIteration); } }
// L i n e a r S o l v e A l g o I Implementation //----------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clLinearSolveAlgoI */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clLinearSolveAlgoI<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("linearSolveAlgoI::buildLinearSystem");
typedef clCycle::const_iterator clArcIterator; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clCycleS::const_iterator clCycleIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBalanceConstraint; clTensionConstraint * lcBoundaryConstraint; clCycleS lcCycleS; clTensionVariable * lcDurationVariable; clTensionConstraint * lcMeetingConstraint; clTensionVariable * lcShrinkVariable; clTensionVariable * lcStretchVariable; tyReal lcTempo;
tyMark lcArcsMark; clArcIterator lcCurrentArc; cpArcIterator lcCurrentArc2; clCycleIterator lcCurrentCycle; clArcIterator lcLastArc; cpArcIterator lcLastArc2; clCycleIterator lcLastCycle;
// Cycles Search // agSystem.objective().kind()=linearSystem::minimum; private_area::findCycles(agGraph,lcCycleS,atShortCycles); lcCurrentCycle=lcCycleS.begin(); lcLastCycle=lcCycleS.end(); lcArcsMark=++(agGraph.mark());
// Constrained Arcs // while (lcCurrentCycle!=lcLastCycle) { lcMeetingConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcCurrentArc=(*lcCurrentCycle).begin(); lcLastArc=(*lcCurrentCycle).end();
while (lcCurrentArc!=lcLastArc) { lcArc=&(agGraph.arc((*lcCurrentArc).first));
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcDurationVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->key(),lcDurationVariable->key()));
lcDurationVariable->content().significance()=tension; lcDurationVariable->content().arc()=lcArc->key(); lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcTempo=lcArc->data().optimum()-lcArc->data().minimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcBoundaryConstraint->boundary()=(lcTempo<0 ? 0 : lcTempo);
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcStretchVariable->key(),+1.0); lcTempo=lcArc->data().maximum()-lcArc->data().optimum(); lcBoundaryConstraint->boundary()=(lcTempo<0 ? 0 : lcTempo); }
// Balance // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcDurationVariable->key(),+1.0); lcBalanceConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcBalanceConstraint->setCoefficient(lcStretchVariable->key(),-1.0); lcBalanceConstraint->boundary()=lcArc->data().optimum();
// Objective // agSystem.objective().setCoefficient(lcShrinkVariable->key(),lcArc->data().shrinkingCost()); agSystem.objective().setCoefficient(lcStretchVariable->key(),lcArc->data().stretchingCost()); }
// Direction In The Cycle // lcMeetingConstraint->setCoefficient(lcAssociation[lcArc->key()],(*lcCurrentArc).second);
lcCurrentArc++; }
lcCurrentCycle++; }
// Unconstrained Arcs // lcCurrentArc2=agGraph.arcs().begin(); lcLastArc2=agGraph.arcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second;
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcDurationVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcDurationVariable->content().significance()=tension; lcDurationVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Variable Equal To Optimum // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcDurationVariable->key(),+1.0); lcBalanceConstraint->boundary()=lcArc->data().optimum(); }
lcCurrentArc2++; } } //----------------------------------------------------------------------------------------------Run /*METHOD clLinearSolveAlgoI */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clLinearSolveAlgoI<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
clVariableIterator lcCurrentVariable; clVariableIterator lcLastVariable; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Connection With The Graph // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) {
if ((*lcCurrentVariable).second->content().significance()==tension) agGraph.arc((*lcCurrentVariable).second->content().arc()).data().expected()= (*lcCurrentVariable).second->value();
lcCurrentVariable++; }
return (lcNbIteration); } }
// B i n a r y S o l v e A l g o I I Implementation //--------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clBinarySolveAlgoII */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clBinarySolveAlgoII<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("binarySolveAlgoII::buildLinearSystem");
typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBoundaryConstraint; clTensionVariable * lcPotentialVariable; clTensionVariable * lcSelectionVariable; linearSystem::tyVariableKey lcSourceKey; linearSystem::tyVariableKey lcTargetKey; clTensionConstraint * lcTensionConstraint; clTensionVariable * lcTensionVariable; tyReal lcTempo;
cpArcIterator lcCurrentArc = agGraph.arcs().begin(); cpArcIterator lcLastArc = agGraph.arcs().end(); tyMark lcMark = ++(agGraph.mark());
agSystem.objective().kind()=linearSystem::minimum;
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
// Potential Variables // if (lcArc->sourceNode()->mark()!=lcMark) { lcArc->sourceNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->sourceNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->sourceNode()->key(); lcSourceKey=lcPotentialVariable->key(); } else lcSourceKey=lcAssociation[lcArc->sourceNode()->key()];
if (lcArc->targetNode()->mark()!=lcMark) { lcArc->targetNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->targetNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->targetNode()->key(); lcTargetKey=lcPotentialVariable->key(); } else lcTargetKey=lcAssociation[lcArc->targetNode()->key()];
// Tension Variable // lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcTensionVariable->content().significance()=tension; lcTensionVariable->content().arc()=lcArc->key();
// Selection Variable // lcSelectionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcSelectionVariable->kind()=linearSystem::integralVariable; lcSelectionVariable->content().significance()=binary; lcSelectionVariable->content().arc()=lcArc->key(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->boundary()=1.0; lcBoundaryConstraint->setCoefficient(lcSelectionVariable->key(),+1.0);
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcTempo=lcArc->data().optimum()-lcArc->data().minimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::superiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->setCoefficient(lcSelectionVariable->key(),lcTempo); lcBoundaryConstraint->boundary()=lcArc->data().optimum();
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcTempo=lcArc->data().maximum()-lcArc->data().optimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->setCoefficient(lcSelectionVariable->key(),-lcTempo); lcBoundaryConstraint->boundary()=lcArc->data().optimum(); }
// Tension Constraint // lcTensionConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcTensionConstraint->setCoefficient(lcTargetKey,+1.0); lcTensionConstraint->setCoefficient(lcSourceKey,-1.0); lcTensionConstraint->setCoefficient(lcTensionVariable->key(),-1.0); lcTensionConstraint->boundary()=0.0;
// Objective // agSystem.objective().setCoefficient(lcSelectionVariable->key(),lcArc->data().weight());
++lcCurrentArc; } } //----------------------------------------------------------------------------------------------Run /*METHOD clBinarySolveAlgoII */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clBinarySolveAlgoII<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; clVariableIterator lcCurrentVariable; cpArcIterator lcLastArc; clVariableIterator lcLastVariable; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Potential Collecting // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { if ((*lcCurrentVariable).second->content().significance()==potential) agGraph.node((*lcCurrentVariable).second->content().node()).data().potential()= (*lcCurrentVariable).second->value();
++lcCurrentVariable; }
// Tension Building // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
lcArc->data().tension()=lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential();
++lcCurrentArc; }
return (lcNbIteration); } //------------------------------------------------------------------------BuildLagrangeanRelaxation /*METHOD clBinarySolveAlgoII */ /* Builds a Lagrangean relaxation of the linear program equivalent to the minimum binary cost tension problem of a graph. Lagrangean coefficients for the relaxed constraints must be given. */ template <tdGraph> void clBinarySolveAlgoII<tuGraph>::buildLagrangeanRelaxation (clTensionSystem & agSystem, clGraph<tuGraph> & agGraph, std_map(clArc<tuGraph> *,tyPairReal) & agCoefficientX) const { method_name("binarySolveAlgoII::buildLagrangeanRelaxation");
typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBoundaryConstraint; clTensionVariable * lcPotentialVariable; linearSystem::tyVariableKey lcSourceKey; linearSystem::tyVariableKey lcTargetKey; clTensionConstraint * lcTensionConstraint; clTensionVariable * lcTensionVariable; tyReal lcTempo;
cpArcIterator lcCurrentArc = agGraph.arcs().begin(); cpArcIterator lcLastArc = agGraph.arcs().end(); tyMark lcMark = ++(agGraph.mark());
agSystem.objective().kind()=linearSystem::minimum;
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
// Potential Variables // if (lcArc->sourceNode()->mark()!=lcMark) { lcArc->sourceNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->sourceNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->sourceNode()->key(); lcSourceKey=lcPotentialVariable->key(); } else lcSourceKey=lcAssociation[lcArc->sourceNode()->key()];
if (lcArc->targetNode()->mark()!=lcMark) { lcArc->targetNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->targetNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->targetNode()->key(); lcTargetKey=lcPotentialVariable->key(); } else lcTargetKey=lcAssociation[lcArc->targetNode()->key()];
// Tension Variable // lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcTensionVariable->content().significance()=tension; lcTensionVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::superiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->boundary()=lcArc->data().minimum();
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),+1.0); lcBoundaryConstraint->boundary()=lcArc->data().maximum(); }
// Tension Constraint // lcTensionConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcTensionConstraint->setCoefficient(lcTargetKey,+1.0); lcTensionConstraint->setCoefficient(lcSourceKey,-1.0); lcTensionConstraint->setCoefficient(lcTensionVariable->key(),-1.0); lcTensionConstraint->boundary()=0.0;
// Objective // lcTempo=agCoefficientX[lcArc].second-agCoefficientX[lcArc].first; agSystem.objective().setCoefficient(lcTensionVariable->key(),lcTempo);
++lcCurrentArc; } } }
// D i s c r e t e S o l v e A l g o I I Implementation //----------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clDiscreteSolveAlgoII */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clDiscreteSolveAlgoII<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("discreteSolveAlgoII::buildLinearSystem");
typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBoundaryConstraint; tyCardinal lcCounter; clTensionConstraint * lcExclusivityConstraint; clTensionVariable * lcPotentialVariable; clTensionVariable * lcShrinkVariable; linearSystem::tyVariableKey lcSourceKey; clTensionVariable * lcStretchVariable; linearSystem::tyVariableKey lcTargetKey; clTensionConstraint * lcTensionConstraint; clTensionVariable * lcTensionVariable; tyReal lcTempo;
cpArcIterator lcCurrentArc = agGraph.arcs().begin(); cpArcIterator lcLastArc = agGraph.arcs().end(); tyMark lcMark = ++(agGraph.mark());
agSystem.objective().kind()=linearSystem::minimum;
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
// Potential Variables // if (lcArc->sourceNode()->mark()!=lcMark) { lcArc->sourceNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->sourceNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->sourceNode()->key(); lcSourceKey=lcPotentialVariable->key(); } else lcSourceKey=lcAssociation[lcArc->sourceNode()->key()];
if (lcArc->targetNode()->mark()!=lcMark) { lcArc->targetNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->targetNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->targetNode()->key(); lcTargetKey=lcPotentialVariable->key(); } else lcTargetKey=lcAssociation[lcArc->targetNode()->key()];
// Tension Variables // lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey()));
lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Feasible Tensions // lcCounter=0; lcTensionConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcTensionConstraint->boundary()=lcArc->data().optimum(); lcTensionConstraint->setCoefficient(lcShrinkVariable->key(),1.0); lcTensionConstraint->setCoefficient(lcStretchVariable->key(),-1.0); lcExclusivityConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcExclusivityConstraint->boundary()=1.0;
while (lcCounter<lcArc->data().feasibles().size()) { lcTensionVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcTensionVariable->content().significance()=binary; lcTensionVariable->content().arc()=lcArc->key(); lcTensionVariable->kind()=linearSystem::integralVariable; lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->boundary()=1.0; lcBoundaryConstraint->setCoefficient(lcTensionVariable->key(),1.0); lcTempo=lcArc->data().feasibles()[lcCounter]; lcTensionConstraint->setCoefficient(lcTensionVariable->key(),lcTempo); lcExclusivityConstraint->setCoefficient(lcTensionVariable->key(),1.0); ++lcCounter; }
// Tension Constraint // lcTensionConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcTensionConstraint->setCoefficient(lcTargetKey,+1.0); lcTensionConstraint->setCoefficient(lcSourceKey,-1.0); lcTensionConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcTensionConstraint->setCoefficient(lcStretchVariable->key(),-1.0); lcTensionConstraint->boundary()=lcArc->data().optimum();
// Objective // agSystem.objective().setCoefficient(lcShrinkVariable->key(),lcArc->data().shrinkingCost()); agSystem.objective().setCoefficient(lcStretchVariable->key(),lcArc->data().stretchingCost());
++lcCurrentArc; } } //----------------------------------------------------------------------------------------------Run /*METHOD clDiscreteSolveAlgoII */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clDiscreteSolveAlgoII<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; clVariableIterator lcCurrentVariable; cpArcIterator lcLastArc; clVariableIterator lcLastVariable; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Potential Collecting // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { if ((*lcCurrentVariable).second->content().significance()==potential) agGraph.node((*lcCurrentVariable).second->content().node()).data().potential()= (*lcCurrentVariable).second->value();
++lcCurrentVariable; }
// Tension Building // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
lcArc->data().tension()=lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential();
++lcCurrentArc; }
return (lcNbIteration); } }
// L i n e a r S o l v e A l g o I I Implementation //--------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clLinearSolveAlgoII */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clLinearSolveAlgoII<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("linearSolveAlgoII::buildLinearSystem");
typedef clCycle::const_iterator clArcIterator; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clCycleS::const_iterator clCycleIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation1; clAssociation lcAssociation2; clTensionConstraint * lcBalanceConstraint; clTensionConstraint * lcBoundaryConstraint; clCycleS lcCycleS; clTensionConstraint * lcMeetingConstraint; clTensionVariable * lcShrinkVariable; clTensionVariable * lcStretchVariable; tyReal lcTempo;
tyMark lcArcsMark; clArcIterator lcCurrentArc; cpArcIterator lcCurrentArc2; clCycleIterator lcCurrentCycle; clArcIterator lcLastArc; cpArcIterator lcLastArc2; clCycleIterator lcLastCycle;
agSystem.objective().kind()=linearSystem::minimum; private_area::findCycles(agGraph,lcCycleS,atShortCycles); lcCurrentCycle=lcCycleS.begin(); lcLastCycle=lcCycleS.end(); lcArcsMark=++(agGraph.mark());
// Constrained Arcs // while (lcCurrentCycle!=lcLastCycle) { lcMeetingConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcCurrentArc=(*lcCurrentCycle).begin(); lcLastArc=(*lcCurrentCycle).end();
while (lcCurrentArc!=lcLastArc) { lcArc=&(agGraph.arc((*lcCurrentArc).first));
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation1.insert(std_make_pair(lcArc->key(),lcShrinkVariable->key())); lcAssociation2.insert(std_make_pair(lcArc->key(),lcStretchVariable->key()));
lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcTempo=lcArc->data().optimum()-lcArc->data().minimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcBoundaryConstraint->boundary()=(lcTempo<0 ? 0 : lcTempo);
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcTempo=lcArc->data().maximum()-lcArc->data().optimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcStretchVariable->key(),+1.0); lcBoundaryConstraint->boundary()=(lcTempo<0 ? 0 : lcTempo); }
// Objective // agSystem.objective().setCoefficient(lcShrinkVariable->key(),(lcArc->data().shrinkingCost())); agSystem.objective().setCoefficient(lcStretchVariable->key(),lcArc->data().stretchingCost()); }
// Direction In The Cycle // lcMeetingConstraint->setCoefficient(lcAssociation1[lcArc->key()],-(*lcCurrentArc).second); lcMeetingConstraint->setCoefficient(lcAssociation2[lcArc->key()],(*lcCurrentArc).second); ((*lcMeetingConstraint).boundary())-=(*lcCurrentArc).second*(lcArc->data().optimum());
lcCurrentArc++; }
lcCurrentCycle++; }
// Unconstrained Arcs // lcCurrentArc2=agGraph.arcs().begin(); lcLastArc2=agGraph.arcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc=(*lcCurrentArc2).second;
// Associated Variables // if (lcArc->mark()!=lcArcsMark) { lcArc->mark()=lcArcsMark; lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Shrink Variable Is Null // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcBalanceConstraint->boundary()=0.0;
// Stretch Variable Is Null // lcBalanceConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcBalanceConstraint->setCoefficient(lcStretchVariable->key(),+1.0); lcBalanceConstraint->boundary()=0.0; }
lcCurrentArc2++; } } //----------------------------------------------------------------------------------------------Run /*METHOD clLinearSolveAlgoII */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clLinearSolveAlgoII<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef clArc<tuGraph> cpArc; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
typedef graphProblemMinCostTensionStructure::clVariableContent clVariableContent;
cpArc * lcArc; clVariableContent * lcContent; clVariableIterator lcCurrentVariable; clVariableIterator lcLastVariable; tyMark lcMark; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Connection With The Graph // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end(); lcMark=++(agGraph.mark());
while (lcCurrentVariable!=lcLastVariable) { lcContent=&((*lcCurrentVariable).second->content()); lcArc=&(agGraph.arc(lcContent->arc()));
if (lcArc->mark()!=lcMark) { lcArc->data().expected()=lcArc->data().optimum(); lcArc->mark()=lcMark; }
if (lcContent->significance()==shrinking) lcArc->data().expected()-=(*lcCurrentVariable).second->value(); else if (lcContent->significance()==stretching) lcArc->data().expected()+=(*lcCurrentVariable).second->value();
lcCurrentVariable++; }
return (lcNbIteration); } }
// L i n e a r S o l v e A l g o I I I Implementation //------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------BuildLinearSystem /*METHOD clLinearSolveAlgoIII */ /* Builds a linear program equivalent to the minimum cost tension problem of a graph. */ template <tdGraph> void clLinearSolveAlgoIII<tuGraph>::buildLinearSystem(clTensionSystem & agSystem, clGraph<tuGraph> & agGraph) const { method_name("linearSolveAlgoIII::buildLinearSystem");
typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_map(tyArcKey,linearSystem::tyVariableKey) clAssociation;
clArc<tuGraph> * lcArc; clAssociation lcAssociation; clTensionConstraint * lcBoundaryConstraint; clTensionVariable * lcPotentialVariable; clTensionVariable * lcShrinkVariable; linearSystem::tyVariableKey lcSourceKey; clTensionVariable * lcStretchVariable; linearSystem::tyVariableKey lcTargetKey; clTensionConstraint * lcTensionConstraint; tyReal lcTempo;
cpArcIterator lcCurrentArc = agGraph.arcs().begin(); cpArcIterator lcLastArc = agGraph.arcs().end(); tyMark lcMark = ++(agGraph.mark());
agSystem.objective().kind()=linearSystem::minimum;
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
// Potential Variables // if (lcArc->sourceNode()->mark()!=lcMark) { lcArc->sourceNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->sourceNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->sourceNode()->key(); lcSourceKey=lcPotentialVariable->key(); } else lcSourceKey=lcAssociation[lcArc->sourceNode()->key()];
if (lcArc->targetNode()->mark()!=lcMark) { lcArc->targetNode()->mark()=lcMark; lcPotentialVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcAssociation.insert(std_make_pair(lcArc->targetNode()->key(),lcPotentialVariable->key())); lcPotentialVariable->content().significance()=potential; lcPotentialVariable->content().node()=lcArc->targetNode()->key(); lcTargetKey=lcPotentialVariable->key(); } else lcTargetKey=lcAssociation[lcArc->targetNode()->key()];
// Tension Variables // lcShrinkVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey())); lcStretchVariable=new_object(clTensionVariable(agSystem,agSystem.getNewVariableKey()));
lcShrinkVariable->content().significance()=shrinking; lcShrinkVariable->content().arc()=lcArc->key(); lcStretchVariable->content().significance()=stretching; lcStretchVariable->content().arc()=lcArc->key();
if (lcArc->data().maximum()<0 or lcArc->data().minimum()<0 or lcArc->data().optimum()<0) send_error(erNegativeTension);
// Minimum // lcTempo=lcArc->data().optimum()-lcArc->data().minimum(); lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcBoundaryConstraint->boundary()=(lcTempo<0 ? 0 : lcTempo);
// Maximum // if (lcArc->data().maximum()!=lcArc->data().positiveInfinity()) { lcBoundaryConstraint=new_object(clTensionConstraint(agSystem,linearSystem::inferiority)); lcBoundaryConstraint->setCoefficient(lcStretchVariable->key(),+1.0); lcTempo=lcArc->data().maximum()-lcArc->data().optimum(); lcBoundaryConstraint->boundary()=(lcTempo<0 ? 0 : lcTempo); }
// Tension Constraint // lcTensionConstraint=new_object(clTensionConstraint(agSystem,linearSystem::equality)); lcTensionConstraint->setCoefficient(lcTargetKey,+1.0); lcTensionConstraint->setCoefficient(lcSourceKey,-1.0); lcTensionConstraint->setCoefficient(lcShrinkVariable->key(),+1.0); lcTensionConstraint->setCoefficient(lcStretchVariable->key(),-1.0); lcTensionConstraint->boundary()=lcArc->data().optimum();
// Objective // agSystem.objective().setCoefficient(lcShrinkVariable->key(),lcArc->data().shrinkingCost()); agSystem.objective().setCoefficient(lcStretchVariable->key(),lcArc->data().stretchingCost());
++lcCurrentArc; } } //----------------------------------------------------------------------------------------------Run /*METHOD clLinearSolveAlgoIII */ /* Solves the minimum cost tension problem of a graph using a given linear program solver. */ template <tdGraph> tyInteger clLinearSolveAlgoIII<tuGraph>::run(clGraph<tuGraph> & agGraph, ctTensionSystemSolver & agLinearSolver) const { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef clTensionSystem::cpVariableX::const_iterator clVariableIterator;
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; clVariableIterator lcCurrentVariable; cpArcIterator lcLastArc; clVariableIterator lcLastVariable; tyInteger lcNbIteration; clTensionSystem lcSystem;
// Linear System Resolution // buildLinearSystem(lcSystem,agGraph); lcNbIteration=agLinearSolver.run(lcSystem); agGraph.solved()=lcSystem.solved(); if (not lcSystem.solved()) return (-1);
// Potential Collecting // lcCurrentVariable=lcSystem.variables().begin(); lcLastVariable=lcSystem.variables().end();
while (lcCurrentVariable!=lcLastVariable) { if ((*lcCurrentVariable).second->content().significance()==potential) agGraph.node((*lcCurrentVariable).second->content().node()).data().potential()= (*lcCurrentVariable).second->value();
++lcCurrentVariable; }
// Tension Building // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
lcArc->data().tension()=lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential();
++lcCurrentArc; }
return (lcNbIteration); } }
// 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 // 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_tension/linear_system.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define GRAPH_PROBLEM_MIN_COST_TENSION_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_tension/linear_system.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostTensionLinearSystem #define private_area graphProblemMinCostTensionLinearSystem_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Graph_problem/Min_cost_tension/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 //------------------------------------------------------------------------------------------- } |
|