//splits graph into connected components void split_graph(ListDigraph& g, vector<ListDigraph*>& graphs){ Undirector<ListDigraph> undirected(g); ListDigraph::NodeMap<int> components(g); stronglyConnectedComponents(undirected, components); int num_subgraphs = 0; for(ListDigraph::NodeIt n(g); n != INVALID; ++n){ if(components[n] > num_subgraphs) num_subgraphs = components[n]; } num_subgraphs++; ListDigraph::NodeMap<ListDigraph::Node> map(g); for(int i = 0; i < num_subgraphs; i++){ ListDigraph temp; for(ListDigraph::NodeIt n(g); n != INVALID; ++n){ if(components[n] == i){ map[n] = temp.addNode(); } } for(ListDigraph::NodeIt n(g); n != INVALID; ++n){ if(components[n] == i){ for(ListDigraph::OutArcIt o(g, n); o != INVALID; ++o){ temp.addArc(map[g.source(o)], map[g.target(o)]); } } } graphs.push_back(&temp); } }
void drawGraphToFileWithArcMap(ListDigraph& g, ListDigraph::ArcMap<int>& map){ ofstream myfile; myfile.open("graph.dot"); myfile << "digraph g {\n"; for (ListDigraph::ArcIt a(g); a!= INVALID; ++a) { myfile << g.id(g.source(a)) << " -> " << g.id(g.target(a)) << " [label=\"" << map[a] << "\"] \n"; } myfile << "}\n"; myfile.close(); }
void drawGraphToFile(ListDigraph& g){ ofstream myfile; myfile.open("graph.dot"); myfile << "digraph g {\n"; for (ListDigraph::ArcIt a(g); a!= INVALID; ++a) { myfile << g.id(g.source(a)) << " -> " << g.id(g.target(a)) << "\n"; } myfile << "}\n"; myfile.close(); }
// This routine visualize a digraph using a pdf viewer. It uses neato (from // graphviz.org) to generate a pdf file and a program to view the pdf file. The // pdf viewer name is given in the viewername parameter. int ViewListDigraph(ListDigraph &g, DNodeStringMap &vname, // node names DNodePosMap &px, // x-position of the nodes DNodePosMap &py, // y-position of the nodes DNodeColorMap &vcolor, // color of node (see myutils.h) ArcColorMap &ecolor, // color of edge string text) // text displayed below the figure { char tempname[1000],cmd[1000]; FILE *fp; double minpx=DBL_MAX,minpy=DBL_MAX,maxpx=-DBL_MAX,maxpy=-DBL_MAX,delta,factor; string str; // obtain a temporary file name strcpy(tempname,".viewdigraphtempname"); fp = fopen(tempname,"w+"); if (fp==NULL) {cout << "Error to open temporary file to visualize digraph.\n"; return(0);} for (DNodeIt v(g); v!=INVALID; ++v) { if (px[v] < minpx) minpx = px[v]; if (px[v] > maxpx) maxpx = px[v]; if (py[v] < minpy) minpy = py[v]; if (py[v] > maxpy) maxpy = py[v]; } factor = 40; // using larger values makes small nodes delta = fmax(maxpx - minpx,maxpy - minpy); // Generate a text file with the graph format of neato program fprintf(fp,"digraph g {\n"); fprintf(fp,"\tsize = \"10, 10\";\n"); fprintf(fp,"\tnode [style = filled, shape = \"circle\"];\n"); for (DNodeIt v(g); v!=INVALID; ++v) { if (vcolor[v]==NOCOLOR) continue; fprintf(fp,"\t%s [color=\"%s\", pos = \"%lf,%lf!\"];\n", vname[v].c_str(),ColorName(vcolor[v]).c_str(),factor*(px[v]-minpx)/delta,factor*(py[v]-minpy)/delta); } for (ArcIt e(g); e!=INVALID; ++e) { if (ecolor[e]==NOCOLOR) continue; fprintf(fp,"\t%s -> %s [color=\"%s\" ];\n",vname[g.source(e)].c_str(),vname[g.target(e)].c_str(),ColorName(ecolor[e]).c_str()); } fprintf(fp,"label=\"%s\";\nfontsize=50;\n",text.c_str()); fprintf(fp,"}\n"); fclose(fp); sprintf(cmd,"neato -Tpdf %s -o %s.pdf",tempname,tempname); system(cmd); str = tempname; str = str + ".pdf"; view_pdffile(str); return(1); }
// ****************** TSP WITH REFUELING ********************************** // Directed version of adjacency matrix. Used to handle with the TSP with Refueling Problem. AdjacencyMatrixDirected::AdjacencyMatrixDirected(ListDigraph &dgraph, ArcValueMap &graphweight, double NonArcValue): DNode2Index(dgraph), Arc2Index(dgraph) { int i; g = &dgraph; this->NonArcValue = NonArcValue; weight = &graphweight; Nnodes = countNodes(dgraph); // number of nodes in the input dgraph Narcs = countArcs(dgraph); // number of edges in the input dgraph Nmatrix = Nnodes*Nnodes; // full matrix AdjMatrix = (double *) malloc(sizeof(double)*Nmatrix); Index2DNode = (DNode *) malloc(sizeof(Node)*Nnodes); Index2Arc = (Arc *) malloc(sizeof(Arc)*Narcs); if ((AdjMatrix==NULL)||(Index2DNode==NULL)||(Index2Arc==NULL)) { cout << "Out of memory in constructor of AdjacencyMatrixDirected\n"; ADJMAT_FreeNotNull(AdjMatrix); ADJMAT_FreeNotNull(Index2DNode); ADJMAT_FreeNotNull(Index2Arc); exit(0);} i = 0; for (DNodeIt v(*g); v != INVALID; ++v) { Index2DNode[i] = v; AdjacencyMatrixDirected::DNode2Index[v] = i; i++; } // Initially all edges have infinity weight for (int i=0;i<Nmatrix;i++) AdjMatrix[i] = NonArcValue; // Then, update the existing edges with the correct weight for (ArcIt a(dgraph); a != INVALID; ++a) { DNode u,v; int i_u,i_v; u = dgraph.source(a); v = dgraph.target(a); // obtain the extremities of e i_u = DNode2Index[u]; i_v = DNode2Index[v]; AdjMatrix[i_u*Nnodes+i_v] = graphweight[a]; } }
//find minflow by reducing the maximal amount of flow (with maxflow) from a feasible flow void find_minflow_IBFS(ListDigraph& g, ListDigraph::ArcMap<int>& demands, ListDigraph::ArcMap<int>& flow, ListDigraph::NodeMap<int>& labels, ListDigraph::Node s, ListDigraph::Node t) { ListDigraph::ArcMap<int> feasible_flow(g); find_feasible_flow(g, demands, feasible_flow); //Create IBFS graph and solve maxflow in it IBFSGraph* g_ibfs = new IBFSGraph(IBFSGraph::IB_INIT_FAST); int num_nodes = countNodes(g); int num_arcs = countArcs(g); //we need a special labeling for IBFS, because we won't have s and t there //ListDigraph::Node label_to_node[num_nodes]; ListDigraph::Node* label_to_node = new ListDigraph::Node[num_nodes]; ListDigraph::NodeMap<int> labels_ibfs(g); int index_counter = 0; for(ListDigraph::NodeIt n(g); n != INVALID; ++n){ if(n == s || n == t) continue; labels_ibfs[n] = index_counter; index_counter++; label_to_node[labels_ibfs[n]] = n; } g_ibfs->initSize(num_nodes-2, num_arcs-countOutArcs(g, s) - countInArcs(g, t)); /** for(ListDigraph::NodeIt n(g); n != INVALID; ++n){ if(countInArcs(g, n) == 0){ g_ibfs->addNode(labels[n], 0, MAX_CAPACITY); } else if(countOutArcs(g, n) == 0){ g_ibfs->addNode(labels[n], MAX_CAPACITY, 0); } } **/ ListDigraph::ArcMap<int> arc_labels(g); //ListDigraph::Arc arc_labels_reverse[num_arcs]; ListDigraph::Arc* arc_labels_reverse = new ListDigraph::Arc[num_arcs]; int counter = 0; for(ListDigraph::ArcIt a(g); a != INVALID; ++a){ arc_labels[a] = counter; arc_labels_reverse[counter] = a; counter++; } for(ListDigraph::ArcIt a(g); a != INVALID; ++a){ if(g.source(a) == s){ g_ibfs->addNode(labels_ibfs[g.target(a)], 0, MAX_CAPACITY); } else if(g.target(a) == t){ g_ibfs->addNode(labels_ibfs[g.source(a)], MAX_CAPACITY, 0); } else{ g_ibfs->addEdge(labels_ibfs[g.target(a)], labels_ibfs[g.source(a)], feasible_flow[a]-demands[a], MAX_CAPACITY); } } g_ibfs->initGraph(); g_ibfs->computeMaxFlow(); /** while(g_ibfs->arcs != g_ibfs->arcEnd){ //cout << "LABEL:: " << g_ibfs->arcs->label << "\n"; if(g_ibfs->arcs->label != -1){ ListDigraph::Arc a = arc_labels_reverse[g_ibfs->arcs->label]; int flow_on_arc = MAX_CAPACITY - g_ibfs->arcs->rCap; int flow_on_reverse = (feasible_flow[a]-demands[a]) - g_ibfs->arcs->rev->rCap; //cout << g_ibfs->arcs->rCap << " " << g_ibfs->arcs->rev->rCap << "\n"; //cout << feasible_flow[a] << " " << flow_on_arc << " " << flow_on_reverse << " "; flow[a] = feasible_flow[a] + flow_on_arc - flow_on_reverse; //cout << flow[a] << "\n"; } g_ibfs->arcs++; } for(ListDigraph::OutArcIt o(g, s); o != INVALID; ++o){ for (ListDigraph::OutArcIt oa(g, g.target(o)); oa != INVALID; ++oa) { flow[o] += flow[oa]; } } for(ListDigraph::InArcIt i(g, t); i != INVALID; ++i){ for(ListDigraph::InArcIt ia(g, g.source(i)); ia != INVALID; ++ia){ flow[i] += flow[ia]; } } **/ }