From 10d7c42468a6d1b9c251d7ce4aac9c2ec04e9028 Mon Sep 17 00:00:00 2001 From: Arnaud Malapert Date: Sat, 9 Jun 2012 00:39:18 +0200 Subject: [PATCH] add graph decorations #18 --- benchmarks/instances/sample-server.dat | 2 +- src/constraint_generation.c | 2 +- src/cplex_solver.h | 2 +- src/cudf.c | 6 +- src/graphviz.cpp | 83 ++++++++++++++++++++++++-- src/network.cpp | 3 +- src/network.hpp | 2 - 7 files changed, 85 insertions(+), 15 deletions(-) diff --git a/benchmarks/instances/sample-server.dat b/benchmarks/instances/sample-server.dat index 0e2d15c..db962db 100644 --- a/benchmarks/instances/sample-server.dat +++ b/benchmarks/instances/sample-server.dat @@ -1,5 +1,5 @@ 4 -2 20 100 1000 +2000 20000 100000 1000000 1 500 1 1 diff --git a/src/constraint_generation.c b/src/constraint_generation.c index 989b818..08397c9 100644 --- a/src/constraint_generation.c +++ b/src/constraint_generation.c @@ -6,7 +6,7 @@ int new_var = 0; -CUDFcoefficient min_bandwidth = 0; //TODO set min_bandwidth to 1Ko +CUDFcoefficient min_bandwidth = 1; //set min_bandwidth to 1Ko struct SetPathCoeff { diff --git a/src/cplex_solver.h b/src/cplex_solver.h index ba93f2d..1e7b9f1 100644 --- a/src/cplex_solver.h +++ b/src/cplex_solver.h @@ -90,7 +90,7 @@ class cplex_solver: public abstract_solver, public scoeff_solver { int first_objective; double *cplex_coeff; // cplex coefficients are doubles ... - //TODO pourquoi des double et pas des CUDFcoefficient ? Pour cplex ... + //pourquoi des double et pas des CUDFcoefficient ? toujours pour cplex ... double *lb; // array of lower bounds double *ub; // array of upper bounds char *vartype; // array of variable types diff --git a/src/cudf.c b/src/cudf.c index bc44ef7..0047edf 100644 --- a/src/cudf.c +++ b/src/cudf.c @@ -782,7 +782,7 @@ int main(int argc, char *argv[]) { PSLProblem* current_problem = NULL; PSLProblem* the_problem = NULL; -int verbosity = 5; //TODO initialize verbosity +int verbosity = 5; int parse_pslp(istream& in) { @@ -791,8 +791,8 @@ int parse_pslp(istream& in) in >> *the_problem; //TODO add option for the_problem->setSeed(seed); //TODO add option for hierarchical network - bool hierarchical=true; - the_problem->generateNetwork(hierarchical); + bool hierarchic=true; + the_problem->generateNetwork(hierarchic); return 0; } diff --git a/src/graphviz.cpp b/src/graphviz.cpp index 1ee1732..2f11afb 100644 --- a/src/graphviz.cpp +++ b/src/graphviz.cpp @@ -30,6 +30,19 @@ #include "graphviz.hpp" +void stylePServers(ostream & out, const int servers) { + switch (servers) { + case 0: out << ",style=dashed"; break; + case 1:break; + case 2: out << ",style=filled,fillcolor=lightgoldenrod";break; + case 3: out << ",style=filled,fillcolor=palegreen";break; + case 4: out << ",style=filled,fillcolor=lightseagreen";break; + default: + out << ",style=filled,fillcolor=salmon";break; + break; + } +} + void node2dotty(ostream & out, FacilityNode* i,PSLProblem & problem, abstract_solver & solver, unsigned int stage) { CUDFcoefficient demand = stage == 0 ? solver.get_solution(problem.rankX(i)) : i->getType()->getDemand(stage-1); @@ -43,12 +56,28 @@ void node2dotty(ostream & out, FacilityNode* i,PSLProblem & problem, abstract_so out << "{" << demand << "|" << servers << "|" << connections << "}"; } out << "}\""; - if(connections > 0) { - out << ",style=filled"; - } + stylePServers(out, servers); out << "];" << endl; } +void colorConnection(ostream & out, const int connections) { + if(connections >= 50) { + if(connections >= 1000) { + out << ",color=firebrick"; + } else if(connections >= 500) { + out << ",color=salmon"; + } else if(connections >= 250) { + + out << ",color=midnightblue"; + //out << ",color=seagreen"; + }else if(connections >= 100) { + out << ",color=seagreen"; + } else { + out << ",color=darkgoldenrod"; + } + } +} + void flow2dotty(ostream & out, PSLProblem & problem, abstract_solver & solver, unsigned int stage) { for(NodeIterator i = problem.nbegin() ; i!= problem.nend() ; i++) { @@ -58,7 +87,12 @@ void flow2dotty(ostream & out, PSLProblem & problem, abstract_solver & solver, u CUDFcoefficient connections = solver.get_solution(problem.rankY(*l, stage)); out << l->getOrigin()->getID() << " -> " << l->getDestination()->getID(); if(connections > 0) { - out << "[label=\"" << connections << "\"];\n"; + out << "[label=\"" << connections << "\""; + colorConnection(out, connections); + if (l->isReliable()) { + out << ", style=bold "; + } + out <<"];" << endl; } else { out << "[style=\"invis\"];\n"; } @@ -83,6 +117,35 @@ void flow2dotty(PSLProblem & problem, abstract_solver & solver) } +void colorUnitBandwidth(ostream & out, const double unitBandwidth) { + if(unitBandwidth >= 10) { + if(unitBandwidth >= 1000) { + out << ",color=firebrick"; + } else if(unitBandwidth >= 250) { + out << ",color=salmon"; + } else if(unitBandwidth >= 100) { + + out << ",color=midnightblue"; + //out << ",color=seagreen"; + }else if(unitBandwidth >= 50) { + out << ",color=seagreen"; + } else { + out << ",color=darkgoldenrod"; + } + } +} + +bool isReliablePath(const FacilityNode* origin, FacilityNode* destination) { + while(destination != origin) { + if(destination->toFather()->isReliable()) { + destination = destination->getFather(); + if(!destination) { + return false; + } + }else return false; + } + return true; +} void path2dotty(ostream& out, PSLProblem & problem, abstract_solver & solver, unsigned int stage) { @@ -95,10 +158,17 @@ void path2dotty(ostream& out, PSLProblem & problem, abstract_solver & solver, un while(j != i->nend()) { CUDFcoefficient connections = solver.get_solution(problem.rankZ(*i,*j, stage)); if(connections > 0) { - CUDFcoefficient bandwidth = solver.get_solution(problem.rankB(*i,*j, stage)); + double bandwidth = solver.get_solution(problem.rankB(*i,*j, stage)); + bandwidth/=connections; + out.precision(1); out << i->getID() << " -> " << j->getID(); out << "[label=\"" << connections << - "|" << bandwidth << "\"];" << endl; + "\\n" << scientific << bandwidth << "\""; + colorUnitBandwidth(out, bandwidth); + if (isReliablePath(*i, *j)) { + out << ", style=bold "; + } + out << "];" << endl; } j++; } @@ -147,3 +217,4 @@ void solution2dotty(PSLProblem &problem, abstract_solver& solver) { + diff --git a/src/network.cpp b/src/network.cpp index f6c1e4b..0b64369 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -347,8 +347,9 @@ NetworkLink::NetworkLink(unsigned int id, FacilityNode* father, } ostream& NetworkLink::toDotty(ostream & out) { + out.precision(1); out << origin->getID() << " -> " << destination->getID(); - out << "[label=\"" << getBandwidth() << "\""; + out << "[label=\"" << scientific << double(getBandwidth()) << "\""; if (isReliable()) { out << ", style=bold "; } diff --git a/src/network.hpp b/src/network.hpp index a45baa0..1c54063 100644 --- a/src/network.hpp +++ b/src/network.hpp @@ -469,7 +469,6 @@ class PSLProblem { inline unsigned int levelCount() const { return levelNodeCounts.size(); } - //TODO inline bool isValid(); void setSeed(const unsigned int seed); FacilityNode* generateNetwork(); @@ -477,7 +476,6 @@ class PSLProblem { //generate Breadth-First Numbered Tree FacilityNode* generateNetwork(bool hierarchic); - //TODO change visibility to network bool checkNetwork(); bool checkNetworkHierarchy(); inline FacilityNode* getRoot() const {