//================================================================================================== // 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 // R a n d o m _ g e n e r a t i o n // 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 generate random minimum cost tension problems in graphs. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/min_cost_tension/random_generation.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guGraphProblemMinCostTensionRandomGeneration #define guGraphProblemMinCostTensionRandomGeneration
// Headers //--------------------------------------------------------------------------------------- #include <set> /*INCLUDE*/ #include <bpp/graph_problem/min_cost_tension/structure.hpp> /*INCLUDE*/ #include <bpp/graph_problem/serial_parallel.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 graphProblemMinCostTensionRandomGeneration #define private_area graphProblemMinCostTensionRandomGeneration_private
namespace public_area { /*NAMESPACE*/ using namespace graphProblemMinCostTensionStructure; /*NAMESPACE*/ using namespace graphProblemSerialParallel; }
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 {}
namespace private_area { template <tdGraph> class clRandomLinearCost; template <tdGraph> class clRandomConvexCost; template <tdGraph> class clRandomPiecewiseCost; template <tdGraph> class clMintyColorForCycleDetection; }
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { template <tdGraph> void generateConvexGraph1(clGraph<tuGraph> &,tyCardinal,tyCardinal, tyInteger,tyCardinal,tyInteger);
template <tdGraph> void generateConvexGraph2(clGraph<tuGraph> &,tyCardinal,tyCardinal, tyInteger,tyCardinal);
template <tdGraph> void generateDiscreteGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyInteger, tyCardinal,tyInteger);
template <tdGraph> void generateLinearGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyInteger, tyCardinal,tyInteger);
template <tdGraph> void generatePiecewiseGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyInteger, tyCardinal,tyInteger,tyCardinal);
template <tdGraph> void generateConvexSerialParallelGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyCardinal, tyInteger,tyCardinal,tyInteger, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * =nil);
template <tdGraph> void generateDiscreteSerialParallelGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyCardinal, tyInteger,tyCardinal,tyInteger);
template <tdGraph> void generateLinearSerialParallelGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyCardinal, tyInteger,tyCardinal,tyInteger, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * =nil);
template <tdGraph> void generatePiecewiseSerialParallelGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyCardinal, tyInteger,tyCardinal,tyInteger,tyCardinal, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * =nil); }
namespace private_area { template <tdGraph,class prRandomCost> void generateGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyInteger,tyCardinal,const prRandomCost &, tyBoolean=true);
template <tdGraph,class prRandomCost> void generateSerialParallelGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyCardinal,tyInteger, tyCardinal,const prRandomCost &, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) *, tyBoolean=true);
template <tdGraph> void generateDiscreteGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal, tyInteger,tyCardinal,tyInteger,tyBoolean,tyCardinal); }
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// R a n d o m L i n e a r C o s t Interface //---------------------------------------------------- namespace private_area { template <tdGraph> class clRandomLinearCost { //-----------------------------------------------------------------------------------------Private private_property clRandomLinearCost(const clRandomLinearCost &); private_property clRandomLinearCost & operator = (const clRandomLinearCost &);
private_property tyInteger atScale; //------------------------------------------------------------------------------------------Public public_property constructor clRandomLinearCost(tyInteger agScale) : atScale(agScale+1) {} public_property destructor clRandomLinearCost(void) {}
public_property void run(clArc<tuGraph> & agArc) const { agArc.data().shrinkingCost()=(atScale==1 ? 1 : randomCardinal(atScale)); agArc.data().stretchingCost()=(atScale==1 ? 1 : randomCardinal(atScale)); } }; }
// R a n d o m C o n v e x C o s t Interface //---------------------------------------------------- namespace private_area { template <tdGraph> class clRandomConvexCost { //-----------------------------------------------------------------------------------------Private private_property clRandomConvexCost(const clRandomConvexCost &); private_property clRandomConvexCost & operator = (const clRandomConvexCost &);
private_property tyInteger atScale; //------------------------------------------------------------------------------------------Public public_property constructor clRandomConvexCost(tyInteger agScale) : atScale(agScale+1) {} public_property destructor clRandomConvexCost(void) {}
public_property void run(clArc<tuGraph> & agArc) const { agArc.data().costAcceleration()=(atScale==1 ? 1 : randomCardinal(atScale)); } }; }
// R a n d o m P i e c e w i s e C o s t Interface //---------------------------------------------- namespace private_area { template <tdGraph> class clRandomPiecewiseCost { //-----------------------------------------------------------------------------------------Private private_property clRandomPiecewiseCost(const clRandomPiecewiseCost &); private_property clRandomPiecewiseCost & operator = (const clRandomPiecewiseCost &);
private_property tyInteger atScale; private_property tyCardinal atNbPiece; //------------------------------------------------------------------------------------------Public public_property constructor clRandomPiecewiseCost(tyInteger agScale,tyCardinal agNbPiece) : atScale(agScale/agNbPiece+1),atNbPiece(agNbPiece) {}
public_property destructor clRandomPiecewiseCost(void) {}
public_property void run(clArc<tuGraph> &) const; }; }
// M i n t y C o l o r F o r C y c l e D e t e c t i o n Interface //------------------------------ namespace private_area { template <tdGraph> class clMintyColorForCycleDetection { //-------------------------------------------------------------------------------------------Types public_property typedef clArc<tuGraph> cpArc; //-----------------------------------------------------------------------------------------Private private_property constructor clMintyColorForCycleDetection(const clMintyColorForCycleDetection &);
private_property clMintyColorForCycleDetection & operator = (const clMintyColorForCycleDetection &); //------------------------------------------------------------------------------------------Public read_only_attribute(tyCardinal,atCardinalityMax,cardinality);
public_property constructor clMintyColorForCycleDetection(tyCardinal); public_property destructor clMintyColorForCycleDetection(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;
public_property tcString color(const cpArc &) const; }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area { //-----------------------------------------------------------------------------GenerateConvexGraph1 /*FUNCTION*/ /* Generates randomly a minimum cost tension problem with given potential scale and flexibility and a given cost acceleration scale, in a graph with given numbers of arcs and nodes. The cost functions of the arcs are as defined by the <CODE>clConvexArcData1</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> inline void generateConvexGraph1(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agFlexibility, tyInteger agAccelerationScale) { private_area::clRandomConvexCost<tuGraph> lcCost(agAccelerationScale);
private_area::generateGraph(agGraph,agNbNode,agNbArc,agPotentialScale,agFlexibility,lcCost); } //----------------------------------------------------------------------------GenerateDiscreteGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem with a given potential scale, a given cardinality for the feasible tension sets and a given unit cost scale, in a graph with given numbers of arcs and nodes. The cost functions of the arcs are as defined by the <CODE>clDiscreteArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> inline void generateDiscreteGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agTensionCardinality, tyInteger agUnitCostScale) { private_area::generateDiscreteGraph(agGraph,agNbNode,agNbArc,agPotentialScale, agTensionCardinality,agUnitCostScale,false,0); } //------------------------------------------------------------------------------GenerateLinearGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem with given potential scale and flexibility and a given unit cost scale, in a graph with given numbers of arcs and nodes. The cost functions of the arcs are as defined by the <CODE>clLinearArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> inline void generateLinearGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agFlexibility, tyInteger agUnitCostScale) { private_area::clRandomLinearCost<tuGraph> lcCost(agUnitCostScale);
private_area::generateGraph(agGraph,agNbNode,agNbArc,agPotentialScale,agFlexibility,lcCost); } //---------------------------------------------------------------------------GeneratePiecewiseGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem with given potential scale and flexibility and a given unit cost scale, in a graph with given numbers of arcs and nodes. The cost functions of the arcs are piecewise linear as defined by the <CODE>clPiecewiseArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> inline void generatePiecewiseGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agFlexibility, tyInteger agUnitCostScale,tyCardinal agNbPiece) { private_area::clRandomPiecewiseCost<tuGraph> lcCost(agUnitCostScale,agNbPiece);
private_area::generateGraph(agGraph,agNbNode,agNbArc,agPotentialScale,agFlexibility,lcCost); } //----------------------------------------------------------------GenerateConvexSerialParallelGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem (with a serial-parallel graph that can be disrupted) with given potential scale and flexibility and a given cost acceleration scale, in a graph with given numbers of arcs (number for the organized serial-parallel graph and number for the disruption) and nodes. The cost functions of the arcs are as defined by the <CODE>clConvexArcData1</CODE> class of the <CODE>Structure</CODE> module. If not null, the last parameter is a pointer to a vector of SP-components representing the generated graph, that is filled during the generation process. The last parameter is null by default. */ template <tdGraph> inline void generateConvexSerialParallelGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode, tyCardinal agNbOrganizingArc,tyCardinal agNbDisruptingArc, tyInteger agPotentialScale,tyCardinal agFlexibility, tyInteger agAcceleration, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * agTreeS) { private_area::clRandomConvexCost<tuGraph> lcCost(agAcceleration);
private_area::generateSerialParallelGraph(agGraph,agNbNode,agNbOrganizingArc, agNbDisruptingArc,agPotentialScale,agFlexibility, lcCost,agTreeS); } //--------------------------------------------------------------GenerateDiscreteSerialParallelGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem (with a serial-parallel graph that can be disrupted) with a given potential scale, a given cardinality for the feasible tension sets and a given unit cost scale, in a graph with given numbers of arcs (number for the organized serial-parallel graph and number for the disruption) and nodes. The cost functions of the arcs are as defined by the <CODE>clDiscreteArcData</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> inline void generateDiscreteSerialParallelGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode, tyCardinal agNbOrganizingArc,tyCardinal agNbDisruptingArc, tyInteger agPotentialScale,tyCardinal agTensionCardinality, tyInteger agUnitCostScale) { private_area::generateDiscreteGraph(agGraph,agNbNode,agNbOrganizingArc,agPotentialScale, agTensionCardinality,agUnitCostScale,true, agNbDisruptingArc); } //----------------------------------------------------------------GenerateLinearSerialParallelGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem (with a serial-parallel graph that can be disrupted) with given potential scale and flexibility and a given unit cost scale, in a graph with given numbers of arcs (number for the organized serial-parallel graph and number for the disruption) and nodes. The cost functions of the arcs are as defined by the <CODE>clLinearArcData</CODE> class of the <CODE>Structure</CODE> module. If not null, the last parameter is a pointer to a vector of SP-components representing the generated graph, that is filled during the generation process. The last parameter is null by default. */ template <tdGraph> inline void generateLinearSerialParallelGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode, tyCardinal agNbOrganizingArc,tyCardinal agNbDisruptingArc, tyInteger agPotentialScale,tyCardinal agFlexibility, tyInteger agUnitCostScale, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * agTreeS) { private_area::clRandomLinearCost<tuGraph> lcCost(agUnitCostScale);
private_area::generateSerialParallelGraph(agGraph,agNbNode,agNbOrganizingArc, agNbDisruptingArc,agPotentialScale,agFlexibility, lcCost,agTreeS); } //-------------------------------------------------------------GeneratePiecewiseSerialParallelGraph /*FUNCTION*/ /* Generates randomly a minimum cost tension problem (with a serial-parallel graph that can be disrupted) with given potential scale and flexibility and a given unit cost scale, in a graph with given numbers of arcs (number for the organized serial-parallel graph and number for the disruption) and nodes. The cost functions of the arcs are piecewise linear as defined by the <CODE>clLinearArcData</CODE> class of the <CODE>Structure</CODE> module. If not null, the last parameter is a pointer to a vector of SP-components representing the generated graph, that is filled during the generation process. The last parameter is null by default. */ template <tdGraph> inline void generatePiecewiseSerialParallelGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode, tyCardinal agNbOrganizingArc, tyCardinal agNbDisruptingArc,tyInteger agPotentialScale, tyCardinal agFlexibility,tyInteger agUnitCostScale, tyCardinal agNbPiece, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * agTreeS) { private_area::clRandomPiecewiseCost<tuGraph> lcCost(agUnitCostScale,agNbPiece);
private_area::generateSerialParallelGraph(agGraph,agNbNode,agNbOrganizingArc, agNbDisruptingArc,agPotentialScale,agFlexibility, lcCost,agTreeS); } }
namespace private_area {}
// M i n t y C o l o r F o r C y c l e D e t e c t i o n Inline //--------------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor template <tdGraph> inline clMintyColorForCycleDetection<tuGraph>::clMintyColorForCycleDetection(tyCardinal agCardinalityMax) : atCardinalityMax(agCardinalityMax) {} //----------------------------------------------------------------------------------------------Red template <tdGraph> inline tyBoolean clMintyColorForCycleDetection<tuGraph>::red(const cpArc & agArc) const { return (agArc.data().feasibles().size()<atCardinalityMax); } //--------------------------------------------------------------------------------------------Black template <tdGraph> inline tyBoolean clMintyColorForCycleDetection<tuGraph>::black(const cpArc &) const { return (false); } //---------------------------------------------------------------------------------------------Blue template <tdGraph> inline tyBoolean clMintyColorForCycleDetection<tuGraph>::blue(const cpArc &) const { return (false); } //--------------------------------------------------------------------------------------------Green template <tdGraph> inline tyBoolean clMintyColorForCycleDetection<tuGraph>::green(const cpArc & agArc) const { return (agArc.data().feasibles().size()>=atCardinalityMax); } }
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //-----------------------------------------------------------------------------GenerateConvexGraph2 /*FUNCTION*/ /* Generates randomly a minimum cost tension problem with given potential scale and flexibility, in a graph with given numbers of arcs and nodes. The cost functions of the arcs are as defined by the <CODE>clConvexArcData2</CODE> class of the <CODE>Structure</CODE> module. */ template <tdGraph> void generateConvexGraph2(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agFlexibility) { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; cpNodeIterator lcCurrentNode; cpArcIterator lcLastArc; cpNodeIterator lcLastNode; clNode<tuGraph> * lcNode; clNode<tuGraph> * lcTempoNode;
tyInteger lcTension; tyReal lcOptimum; tyInteger lcMaximum; tyInteger lcMinimum;
// Structure Generation // generateConnexGraph(agGraph,agNbNode,agNbArc,false);
// Potential Generation // lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=randomCardinal(agPotentialScale+1); lcCurrentNode++; }
// Arc Tension Generation // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcTension=tyInteger(lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential());
if (lcTension<0) { lcTempoNode=lcArc->sourceNode(); lcArc->setSourceNode(lcArc->targetNode()); lcArc->setTargetNode(lcTempoNode); lcTension*=-1; }
lcMinimum=lcTension-randomCardinal(percentage(lcTension,agFlexibility)+1); lcMaximum=lcTension+randomCardinal(percentage(lcTension,agFlexibility)+1); lcOptimum=tyReal(lcMaximum+lcMinimum)/2.0;
lcArc->data().optimum()=lcOptimum; lcArc->data().tolerance()=lcOptimum-lcMinimum; lcArc->data().expected()=0.0; lcCurrentArc++; }
// Potential Cleaning // lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=0.0; lcCurrentNode++; } } }
namespace private_area { //------------------------------------------------------------------------------------GenerateGraph template <tdGraph,class prRandomCost> void generateGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agFlexibility, const prRandomCost & agRandomCost,tyBoolean agClean) { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; cpNodeIterator lcCurrentNode; cpArcIterator lcLastArc; cpNodeIterator lcLastNode; clNode<tuGraph> * lcNode; clNode<tuGraph> * lcTempoNode;
tyInteger lcTension; tyInteger lcOptimum; tyInteger lcMaximum; tyInteger lcMinimum;
// Structure Generation // generateConnexGraph(agGraph,agNbNode,agNbArc,false);
// Potential Generation // lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=randomCardinal(agPotentialScale+1); lcCurrentNode++; }
// Arc Tension Generation // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
lcTension=tyInteger(lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential());
if (lcTension<0) { lcTempoNode=lcArc->sourceNode(); lcArc->setSourceNode(lcArc->targetNode()); lcArc->setTargetNode(lcTempoNode); lcTension*=-1; }
lcMinimum=lcTension-randomCardinal(percentage(lcTension,agFlexibility)+1); lcMaximum=lcTension+randomCardinal(percentage(lcTension,agFlexibility)+1); lcOptimum=lcMinimum+randomCardinal(lcMaximum-lcMinimum+1);
lcArc->data().minimum()=lcMinimum; lcArc->data().maximum()=lcMaximum; lcArc->data().optimum()=lcOptimum; lcArc->data().expected()=0.0; agRandomCost.run(*lcArc);
lcCurrentArc++; }
// Potential Cleaning // if (agClean) { lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=0.0; lcCurrentNode++; } } } //----------------------------------------------------------------------GenerateSerialParallelGraph template <tdGraph,class prRandomCost> void generateSerialParallelGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode, tyCardinal agNbOrganizingArc,tyCardinal agNbDisruptingArc, tyInteger agPotentialScale,tyCardinal agFlexibility, const prRandomCost & agRandomCost, std_vector(clBinaryTree<clSerialParallelData<tuGraph> > *) * agTreeS, tyBoolean agClean) { typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator; typedef clSerialParallelData<tuGraph> cpSerialParallelData; typedef clBinaryTree<cpSerialParallelData > cpTree;
typedef typename clGraph<tuGraph>::cpArc cpArc; typedef typename clGraph<tuGraph>::cpNode cpNode;
typedef std_set(cpNode *) cpNodeS; typedef std_set(tyInteger) clPotentialS;
cpNodeS * lcNextNodeS = new_object(cpNodeS); cpNodeS * lcNextNodeS2 = new_object(cpNodeS);
cpArc * lcArc; cpArcIterator lcCurrentArc; cpNodeIterator lcCurrentNode; cpArcIterator lcLastArc; cpNodeIterator lcLastNode; cpNode * lcNode; std_vector(tyNodeKey) lcNodeS; tyNodeKey lcNodeKey1; tyNodeKey lcNodeKey2; clPotentialS lcPotentialS;
tyInteger lcTension; tyInteger lcOptimum; tyInteger lcPotential; tyInteger lcMaximum; tyInteger lcMinimum;
clPotentialS::const_iterator lcCurrentPotential;
// Structure Generation // graphRandomGeneration_private::generateSerialParallelGraph(agGraph,agNbNode, agNbOrganizingArc,lcNodeS);
if (agTreeS!=nil) graphProblemSerialParallel::clDecomposeAlgo<tuGraph>::defaultRun(agGraph,*agTreeS);
// Potentials Generation // while (lcPotentialS.size()!=agNbNode) { lcPotential=randomCardinal(maxi(tyCardinal(agPotentialScale),agNbNode)+1); if (lcPotentialS.count(lcPotential)==0) lcPotentialS.insert(lcPotential); }
lcCurrentPotential=lcPotentialS.begin();
// Node Potential Cleaning // lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=0.0;
if (lcNode->incomingArcs().size()==0) { lcNextNodeS->insert(lcNode); lcNode->data().potential()=*lcCurrentPotential; lcCurrentPotential++; }
lcCurrentNode++; }
// Potential Affectation // { typedef typename cpNodeS::const_iterator cpNodeIterator;
cpNodeIterator lcCurrentNode; cpNodeIterator lcLastNode; cpNodeS * lcTempoSet;
while (lcNextNodeS->size()>0) { lcCurrentNode=lcNextNodeS->begin(); lcLastNode=lcNextNodeS->end();
while (lcCurrentNode!=lcLastNode) { lcCurrentArc=(*lcCurrentNode)->outgoingArcs().begin(); lcLastArc=(*lcCurrentNode)->outgoingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcNode=(*lcCurrentArc).second->targetNode(); lcNode->data().potential()++;
if (lcNode->data().potential()==lcNode->incomingArcs().size()) { lcNextNodeS2->insert(lcNode); lcNode->data().potential()=*lcCurrentPotential; lcCurrentPotential++; }
lcCurrentArc++; }
lcCurrentNode++; }
lcNextNodeS->erase(lcNextNodeS->begin(),lcNextNodeS->end()); lcTempoSet=lcNextNodeS; lcNextNodeS=lcNextNodeS2; lcNextNodeS2=lcTempoSet; } }
// Arc Tension Generation // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second;
lcTension=tyInteger(lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential());
lcMinimum=lcTension-randomCardinal(percentage(lcTension,agFlexibility)+1); lcMaximum=lcTension+randomCardinal(percentage(lcTension,agFlexibility)+1); lcOptimum=lcMinimum+randomCardinal(lcMaximum-lcMinimum+1);
lcArc->data().minimum()=lcMinimum; lcArc->data().maximum()=lcMaximum; lcArc->data().optimum()=lcOptimum; lcArc->data().expected()=0.0; agRandomCost.run(*lcArc);
lcCurrentArc++; }
// Disrupting Arcs Generation // while (agNbDisruptingArc>0) { lcNodeKey1=lcNodeS[randomCardinal(agNbNode)];
do { lcNodeKey2=lcNodeS[randomCardinal(agNbNode)]; } while (lcNodeKey2==lcNodeKey1);
if (agGraph.node(lcNodeKey1).data().potential()>agGraph.node(lcNodeKey2).data().potential()) standard::swap(lcNodeKey1,lcNodeKey2);
lcArc=new_object(cpArc(agGraph,agGraph.getNewArcKey(),prArcData(),lcNodeKey1,lcNodeKey2));
lcTension=tyInteger(lcArc->targetNode()->data().potential() -lcArc->sourceNode()->data().potential());
lcMinimum=lcTension-randomCardinal(percentage(lcTension,agFlexibility)+1); lcMaximum=lcTension+randomCardinal(percentage(lcTension,agFlexibility)+1); lcOptimum=lcMinimum+randomCardinal(lcMaximum-lcMinimum+1);
lcArc->data().minimum()=lcMinimum; lcArc->data().maximum()=lcMaximum; lcArc->data().optimum()=lcOptimum; lcArc->data().expected()=0.0; agRandomCost.run(*lcArc);
if (agTreeS!=nil) agTreeS->push_back(new_object(cpTree(cpSerialParallelData(lcArc,cpSerialParallelData::none), nil,nil)));
agNbDisruptingArc--; }
// Potential Cleaning // if (agClean) { lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=0.0; lcCurrentNode++; } }
// End // lcPotentialS.erase(lcPotentialS.begin(),lcPotentialS.end()); delete_object(lcNextNodeS); delete_object(lcNextNodeS2); } //----------------------------------------------------------------------------GenerateDiscreteGraph template <tdGraph> void generateDiscreteGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode,tyCardinal agNbArc, tyInteger agPotentialScale,tyCardinal agTensionCardinality, tyInteger agUnitCostScale,tyBoolean agSerialParallel, tyCardinal agNbDisruptingArc) { typedef clArc<tuGraph> cpArc; typedef clGraph<tuGraph> cpGraph; typedef clNode<tuGraph> cpNode; typedef std_map(cpArc *,tyInteger) cpCycle; typedef typename cpCycle::difference_type cpDistance; typedef std_vector(cpArc *) cpSet; typedef std_vector(cpSet) cpSetS; typedef typename cpGraph::cpArcX::const_iterator cpArcIterator1; typedef typename cpNode::cpArcX::const_iterator cpArcIterator2; typedef typename cpCycle::const_iterator cpArcIterator3; typedef typename cpGraph::cpNodeX::const_iterator cpNodeIterator; typedef private_area::clMintyColorForCycleDetection<tuGraph> cpMintyTest; typedef clRandomLinearCost<tuGraph> cpRandomCost;
cpArc * lcArc1; cpArc * lcArc2; cpSet lcArcS; cpCycle lcCocycle; cpArcIterator1 lcCurrentArc1; cpArcIterator2 lcCurrentArc2; cpArcIterator3 lcCurrentArc3; cpNodeIterator lcCurrentNode; cpCycle lcCycle; cpGraph lcGraph; cpArcIterator1 lcLastArc1; cpArcIterator2 lcLastArc2; cpNodeIterator lcLastNode; cpNode * lcNode; cpSetS lcSetS;
tyCardinal lcArcCounter; tyCardinal lcCardinality; tyCardinal lcCounter; tyInteger lcDecreaseMax; tyInteger lcIncreaseMax; tyCardinal lcSize; tyInteger lcTension; tyBoolean lcValid;
cpMintyTest lcMintyTest(agTensionCardinality); cpRandomCost lcRandomCost(agUnitCostScale);
// Structure Generation // if (agSerialParallel) generateSerialParallelGraph<tuGraph,cpRandomCost>(agGraph,agNbNode,agNbArc,agNbDisruptingArc, agPotentialScale,0,lcRandomCost,nil,false); else generateGraph(agGraph,agNbNode,agNbArc,agPotentialScale,0,lcRandomCost,false);
// Arc Tension Generation // lcSetS.push_back(cpSet()); lcCurrentArc1=agGraph.arcs().begin(); lcLastArc1=agGraph.arcs().end();
while (lcCurrentArc1!=lcLastArc1) { lcArc1=(*lcCurrentArc1).second;
lcTension=tyInteger(lcArc1->targetNode()->data().potential() -lcArc1->sourceNode()->data().potential());
lcArc1->data().addFeasible(lcTension); lcArc1->data().expected()=lcTension; ++lcCurrentArc1; }
// Feasible Sets Generation // lcArcCounter=agGraph.arcs().size();
while (lcArcCounter>0) { lcGraph=agGraph;
// Blocking Arcs Removing // do { lcArc1=nil; lcCurrentArc1=lcGraph.arcs().begin(); lcLastArc1=lcGraph.arcs().end();
while (lcCurrentArc1!=lcLastArc1 and lcArc1==nil) { if (findMintyCycle(*((*lcCurrentArc1).second),lcMintyTest,lcCycle,lcCocycle)) { lcCurrentArc3=lcCycle.begin(); std_advance(lcCurrentArc3,cpDistance(randomCardinal(lcCycle.size()))); lcArc1=(*lcCurrentArc3).first; }
++lcCurrentArc1; }
if (lcArc1!=nil) { lcArcS.push_back(&(agGraph.arc(lcArc1->key()))); delete_object(lcArc1); } } while (lcArc1!=nil);
// Cardinality Sets Building // lcSetS.erase(lcSetS.begin(),lcSetS.end()); lcCurrentArc1=lcGraph.arcs().begin(); lcLastArc1=lcGraph.arcs().end();
while (lcCurrentArc1!=lcLastArc1) { lcArc1=(*lcCurrentArc1).second; lcCardinality=lcArc1->data().feasibles().size(); while (lcSetS.size()<=lcCardinality) lcSetS.push_back(cpSet()); lcSetS[lcCardinality].push_back(lcArc1); ++lcCurrentArc1; }
// Blocking Arcs Reinsertion // lcCounter=0; while (lcCounter<lcSetS.size()-1 and lcSetS[lcCounter].size()==0) ++lcCounter;
while (lcArcS.size()>0) { lcArc1=lcArcS.back(); lcArc2=new_object(cpArc(lcGraph,*lcArc1)); lcArcS.pop_back(); lcSetS[lcCounter].push_back(lcArc2); }
// Cocycle Building // while (lcGraph.nodes().size()>2) { while (lcSetS.back().size()==0) lcSetS.pop_back(); lcCounter=randomCardinal(lcSetS.back().size()); lcArc1=lcSetS.back()[lcCounter]; lcSetS.back()[lcCounter]=lcSetS.back().back(); lcSetS.back().pop_back();
if (lcArc1->sourceNode()==nil or lcArc1->targetNode()==nil) delete_object(lcArc1); else { lcCurrentArc2=lcArc1->sourceNode()->outgoingArcs().begin(); lcLastArc2=lcArc1->sourceNode()->outgoingArcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc2=(*lcCurrentArc2).second; if (lcArc2->targetNode()==lcArc1->targetNode() and lcArc2!=lcArc1) lcArcS.push_back(lcArc2); ++lcCurrentArc2; }
lcCurrentArc2=lcArc1->sourceNode()->incomingArcs().begin(); lcLastArc2=lcArc1->sourceNode()->incomingArcs().end();
while (lcCurrentArc2!=lcLastArc2) { lcArc2=(*lcCurrentArc2).second; if (lcArc2->sourceNode()==lcArc1->targetNode()) lcArcS.push_back(lcArc2); ++lcCurrentArc2; }
while (lcArcS.size()>0) { lcArcS.back()->setSourceNode(nil); lcArcS.back()->setTargetNode(nil); lcArcS.pop_back(); }
lcGraph.mergeNodes(*(lcArc1->sourceNode()),*(lcArc1->targetNode())); } }
// Maximum Decrease and Increase Computation // lcValid=false; lcIncreaseMax=integerMax(); lcDecreaseMax=integerMax(); lcCurrentArc1=lcGraph.arcs().begin(); lcLastArc1=lcGraph.arcs().end();
while (lcCurrentArc1!=lcLastArc1) { lcArc1=(*lcCurrentArc1).second;
if (lcArc1->sourceNode()!=nil and lcArc1->targetNode()!=nil) { lcTension=tyInteger(lcArc1->data().expected()); if (lcTension<lcDecreaseMax) lcDecreaseMax=lcTension; lcTension=agPotentialScale-lcTension; if (lcTension<lcIncreaseMax) lcIncreaseMax=lcTension; if (lcArc1->data().feasibles().size()<agTensionCardinality) lcValid=true; lcArcS.push_back(&(agGraph.arc(lcArc1->key()))); }
++lcCurrentArc1; }
// Cocycle Tension Change // if (lcValid) { lcTension=randomCardinal(lcDecreaseMax+lcIncreaseMax)+1; lcCounter=lcArcS.size();
if (lcTension<=lcDecreaseMax) { while (lcCounter>0) { --lcCounter; lcArc1=lcArcS[lcCounter]; lcArc1->data().expected()-=lcTension; lcSize=lcArc1->data().feasibles().size(); lcArc1->data().addFeasible(lcArc1->data().expected()); if (lcArc1->data().feasibles().size()==agTensionCardinality and lcSize<agTensionCardinality) --lcArcCounter; } } else { lcTension-=lcDecreaseMax;
while (lcCounter>0) { --lcCounter; lcArc1=lcArcS[lcCounter]; lcArc1->data().expected()+=lcTension; lcSize=lcArc1->data().feasibles().size(); lcArc1->data().addFeasible(lcArc1->data().expected()); if (lcArc1->data().feasibles().size()==agTensionCardinality and lcSize<agTensionCardinality) --lcArcCounter; } } }
lcArcS.erase(lcArcS.begin(),lcArcS.end()); }
// Arc Optimum Tension // lcCurrentArc1=agGraph.arcs().begin(); lcLastArc1=agGraph.arcs().end();
while (lcCurrentArc1!=lcLastArc1) { lcArc1=(*lcCurrentArc1).second; lcCardinality=lcArc1->data().feasibles().size(); lcArc1->data().optimum()=lcArc1->data().feasibles()[randomCardinal(lcCardinality)]; lcArc1->data().expected()=0.0; ++lcCurrentArc1; }
// Potential Cleaning // lcCurrentNode=agGraph.nodes().begin(); lcLastNode=agGraph.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second; lcNode->data().potential()=0.0; lcCurrentNode++; } } }
// R a n d o m P i e c e w i s e C o s t Implementation //----------------------------------------- namespace private_area { template <tdGraph> void clRandomPiecewiseCost<tuGraph>::run(clArc<tuGraph> & agArc) const { tyReal lcLength; tyInteger lcScale;
tyCardinal lcCounter = atNbPiece; tyReal lcMaximum = agArc.data().maximum()-agArc.data().optimum(); tyReal lcMinimum = agArc.data().optimum()-agArc.data().minimum(); tyReal lcStretchingCost = 0.0; tyReal lcShrinkingCost = 0.0;
agArc.data().expected()=agArc.data().optimum(); if (agArc.data().needUpdate()) agArc.data().update();
while (lcCounter>0) { lcScale=tyInteger(lcMaximum/lcCounter);
if (lcScale>0) { lcLength=(lcCounter==1 ? lcMaximum : randomCardinal(lcScale)+1); lcStretchingCost+=randomCardinal(atScale); lcMaximum-=lcLength; agArc.data().stretchingCosts().push_back(standard::make_pair(lcLength,lcStretchingCost)); }
lcScale=tyInteger(lcMinimum/lcCounter);
if (lcScale>0) { lcLength=(lcCounter==1 ? lcMinimum : randomCardinal(lcScale)+1); lcShrinkingCost+=randomCardinal(atScale); lcMinimum-=lcLength; agArc.data().shrinkingCosts().push_back(standard::make_pair(lcLength,lcShrinkingCost)); }
--lcCounter; }
std_reverse(agArc.data().shrinkingCosts().begin(),agArc.data().shrinkingCosts().end()); std_reverse(agArc.data().stretchingCosts().begin(),agArc.data().stretchingCosts().end()); } }
// 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 // R a n d o m _ g e n e r a t i o n // 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/random_generation.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define GRAPH_PROBLEM_MIN_COST_TENSION_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_tension/random_generation.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostTensionRandomGeneration #define private_area graphProblemMinCostTensionRandomGeneration_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Graph_problem/Min_cost_tension/Random_generation");
// 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 //------------------------------------------------------------------------------------------- } |
|