//================================================================================================== // G r a p h _ p r o b l e m Interface // M i n _ c o s t _ f l o w // 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 flow problems. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/min_cost_flow/random_generation.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guGraphProblemMinCostFlowRandomGeneration #define guGraphProblemMinCostFlowRandomGeneration
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/max_flow.hpp> /*INCLUDE*/ #include <bpp/graph_problem/min_cost_flow/structure.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef GRAPH_PROBLEM_MIN_COST_FLOW_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostFlowRandomGeneration #define private_area graphProblemMinCostFlowRandomGeneration_private
namespace public_area { /*NAMESPACE*/ using namespace graphProblemMinCostFlowStructure; } 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 {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { template <tdGraph> void generateLinearGraph(clGraph<tuGraph> &,tyCardinal,tyCardinal,tyInteger,tyCardinal,tyInteger); }
namespace private_area {}
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// X X X Interface //------------------------------------------------------------------------------ namespace {}
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// X X X Inline //--------------------------------------------------------------------------------- namespace {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------GenerateLinearGraph /*FUNCTION*/ /* Generates randomly a minimum cost flow problem with given flow scale and flexibility and a given unit cost scale, in a graph with given numbers of arcs and nodes (the unique source and target nodes, as well as the arcs that link them to the graph, are not counted, i.e. the numbers of arcs and nodes are a little more than given). The cost functions of the arcs are linear. */ template <tdGraph> void generateLinearGraph(clGraph<tuGraph> & agGraph,tyCardinal agNbNode, tyCardinal agNbArc,tyInteger agCapacityScale, tyCardinal agFlexibility,tyInteger agCostScale) { typedef std_vector(clNode<tuGraph> *) cpNodeS; typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;
tyInteger lcFlow; tyReal lcIncomingFlow; tyReal lcOutgoingFlow; tyMark lcMark;
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; cpNodeIterator lcCurrentNode; cpArcIterator lcLastArc; cpNodeIterator lcLastNode; tyReal lcMainFlow; clNode<tuGraph> * lcNode; cpNodeS lcNodeS; clGraph<tuGraph> lcTree;
// Graph Structure Generation // graphProblemMaxFlow::generateFlowGraph(agGraph,agNbNode,agNbArc,agCapacityScale);
// Pseudo-Flow Setting // findCoveringTree(agGraph,lcTree); lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcArc->data().flow()=randomCardinal(agCapacityScale+1); lcCurrentArc++; }
lcMainFlow=randomCardinal(agCapacityScale+1);
// Flow Finding // lcMark=++(lcTree.mark());
while (lcTree.arcs().size()!=0) { lcCurrentNode=lcTree.nodes().begin(); lcLastNode=lcTree.nodes().end();
while (lcCurrentNode!=lcLastNode) { lcNode=(*lcCurrentNode).second;
// Flow Setting On Direct Arc // if (lcNode->outgoingArcs().size()==0 and lcNode->incomingArcs().size()==1) { lcArc=(*(lcNode->incomingArcs().begin())).second;
if (lcArc->mark()!=lcMark) { lcArc->mark()=lcMark; lcNodeS.push_back(lcNode); lcArc=&(agGraph.arc(lcArc->key())); lcNode=&(agGraph.node(lcNode->key()));
lcIncomingFlow=0.0; lcCurrentArc=lcNode->incomingArcs().begin(); lcLastArc=lcNode->incomingArcs().end();
while (lcCurrentArc!=lcLastArc) { if ((*lcCurrentArc).first!=lcArc->key()) lcIncomingFlow+=(*lcCurrentArc).second->data().flow();
lcCurrentArc++; }
if (lcNode->outgoingArcs().size()==0) lcOutgoingFlow=lcMainFlow; else { lcOutgoingFlow=0.0; lcCurrentArc=lcNode->outgoingArcs().begin(); lcLastArc=lcNode->outgoingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcOutgoingFlow+=(*lcCurrentArc).second->data().flow(); lcCurrentArc++; } }
lcArc->data().flow()=lcOutgoingFlow-lcIncomingFlow; } }
// Flow Setting On Inverse Arc // else if (lcNode->incomingArcs().size()==0 and lcNode->outgoingArcs().size()==1) { lcArc=(*(lcNode->outgoingArcs().begin())).second;
if (lcArc->mark()!=lcMark) { lcArc->mark()=lcMark; lcNodeS.push_back(lcNode); lcArc=&(agGraph.arc(lcArc->key())); lcNode=&(agGraph.node(lcNode->key()));
if (lcNode->incomingArcs().size()==0) lcIncomingFlow=lcMainFlow; else { lcIncomingFlow=0.0; lcCurrentArc=lcNode->incomingArcs().begin(); lcLastArc=lcNode->incomingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcIncomingFlow+=(*lcCurrentArc).second->data().flow(); lcCurrentArc++; } }
lcOutgoingFlow=0.0; lcCurrentArc=lcNode->outgoingArcs().begin(); lcLastArc=lcNode->outgoingArcs().end();
while (lcCurrentArc!=lcLastArc) { if ((*lcCurrentArc).first!=lcArc->key()) lcOutgoingFlow+=(*lcCurrentArc).second->data().flow();
lcCurrentArc++; }
lcArc->data().flow()=lcIncomingFlow-lcOutgoingFlow; } }
lcCurrentNode++; }
// Destruction In Tree // while (lcNodeS.size()!=0) { lcNode=lcNodeS.back(); lcNodeS.pop_back();
if (lcNode->incomingArcs().size()!=0) lcArc=(*(lcNode->incomingArcs().begin())).second; else lcArc=(*(lcNode->outgoingArcs().begin())).second;
delete_object(lcArc); delete_object(lcNode); } }
// Capacity & Cost Setting // lcCurrentArc=agGraph.arcs().begin(); lcLastArc=agGraph.arcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcFlow=(tyInteger)(lcArc->data().flow()); if (lcFlow<0) lcFlow*=-1;
lcArc->data().minimum()=lcArc->data().flow() -tyReal(randomCardinal(percentage(lcFlow,agFlexibility)+1));
lcArc->data().maximum()=lcArc->data().flow() +tyReal(randomCardinal(percentage(lcFlow,agFlexibility)+1));
lcArc->data().unitCost()=(agCostScale==0 ? 1 : randomCardinal(agCostScale+1)); lcArc->data().flow()=0.0; lcCurrentArc++; }
agGraph.solved()=false; } }
// 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 _ f l o w // 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_flow/random_generation.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define GRAPH_PROBLEM_MIN_COST_FLOW_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/min_cost_flow/random_generation.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemMinCostFlowRandomGeneration #define private_area graphProblemMinCostFlowRandomGeneration_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Graph_problem/Min_cost_flow/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 //------------------------------------------------------------------------------------------- } |
|