void PrintListGraph(ListGraph &g, NodeStringMap &vname, EdgeValueMap &graphweight) { int Nnodes = countNodes(g); // number of nodes in the input graph int Nedges = countEdges(g); // number of edges in the input graph printf("-------------------------------------------------------\n"); printf("Number of nodes: %d\n",Nnodes); printf("Number of edges: %d\n",Nedges); for (NodeIt v(g); v!=INVALID; ++v) printf("%s\n",vname[v].c_str()); printf("\n"); printf("-------------------------------------------------------\n"); for (EdgeIt a(g); a!=INVALID; ++a) printf("%s -- %s %lf\n",vname[g.u(a)].c_str(),vname[g.v(a)].c_str(), graphweight[a]); printf("\n"); }
int monitoramento_em_grafo_bipartido( ListGraph &g, NodeName &vname, ListGraph::NodeMap<double> &custo, ListGraph::NodeMap<int> &solucao) { int seed=0; GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); model.getEnv().set(GRB_IntParam_Seed, seed); model.set(GRB_StringAttr_ModelName, "Monitoramento em Grafo Bipartido"); // prob. name model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem // ------------------------------------------------------ // Construa o modelo daqui para baixo // ------------------------------------------------------ // Exemplos de como voce pode declarar variaveis indexadas nos vertices ou nas arestas. // Nao necessariamente voce precisa dos dois tipos // ListGraph::NodeMap<GRBVar> x(g); // variables for each node // ListGraph::EdgeMap<GRBVar> y(g); // variables for each edge ListGraph::NodeMap<GRBVar> x(g); // variables for each node ListGraph::EdgeMap<GRBVar> y(g); // variables for each edge int name = 0; char namme[100]; for(ListGraph::NodeIt v(g); v != INVALID; ++v) { sprintf(namme,"PC_%s",vname[v].c_str()); x[v] = model.addVar(0.0, 1.0, custo[v],GRB_CONTINUOUS,namme); } model.update(); try { for(ListGraph::EdgeIt e(g); e != INVALID; ++e) { //Para cada aresta, um dos lados e 1 GRBLinExpr expr; expr += x[g.u(e)]; expr += x[g.v(e)]; model.addConstr(expr >= 1); } model.update(); // ------------------------------------------------------ // Construa o modelo daqui para cima // ------------------------------------------------------ //model.write("model.lp"); system("cat model.lp"); model.optimize(); for (ListGraph::NodeIt v(g); v!=INVALID; ++v) { if (x[v].get(GRB_DoubleAttr_X)>1-EPS) solucao[v] = 1; else solucao[v] = 0; //solucao[v] = 1; } return(1); } catch (...) {cout << "Error during callback..." << endl; return(0);} }
int main(int argc, char *argv[]) { int n; double box_width,box_height; ListGraph g; // graph declaration NodeName vname(g); // name of graph nodes ListGraph::NodeMap<double> px(g),py(g); // xy-coodinates for each node ListGraph::NodeMap<int> vcolor(g);// color of nodes ListGraph::EdgeMap<int> ecolor(g); // color of edges EdgeWeight lpvar(g); // used to obtain the contents of the LP variables EdgeWeight weight(g); // edge weights vector <Node> V; srand48(1); // double cutoff; // used to prune non promissing branches (of the B&B tree) if (argc!=5) {cout<<"Usage: "<< argv[0]<<" <number_of_nodes_in_graph> <number_of_pairs> <box_width> <box_height>"<< endl;exit(0);} n = atoi(argv[1]); int kPairs = atoi(argv[2]); box_width = atof(argv[3]); box_height = atof(argv[4]); GenerateTriangulatedListGraph(g,vname,px,py,weight,n,box_width,box_height); int nV = countNodes(g); int nA = countEdges(g); cout << nA << " " << nV << " " << kPairs << endl; for (NodeIt v(g);v!=INVALID;++v) cout << vname[v] << " " << px[v] << " " << py[v] << endl; for (EdgeIt e(g);e!=INVALID;++e) cout << vname[g.u(e)] << " " << vname[g.v(e)] << " " << 20*drand48() << " " << weight[e] << " " << 5*drand48() <<endl; for (int i = 0; i < kPairs; i++) { int v1 = ((int)((nV-1)*drand48() + 1)); int v2 = ((int)((nV-1)*drand48() + 1)); if (v1 != v2) { cout << v1 <<" " << v2 <<" "<< (25*drand48() + 25*drand48()) <<" " << (20*drand48() + nA)<< endl; } else { i--; } } return 0; }
AdjacencyMatrix::AdjacencyMatrix(ListGraph &graph,EdgeValueMap &graphweight,double NonEdgValue): Node2Index(graph),Edge2Index(graph) { int i; g = &graph; NonEdgeValue = NonEdgValue; weight = &graphweight; Nnodes = countNodes(graph); // number of nodes in the input graph Nedges = countEdges(graph); // number of edges in the input graph Nmatrix = (Nnodes*(Nnodes-1))/2; // no. of edges/elem. in strict. triang. inf. matrix AdjMatrix = (double *) malloc(sizeof(double)*Nmatrix); Index2Node = (Node *) malloc(sizeof(Node)*Nnodes); Index2Edge = (Edge *) malloc(sizeof(Edge)*Nedges); if ((AdjMatrix==NULL)||(Index2Node==NULL)||(Index2Edge==NULL)) { cout << "Out of memory in constructor of AdjacencyMatrix\n"; ADJMAT_FreeNotNull(AdjMatrix); ADJMAT_FreeNotNull(Index2Node); ADJMAT_FreeNotNull(Index2Edge); exit(0);} i = 0; for (NodeIt v(*g); v != INVALID; ++v) { Index2Node[i] = v; AdjacencyMatrix::Node2Index[v]=i; i++; } // Initially all edges have infinity weight for (int i=0;i<Nmatrix;i++) AdjMatrix[i] = NonEdgeValue; // Then, update the existing edges with the correct weight for (EdgeIt e(graph); e != INVALID; ++e) { Node u,v; int i_u,i_v; u = graph.u(e); v = graph.v(e); // obtain the extremities of e i_u = Node2Index[u]; i_v = Node2Index[v]; if (i_u > i_v) AdjMatrix[i_u*(i_u-1)/2+i_v] = graphweight[e]; else if (i_u < i_v) AdjMatrix[i_v*(i_v-1)/2+i_u] = graphweight[e]; else { cout << "Out of memory in constructor of AdjacencyMatrix\n"; exit(0);} } }
bool WriteListGraphGraphviz(ListGraph &g, NodeStringMap &vname, // vertex names EdgeStringMap &ename, // edge names NodeColorMap &vcolor, // vertex colors EdgeColorMap &acolor, // edge colors string filename) { ofstream out; string linha; out.open(filename.c_str()); if (out.is_open()) return(false); out << "graph g {\n"; out << "\tsize = \"8, 11\";\n"; out << "\tnode [shape = \"circle\"];\n"; for (NodeIt v(g); v!=INVALID; ++v) { linha = "\t"; linha += vname[v].c_str(); linha += " [color="; linha += ColorName(vcolor[v]); linha += "];\n"; out << linha; } for (EdgeIt a(g); a!=INVALID; ++a) { if (acolor[a]!=WHITE) { linha = "\t"; linha += vname[g.u(a)].c_str() ; linha += " -- "; linha += vname[g.v(a)].c_str(); linha += " [label = \""; linha += ename[a].c_str(); linha += "\""; linha += ", color=\""; linha += ColorName(acolor[a]); linha += "\" ];\n"; out << linha; } } out << "}\n"; out.close(); return(true); }
//指定一些特殊分支,要求搜索一条路径时尽可能多的通过这些特殊分支 //例如:搜索一条串联通风路径(通过多个用风地点的一条路径) //采用二分匹配实现失败!!! static bool MaxKeyEdgePass_Match(Digraph& dg, EdgeArray& airEdges, Digraph::Node s, Digraph::Node t, EdgeArray& mpp) { EdgeArray p; if(!GraphUtils::DFS_Path(dg, s, t, p)) return false; typedef Digraph::NodeMap<Digraph::Node> DDMap; DDMap ddm(dg, INVALID); NodeArray left, right; left.push_back(s); right.push_back(t); for(size_t i=0;i<airEdges.size();i++) { Digraph::Arc e = airEdges[i]; Digraph::Node u = dg.source(e); Digraph::Node v = dg.target(e); p.clear(); bool ret = GraphUtils::DFS_Path(dg, v, t, p); if(!ret) continue; p.clear(); ret = GraphUtils::DFS_Path(dg, s, u, p); if(!ret) continue; left.push_back(v); right.push_back(u); } //cout<<"left="<<left.size()<<" right="<<right.size()<<endl; ListGraph g; ListGraph::NodeMap<Digraph::Node> udm(g); typedef std::vector<ListGraph::Node> UNodeArray; UNodeArray left_nodes, right_nodes; typedef std::map<Digraph::Node, ListGraph::Node> DUMap; DUMap dum; //添加节点 for(size_t i=0;i<left.size();i++) { Digraph::Node u = left[i]; ListGraph::Node uu = g.addNode(); udm[uu] = u; left_nodes.push_back(uu); //cout<<dg.id(u)<< " "; } //cout<<endl; for(size_t i=0;i<right.size();i++) { Digraph::Node u = right[i]; ListGraph::Node uu = g.addNode(); udm[uu] = u; right_nodes.push_back(uu); //cout<<dg.id(u)<<" "; } //cout<<endl; for(size_t i=0;i<right.size();i++) { Digraph::Node u = right[i]; ListGraph::Node uu = g.addNode(); udm[uu] = u; left_nodes.push_back(uu); //cout<<dg.id(u)<< " "; } //cout<<endl; for(size_t i=0;i<left.size();i++) { Digraph::Node u = left[i]; ListGraph::Node uu = g.addNode(); udm[uu] = u; right_nodes.push_back(uu); //cout<<dg.id(u)<< " "; } //cout<<endl; //添加分支 for(size_t i=0;i<left_nodes.size();i++) { ListGraph::Node uv = left_nodes[i]; for(size_t j=0;j<right_nodes.size();j++) { ListGraph::Node uu = right_nodes[j]; Digraph::Node v = udm[uv]; Digraph::Node u = udm[uu]; if(u == v) continue; p.clear(); if(GraphUtils::DFS_Path(dg, v, u, p)) { //ListGraph::Node uv = left_nodes[i]; //ListGraph::Node uu = right_nodes[j]; ListGraph::Edge e = g.addEdge(uu,uv); //cout<<"二分图:"<<dg.id(v)<<"<-->"<<dg.id(u)<<endl; } } } //二分图最大匹配 MaxMatching<ListGraph> mm(g); mm.run(); //cout<<"分支数:"<<countEdges(g)<<" 匹配数:"<<mm.matchingSize()<<endl; for(ListGraph::EdgeIt e(g);e!=INVALID;++e) { if(mm.matching(e)) { ListGraph::Node du = g.u(e); ListGraph::Node dv = g.v(e); Digraph::Node u = udm[du]; Digraph::Node v = udm[dv]; //cout<<"匹配:"<<dg.id(v)<<"<-->"<<dg.id(u)<<endl; if(ddm[u] != INVALID && ddm[v] == INVALID) { ddm[v] = u; //cout<<" v"<<dg.id(v)<<"-->v"<<dg.id(u) <<" v"<<dg.id(u)<<"-->"<<dg.id(ddm[u])<<endl; } else if(ddm[v] != INVALID && ddm[u] == INVALID) { ddm[u] = v; //cout<<" v"<<dg.id(v)<<"-->v"<<dg.id(ddm[v]) <<" v"<<dg.id(u)<<"-->"<<dg.id(v)<<endl; } } } NodeArray node_path; Digraph::Node u = s; bool ret = true; while(u != t) { Digraph::Node v = ddm[u]; //cout<<dg.id(u)<<"->"<<endl; if(v == INVALID) { //cout<<"错误"<<endl; ret = false; break; } //cout<<" ->"<<dg.id(v)<<" "<<endl; node_path.push_back(v); u = v; } if(ret) { u = s; for(size_t i=0;i<node_path.size();i++) { Digraph::Node v = node_path[i]; GraphUtils::DFS_Path(dg, u, v, mpp); u = v; } } return ret; }
int Steiner::steiner(const set<ListGraph::Node> terminals) { if (this->s != 0) delete this->s; this->s = new ListGraph(); if (this->sweight != 0) delete this->sweight; this->sweight = new ListGraph::EdgeMap<int>(*this->s); // perform dijkstra for every terminal ListGraph::NodeMap<Dijkstra*> dijk(this->g); for (set<ListGraph::Node>::iterator it = terminals.begin(); it != terminals.end(); ++it) { dijk[*it] = new Dijkstra(this->g, this->weight); dijk[*it]->dijkstra(*it); } // build intermediate graph ListGraph intermediate; ListGraph::EdgeMap<int> iweight(intermediate); map<ListGraph::Node, ListGraph::Node> imapper; for (set<ListGraph::Node>::iterator it = terminals.begin(); it != terminals.end(); ++it) { ListGraph::Node n = intermediate.addNode(); imapper[n] = *it; } for (ListGraph::NodeIt it1(intermediate); it1 != INVALID; ++it1) { ListGraph::NodeIt it2 = it1; for (++it2; it2 != INVALID; ++it2) { ListGraph::Edge e = intermediate.addEdge(it1, it2); iweight[e] = (*dijk[imapper[it1]]->dist)[imapper[it2]]; } } // compute mst MST mst(intermediate, iweight); mst.prim(); // Kruskal mst(intermediate, iweight); // mst.kruskal(); // build final graph map<ListGraph::Node, ListGraph::Node> smapper; for (set<ListGraph::Edge>::iterator it = mst.mst->begin(); it != mst.mst->end(); ++it) { // for each edge in the mst // add end nodes to graph ListGraph::Node u = imapper[intermediate.u(*it)]; if (smapper.count(u) == 0) smapper[u] = this->s->addNode(); ListGraph::Node v = imapper[intermediate.v(*it)]; if (smapper.count(v) == 0) smapper[v] = this->s->addNode(); ListGraph::Node last = v; ListGraph::Node cur = v; do { // walk through path cur = (*dijk[u]->pred)[cur]; if (smapper.count(cur) == 0) smapper[cur] = this->s->addNode(); // add edge to graph, if not already existing if (findEdge(*this->s, smapper[last], smapper[cur]) == INVALID) { ListGraph::Edge e = this->s->addEdge(smapper[last], smapper[cur]); (*this->sweight)[e] = (*dijk[u]->dist)[last] - (*dijk[u]->dist)[cur]; } last = cur; } while (cur != u); } // compute overall weight int overallw = 0; for (ListGraph::EdgeIt e(*this->s); e != INVALID; ++e) { overallw += (*this->sweight)[e]; } // clean up dijkstras for (set<ListGraph::Node>::iterator it = terminals.begin(); it != terminals.end(); ++it) { delete dijk[*it]; } return overallw; }
int main(int argc, char *argv[]) { int time_limit; char name[1000]; double cutoff=0.0; ListGraph g; EdgeWeight lpvar(g); EdgeWeight weight(g); NodeName vname(g); ListGraph::NodeMap<double> posx(g),posy(g); string filename; int seed=1; // uncomment one of these lines to change default pdf reader, or insert new one //set_pdfreader("open"); // pdf reader for Mac OS X //set_pdfreader("xpdf"); // pdf reader for Linux //set_pdfreader("evince"); // pdf reader for Linux srand48(seed); time_limit = 3600; // solution must be obtained within time_limit seconds if (argc!=2) {cout<< endl << "Usage: "<< argv[0]<<" <graph_filename>"<<endl << endl << "Example: " << argv[0] << " gr_berlin52" << endl << " " << argv[0] << " gr_att48" << endl << endl; exit(0);} else if (!FileExists(argv[1])) {cout<<"File "<<argv[1]<<" does not exist."<<endl; exit(0);} filename = argv[1]; // Read the graph if (!ReadListGraph(filename,g,vname,weight,posx,posy)) {cout<<"Error reading graph file "<<argv[1]<<"."<<endl;exit(0);} TSP_Data tsp(g,vname,posx,posy,weight); ListGraph::EdgeMap<GRBVar> x(g); GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); #if GUROBI_NEWVERSION model.getEnv().set(GRB_IntParam_LazyConstraints, 1); model.getEnv().set(GRB_IntParam_Seed, seed); #else model.getEnv().set(GRB_IntParam_DualReductions, 0); // Dual reductions must be disabled when using lazy constraints #endif model.set(GRB_StringAttr_ModelName, "Undirected TSP with GUROBI"); // name to the problem model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem // Add one binary variable for each edge and also sets its cost in the objective function for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { sprintf(name,"x_%s_%s",vname[g.u(e)].c_str(),vname[g.v(e)].c_str()); x[e] = model.addVar(0.0, 1.0, weight[e],GRB_BINARY,name); } model.update(); // run update to use model inserted variables // Add degree constraint for each node (sum of solution edges incident to a node is 2) for (ListGraph::NodeIt v(g); v!=INVALID; ++v) { GRBLinExpr expr; for (ListGraph::IncEdgeIt e(g,v); e!=INVALID; ++e) expr += x[e]; //aqui model.addConstr(expr == 2 ); what? ignorou! model.addConstr(expr == 2 ); } try { model.update(); // Process any pending model modifications. if (time_limit >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,time_limit); subtourelim cb = subtourelim(tsp , x); model.setCallback(&cb); tsp.max_perturb2opt_it = 200; //1000; // number of iterations used in heuristic TSP_Perturb2OPT TSP_Perturb2OPT(tsp); if (tsp.BestCircuitValue < DBL_MAX) cutoff = tsp.BestCircuitValue-BC_EPS; // // optimum value for gr_a280=2579, gr_xqf131=566.422, gr_drilling198=15808.652 if (cutoff > 0) model.getEnv().set(GRB_DoubleParam_Cutoff, cutoff ); model.update(); // Process any pending model modifications. model.optimize(); double soma=0.0; for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { lpvar[e] = x[e].get(GRB_DoubleAttr_X); if (lpvar[e] > 1-BC_EPS ) { soma += weight[e]; if ( (vname[g.u(e)] == "243")||(vname[g.v(e)] == "243") || (vname[g.u(e)] == "242")||(vname[g.v(e)] == "242") ) { cout << "Achei, x("<< vname[g.u(e)] << " , " << vname[g.v(e)] << " = " << lpvar[e] <<"\n"; } } } cout << "Solution cost = "<< soma << endl; Update_Circuit(tsp,x); // Update the circuit in x to tsp circuit variable (if better) ViewTspCircuit(tsp); }catch (...) { if (tsp.BestCircuitValue < DBL_MAX) { cout << "Heuristic obtained optimum solution" << endl; ViewTspCircuit(tsp); return 0; }else { cout << "Graph is infeasible" << endl; return 1; } } }
int main(int argc, char *argv[]) { ListGraph g; // graph declaration string digraph_vcover_filename; NodeName vname(g); // name of graph nodes EdgeName ename(g); // name of graph edges ListGraph::NodeMap<double> px(g),py(g); // xy-coodinates for each node ListGraph::NodeMap<int> vcolor(g);// color of nodes ListGraph::EdgeMap<int> ecolor(g); // color of edges ListGraph::NodeMap<int> solucao(g); // vetor 0/1 que identifica vertices da solucao NodeWeight lpvar(g); // used to obtain the contents of the LP variables NodeWeight weight(g); // node weights vector <Node> V; srand48(1); // uncomment one of these lines to change default pdf reader, or insert new one //set_pdfreader("open"); // pdf reader for Mac OS X //set_pdfreader("xpdf"); // pdf reader for Linux set_pdfreader("evince"); // pdf reader for Linux //set_pdfreader("open -a Skim.app"); SetGraphLabelFontSize(50); if (argc!=2) {cout<<endl<<"Usage: "<< argv[0]<<" <digraph_vcover_filename>"<< endl << endl; cout << "Example: " << argv[0] << " gr_bipartido_1.in" << endl << endl; exit(0);} digraph_vcover_filename = argv[1]; ReadListGraph3(digraph_vcover_filename,g,vname,weight,px,py); vCover_Instance T(g,vname,px,py,weight); for (EdgeIt e(g); e != INVALID; ++e) ename[e] = vname[g.u(e)]+" , "+vname[g.v(e)]; cout << "Rede com " << T.nnodes << endl << endl; cout << "Computadores e seus custos:" << endl << endl; for (NodeIt v(g);v!=INVALID;++v) cout << "Computador[ " << vname[v] << " ] com custo " << weight[v] << "." << endl; cout << endl << "Conexoes entre computadores:" << endl << endl; for (EdgeIt e(g);e!=INVALID;++e) cout << "Conexao " << ename[e] << "." << endl; cout << endl << endl; // for (NodeIt v(g);v!=INVALID;++v) vcolor[v]=BLACK; // for (EdgeIt e(g); e != INVALID; ++e) ecolor[e] = BLUE; // for (EdgeIt e(g); e != INVALID; ++e) ename[e] = ""; // ViewListGraph(g,vname,ename,px,py,vcolor,ecolor,digraph_vcover_filename); // cout << "Pause\n"; getchar(); // Generate the binary variables and the objective function // Add one binary variable for each edge and set its cost in the objective function if (monitoramento_em_grafo_bipartido(g, vname, weight, solucao)) { // verificacao e apresentacao da solucao obtida for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) if (!(solucao[g.u(e)] || solucao[g.v(e)])) { cout << "Nao foi obtida uma solucao viavel.\nConexao {" << vname[g.u(e)] << "---" << vname[g.v(e)] << "} nao monitorada." << endl << endl; exit(0);} double soma=0.0; for (ListGraph::NodeIt v(g);v!=INVALID;++v) vcolor[v]=BLUE; // all nodes BLUE for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) ecolor[e]=BLUE; cout << "Computadores Selecionados" << endl ; for (ListGraph::NodeIt v(g); v!=INVALID; ++v) if (solucao[v]){soma += weight[v]; vcolor[v]=RED; cout << vname[v] << endl;} cout << endl << "Valor da Solucao = " << soma << "." << endl; ViewListGraph(g,vname,ename,px,py,vcolor,ecolor, "Solucao do Monitoramento com custo "+DoubleToString(soma)); return(0); }else{cout << "Programa linear gerado eh inviavel." << endl;return(1);} }
void IMFT<Ptr>::twoFrameCorresponding(vector<ListGraph::Node> vecUFrame, vector<ListGraph::Node> vecVFrame) { if(m_isDebug) printf("2-Frame Corresponding : # F1 - %d, # F2 - %d\n", vecUFrame.size(), vecVFrame.size()); // make graph, weight map ListGraph g; ListGraph::NodeMap<V> gNodeMap(g); ListGraph::EdgeMap<double> gEdgeMap(g); // make nodes of UFrame : save node id of UFrame for(int i=0;i<vecUFrame.size();i++){ ListGraph::Node n = g.addNode(); V v; v.id = m_g.id(vecUFrame.at(i)); v.ptr = (*m_gNodeMap)[vecUFrame.at(i)].ptr; v.nFrame = 1; gNodeMap[n] = v; } // make nodes of VFrame : save node id of VFrame for(int i=0;i<vecVFrame.size();i++){ ListGraph::Node n = g.addNode(); V v; v.id = m_g.id(vecVFrame.at(i)); v.ptr = (*m_gNodeMap)[vecVFrame.at(i)].ptr; v.nFrame = 2; gNodeMap[n] = v; // connection for(ListGraph::NodeIt pn(g); pn != INVALID; ++pn){ if(gNodeMap[pn].nFrame != v.nFrame){ double weight = gain(gNodeMap[pn], v); gEdgeMap[g.addEdge(pn,n)] = weight; // ListGraph::Edge e = g.addEdge(pn,n); // gEdgeMap[e] = weight; // gNodeMap[m_g.u(e)].edgeID = g.id(e); // gNodeMap[m_g.v(e)].edgeID = g.id(e); } } } // maximum weighted matching MaxWeightedMatching<ListGraph, ListGraph::EdgeMap<double> > mwm(g, gEdgeMap); mwm.run(); int wsum = mwm.matchingWeight(); if(m_isDebug) printf("2-Frame Max = %d\n", wsum); // make edges of original graph using original nodes' ids for(ListGraph::EdgeIt e(g); e != INVALID; ++e){ if(mwm.matching(e)){ int origUId = gNodeMap[g.u(e)].id; int origVId = gNodeMap[g.v(e)].id; ListGraph::Node newU, newV; newU = m_g.nodeFromId(origUId); newV = m_g.nodeFromId(origVId); if(m_isDebug) printf("2-Frame Connection %d, %d nodes\n", origUId, origVId); double weight = gain((*m_gNodeMap)[newU], (*m_gNodeMap)[newV]); ListGraph::Edge e = m_g.addEdge(newU,newV); (*m_gEdgeMap)[e] = weight; (*m_gNodeMap)[m_g.u(e)].edgeID = m_g.id(e); (*m_gNodeMap)[m_g.v(e)].edgeID = m_g.id(e); // if u가 track이 없으면, track 생성하고, v도 track에 집어 넣음. // u가 track이 있으면, v를 그 track에 집어 넣음. if(cnt > m_nWindow){ int vId = m_g.id(m_g.u(e))-1; if(!(*m_gNodeMap)[m_g.nodeFromId(vId)].isTrack){ // generate a track of vId m_cntTrack ++; Track track; track.setNum(m_cntTrack); track.putNode((*m_gNodeMap)[m_g.nodeFromId(vId)].ptr, vId, (*m_gNodeMap)[m_g.nodeFromId(vId)].nFrame); (*m_gNodeMap)[m_g.nodeFromId(vId)].isTrack = 1; (*m_gNodeMap)[m_g.nodeFromId(vId)].nTrack = m_cntTrack; if(m_isDebug) printf("Generate new track # %d of node %d\n", m_cntTrack, vId); // add v(e) to the track track.putNode((*m_gNodeMap)[m_g.v(e)].ptr, m_g.id(m_g.v(e)), (*m_gNodeMap)[m_g.v(e)].nFrame); (*m_gNodeMap)[m_g.v(e)].isTrack = 1; (*m_gNodeMap)[m_g.v(e)].nTrack = m_cntTrack; m_tracks.push_back(track); } else{ // add v(e) to the track for(int i=0;i<m_tracks.size();i++){ if(m_tracks.at(i).num() == (*m_gNodeMap)[m_g.nodeFromId(vId)].nTrack){ m_tracks.at(i).putNode((*m_gNodeMap)[m_g.v(e)].ptr, m_g.id(m_g.v(e)), (*m_gNodeMap)[m_g.v(e)].nFrame); (*m_gNodeMap)[m_g.v(e)].nTrack = (*m_gNodeMap)[m_g.nodeFromId(vId)].nTrack; (*m_gNodeMap)[m_g.v(e)].isTrack = 1; if(m_isDebug) printf("put node %d to the track %d\n", m_g.id(m_g.v(e)), (*m_gNodeMap)[m_g.v(e)].nTrack); break; } } } } } } }
int ViewEuclideanListGraph(ListGraph &g, NodeStringMap &vname, // nome dos vertices NodePosMap &posx, // coord. x dos vertices NodePosMap &posy, // coord. y dos vertices NodeColorMap &vcolor, // cor dos vertices EdgeColorMap &ecolor) // cor das arestas { char tempname[1000],cmd[1000]; FILE *fp; double gap,maxx, maxy, minx, miny, telax,posxu,posxv,posyu,posyv; char epscolor[100]; (void) vname;// to avoid "non-used" parameter. string str; strcpy(tempname,".vieweuclideangraphtempname"); //std::string tempname1 = std::tmpnam(nullptr);strcpy(tempname,tempname1.c_str()); fp = fopen(tempname,"w+"); if (fp==NULL) { cout << "Erro ao abrir arquivo para visualizar o grafo.\n"; return(0); } maxx = -999999; maxy = -999999; minx = 999999; miny = 999999; for (NodeIt v(g); v!=INVALID; ++v) { if (posx[v] > maxx) maxx = posx[v]; if (posx[v] < minx) minx = posx[v]; if (posy[v] > maxy) maxy = posy[v]; if (posy[v] < miny) miny = posy[v]; } telax = 500; fprintf(fp,"%%!PS-Adobe-2.0 EPSF-2.0\n"); fprintf(fp,"%%%%Title: x.eps\n"); fprintf(fp,"%%%%Creator: fig2dev Version 3.2 Patchlevel 3c\n"); fprintf(fp,"%%%%CreationDate: Thu Sep 12 13:02:34 2002\n"); fprintf(fp,"%%%%For: [email protected] ()\n"); fprintf(fp,"%%%%BoundingBox: 0 0 %d %d\n",(int) telax,(int) telax); fprintf(fp,"%%%%Magnification: 1.0000\n"); fprintf(fp,"%%%%EndComments\n"); fprintf(fp,"/$F2psDict 200 dict def\n"); fprintf(fp,"$F2psDict begin\n"); fprintf(fp,"$F2psDict /mtrx matrix put\n"); fprintf(fp,"/col-1 {0 setgray} bind def\n"); fprintf(fp,"/col0 {0.000 0.000 0.000 srgb} bind def\n"); fprintf(fp,"/col1 {0.000 0.000 1.000 srgb} bind def\n"); fprintf(fp,"/col2 {0.000 1.000 0.000 srgb} bind def\n"); fprintf(fp,"/col3 {0.000 1.000 1.000 srgb} bind def\n"); fprintf(fp,"/col4 {1.000 0.000 0.000 srgb} bind def\n"); fprintf(fp,"/col5 {1.000 0.000 1.000 srgb} bind def\n"); fprintf(fp,"/col6 {1.000 1.000 0.000 srgb} bind def\n"); fprintf(fp,"/col7 {1.000 1.000 1.000 srgb} bind def\n"); fprintf(fp,"/col8 {0.000 0.000 0.560 srgb} bind def\n"); fprintf(fp,"/col9 {0.000 0.000 0.690 srgb} bind def\n"); fprintf(fp,"/col10 {0.000 0.000 0.820 srgb} bind def\n"); fprintf(fp,"/col11 {0.530 0.810 1.000 srgb} bind def\n"); fprintf(fp,"/col12 {0.000 0.560 0.000 srgb} bind def\n"); fprintf(fp,"/col13 {0.000 0.690 0.000 srgb} bind def\n"); fprintf(fp,"/col14 {0.000 0.820 0.000 srgb} bind def\n"); fprintf(fp,"/col15 {0.000 0.560 0.560 srgb} bind def\n"); fprintf(fp,"/col16 {0.000 0.690 0.690 srgb} bind def\n"); fprintf(fp,"/col17 {0.000 0.820 0.820 srgb} bind def\n"); fprintf(fp,"/col18 {0.560 0.000 0.000 srgb} bind def\n"); fprintf(fp,"/col19 {0.690 0.000 0.000 srgb} bind def\n"); fprintf(fp,"/col20 {0.820 0.000 0.000 srgb} bind def\n"); fprintf(fp,"/col21 {0.560 0.000 0.560 srgb} bind def\n"); fprintf(fp,"/col22 {0.690 0.000 0.690 srgb} bind def\n"); fprintf(fp,"/col23 {0.820 0.000 0.820 srgb} bind def\n"); fprintf(fp,"/col24 {0.500 0.190 0.000 srgb} bind def\n"); fprintf(fp,"/col25 {0.630 0.250 0.000 srgb} bind def\n"); fprintf(fp,"/col26 {0.750 0.380 0.000 srgb} bind def\n"); fprintf(fp,"/col27 {1.000 0.500 0.500 srgb} bind def\n"); fprintf(fp,"/col28 {1.000 0.630 0.630 srgb} bind def\n"); fprintf(fp,"/col29 {1.000 0.750 0.750 srgb} bind def\n"); fprintf(fp,"/col30 {1.000 0.880 0.880 srgb} bind def\n"); fprintf(fp,"/col31 {1.000 0.840 0.000 srgb} bind def\n"); fprintf(fp,"\n"); fprintf(fp,"end\n"); fprintf(fp,"save\n"); fprintf(fp,"newpath 0 %d moveto 0 0 lineto %d 0 lineto %d %d " "lineto closepath clip newpath\n",(int) telax,(int) telax,(int) telax,(int) telax); fprintf(fp,"%d %d translate\n",-10,(int) telax+10); fprintf(fp,"1 -1 scale\n"); fprintf(fp,"\n"); fprintf(fp,"/cp {closepath} bind def\n"); fprintf(fp,"/ef {eofill} bind def\n"); fprintf(fp,"/gr {grestore} bind def\n"); fprintf(fp,"/gs {gsave} bind def\n"); fprintf(fp,"/sa {save} bind def\n"); fprintf(fp,"/rs {restore} bind def\n"); fprintf(fp,"/l {lineto} bind def\n"); fprintf(fp,"/m {moveto} bind def\n"); fprintf(fp,"/rm {rmoveto} bind def\n"); fprintf(fp,"/n {newpath} bind def\n"); fprintf(fp,"/s {stroke} bind def\n"); fprintf(fp,"/sh {show} bind def\n"); fprintf(fp,"/slc {setlinecap} bind def\n"); fprintf(fp,"/slj {setlinejoin} bind def\n"); fprintf(fp,"/slw {setlinewidth} bind def\n"); fprintf(fp,"/srgb {setrgbcolor} bind def\n"); fprintf(fp,"/rot {rotate} bind def\n"); fprintf(fp,"/sc {scale} bind def\n"); fprintf(fp,"/sd {setdash} bind def\n"); fprintf(fp,"/ff {findfont} bind def\n"); fprintf(fp,"/sf {setfont} bind def\n"); fprintf(fp,"/scf {scalefont} bind def\n"); fprintf(fp,"/sw {stringwidth} bind def\n"); fprintf(fp,"/tr {translate} bind def\n"); fprintf(fp,"/tnt {dup dup currentrgbcolor\n"); fprintf(fp," 4 -2 roll dup 1 exch sub 3 -1 roll mul add\n"); fprintf(fp," 4 -2 roll dup 1 exch sub 3 -1 roll mul add\n"); fprintf(fp," 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}\n"); fprintf(fp," bind def\n"); fprintf(fp,"/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul\n"); fprintf(fp," 4 -2 roll mul srgb} bind def\n"); fprintf(fp," /DrawEllipse {\n"); fprintf(fp," /endangle exch def\n"); fprintf(fp," /startangle exch def\n"); fprintf(fp," /yrad exch def\n"); fprintf(fp," /xrad exch def\n"); fprintf(fp," /y exch def\n"); fprintf(fp," /x exch def\n"); fprintf(fp," /savematrix mtrx currentmatrix def\n"); fprintf(fp," x y tr xrad yrad sc 0 0 1 startangle endangle arc\n"); fprintf(fp," closepath\n"); fprintf(fp," savematrix setmatrix\n"); fprintf(fp," } def\n"); fprintf(fp,"\n"); fprintf(fp,"/$F2psBegin {$F2psDict begin " "/$F2psEnteredState save def} def\n"); fprintf(fp,"/$F2psEnd {$F2psEnteredState restore end} def\n"); fprintf(fp,"\n"); fprintf(fp,"$F2psBegin\n"); fprintf(fp,"%%%%Page: 1 1\n"); fprintf(fp,"10 setmiterlimit\n"); fprintf(fp," %10.8lf %10.8lf sc\n",(double) MAXPOINTPOSITION/100000.0,(double) MAXPOINTPOSITION/100000.0); fprintf(fp,"%%\n"); fprintf(fp,"%% Fig objects follow\n"); fprintf(fp,"%%\n"); fprintf(fp,"25.000 slw\n"); gap = 300; for (EdgeIt a(g); a!=INVALID; ++a) { Node u,v; if (ecolor[a]==WHITE) continue; u = g.u(a); v = g.v(a); posxu = (int) (MAXPOINTPOSITION*((double)(posx[u] -minx))/ ((double) (maxx-minx)))+gap; posyu = MAXPOINTPOSITION - (int) (MAXPOINTPOSITION*((double)(posy[u] -miny))/ ((double) (maxy-miny)))+gap; posxv = (int) (MAXPOINTPOSITION*((double)(posx[v] -minx))/ ((double) (maxx-minx)))+gap; posyv = MAXPOINTPOSITION - (int) (MAXPOINTPOSITION*((double)(posy[v] -miny))/ ((double) (maxy-miny)))+gap; getepscolor(epscolor,ecolor[a]); fprintf(fp,"n %d %d m\n %d %d l gs %s s gr \n",(int) posxu,(int) posyu,(int) posxv,(int) posyv,epscolor); } for (NodeIt v(g); v!=INVALID; ++v) { posxv = (int) (MAXPOINTPOSITION*((double)(posx[v] -minx))/ ((double) (maxx-minx)))+gap; posyv = MAXPOINTPOSITION - (int) (MAXPOINTPOSITION*((double)(posy[v] -miny))/ ((double) (maxy-miny)))+gap; getepscolor(epscolor,vcolor[v]); /* 45 eh o raio (ambos)*/ fprintf(fp,"n %d %d 45 45 0 360 DrawEllipse gs %s 1.00 shd ef gr \n", (int) posxv,(int) posyv,epscolor); } fprintf(fp,"$F2psEnd\n"); fprintf(fp,"rs\n"); fclose(fp); sprintf(cmd,"mv %s %s.eps",tempname,tempname); system(cmd); sprintf(cmd,"convert %s.eps %s.pdf",tempname,tempname); system(cmd); //sprintf(cmd,"%s %s.pdf",pdfreader.c_str(),tempname); system(cmd); str = tempname; str = str+".pdf"; view_pdffile(str); return(true); }
// This routine visualize a graph 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 ViewListGraph(ListGraph &g, NodeStringMap &vname, // name of the nodes EdgeStringMap &ename, // name of edges NodePosMap& px, // x-position of the nodes NodePosMap& py, // y-position of the nodes NodeColorMap& vcolor, // color of node (see myutils.h) EdgeColorMap& ecolor, // color of edge string text) // text displayed below the figure { char tempname[1000],cmd[1000],outputname[1000]; FILE *fp; double minpx=DBL_MAX,minpy=DBL_MAX,maxpx=-DBL_MAX,maxpy=-DBL_MAX,delta,factor; // obtain a temporary file name strcpy(tempname,".viewgraphtempname"); sprintf(outputname,"%s.pdf",tempname); fp = fopen(tempname,"w+"); if (fp==NULL) {cout << "Error to open temporary file to visualize graph.\n"; return(0);} for (NodeIt 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; // quanto maior, menor o desenho do vértice delta = fmax(maxpx - minpx,maxpy - minpy); // Generate a text file with the graph format of neato program fprintf(fp,"graph g {\n"); //fprintf(fp,"\tsize = \"10, 10\";\n"); //fprintf(fp,"\tnode [shape = \"circle\"];\n"); fprintf(fp,"\tnode [\n"); fprintf(fp,"shape = \"ellipse\",\n"); fprintf(fp,"style = \"bold\",\n"); fprintf(fp,"color = \"black\",\n"); fprintf(fp,"];\n"); for (NodeIt v(g); v!=INVALID; ++v) { if (vcolor[v]==NOCOLOR) continue; fprintf(fp,"\t%s [style = \"bold\", 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); } int nar=0; for (EdgeIt e(g); e!=INVALID; ++e) { nar++; if (ecolor[e]==NOCOLOR) continue; fprintf(fp,"\t%s -- %s [label = \"%s\", color=\"%s\" ];\n",vname[g.u(e)].c_str(),vname[g.v(e)].c_str(),ename[e].c_str(),ColorName(ecolor[e]).c_str()); //cout << "e_" << nar << " = ( " << vname[g.u(e)] << " , " << vname[g.v(e)] << ")\n"; } //cout << "\n\n\nColocou "<< nar << " arestas\n\n\n"; fprintf(fp,"label=\"%s\";\nfontsize=50;\n",text.c_str()); fprintf(fp,"}\n"); fclose(fp); sprintf(cmd,"neato -Tpdf %s -o %s",tempname,outputname); system(cmd); //cout << "Grafo em "<< tempname << "\n"; view_pdffile(outputname); //pause(); return(1); }
// This routine use the neato program to generate positions. bool GenerateVertexPositions(ListGraph &g, EdgeValueMap &custo, NodePosMap &posx, NodePosMap &posy) { size_t t=0; double x,y; char tempname[1000],tempnamedot[1000],tempnameposdot[1000],cmd[1000]; ofstream out; ifstream in; string linha,substring; (void) custo;// to avoid "non-used" parameter message. // obtain a temporary file name strcpy(tempname,".readgraphtempname"); strcpy(tempnamedot,tempname); strcat(tempnamedot,".dot"); strcpy(tempnameposdot,tempname);strcat(tempnameposdot,"_pos.dot"); out.open(tempnamedot); if (!out.is_open()) return(false); out << "graph g {\n"; out << "\tsize = \"11, 11\";\n"; out << "\tnode [shape = \"circle\"];\n"; for (NodeIt v(g); v!=INVALID; ++v) { linha = "\t"; linha += IntToString(g.id(v)); linha += ";\n"; out << linha; } for (EdgeIt a(g); a!=INVALID; ++a) { linha = "\t"; linha += IntToString(g.id(g.u(a))); linha += " -- "; linha += IntToString(g.id(g.v(a))); linha += ";\n"; out << linha; } out << "}\n"; out.close(); sprintf(cmd,"neato -Goverlap=false %s -o %s",tempnamedot,tempnameposdot); //printf("neato -Goverlap=false %s -o %s\n",tempnamedot,tempnameposdot); fflush(stdout); system(cmd); // gera outro arquivo do neato, mas com posições in.open(tempnameposdot); if (!in.is_open()) return(false); while (!in.eof()) { getline(in,linha); t = linha.find("{"); if (t!=string::npos) break; } if (t==string::npos) { cout << "Temp Graphviz file is not appropriate for GenerateVertexPositions.\n"; exit(0); } for (NodeIt v(g); v!=INVALID; ++v) { getline(in,linha); // avoid info on the graph, node or edges while ((!in.eof()) && ((linha.find("graph [")!=string::npos) || (linha.find("node [")!=string::npos) || (linha.find("edge [")!=string::npos) || (linha.find(" -- ")!=string::npos))) { while ((!in.eof()) && (linha.find("];")==string::npos)) { string linha2; getline(in,linha2); linha += linha2; } getline(in,linha); while ((!in.eof()) && (linha.find("[")==string::npos)) { string linha2; getline(in,linha2); linha += linha2; } } if (linha.find("[")!=string::npos) { while (linha.find("];")==string::npos) { string linha2; getline(in,linha2); linha += linha2; } } t = linha.find("pos=\""); if (t!=string::npos) { stringstream s; int nodeid; sscanf(linha.c_str(),"%d",&nodeid); substring = linha.substr(t+5); sscanf(substring.c_str(),"%lf,%lf",&x,&y); //printf("%lf , %lf",x,y); for (NodeIt vv(g); vv!=INVALID; ++vv) { if (nodeid==g.id(vv)){ posx[vv] = x; posy[vv] = y; //printf("interno: %d ( %lf , %lf )\n",g.id(vv),posx[vv],posy[vv]); break; } } } else { printf("GenerateVertexPositions: Error to obtain vertex coordinates.\n"); return(false); } } //for (NodeIt vv(g); vv!=INVALID; ++vv) { // printf(" %d ( %lf , %lf )\n",g.id(vv),posx[vv],posy[vv]); //} //printf("-------------------------------------------------------\n"); return(true); }
int main(int argc, char *argv[]) { int time_limit; char name[1000]; ListGraph g; EdgeWeight lpvar(g); EdgeWeight weight(g); NodeName vname(g); ListGraph::NodeMap<double> posx(g),posy(g); string filename; int seed=1; // uncomment one of these lines to change default pdf reader, or insert new one //set_pdfreader("open"); // pdf reader for Mac OS X //set_pdfreader("xpdf"); // pdf reader for Linux //set_pdfreader("evince"); // pdf reader for Linux srand48(seed); time_limit = 3600; // solution must be obtained within time_limit seconds if (argc!=2) {cout<< endl << "Usage: "<< argv[0]<<" <graph_filename>"<<endl << endl << "Example: " << argv[0] << " gr_berlin52" << endl << " " << argv[0] << " gr_att48" << endl << endl; exit(0);} else if (!FileExists(argv[1])) {cout<<"File "<<argv[1]<<" does not exist."<<endl; exit(0);} filename = argv[1]; // Read the graph if (!ReadListGraph(filename,g,vname,weight,posx,posy)) {cout<<"Error reading graph file "<<argv[1]<<"."<<endl;exit(0);} TSP_Data tsp(g,vname,posx,posy,weight); ListGraph::EdgeMap<GRBVar> x(g); GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); #if GUROBI_NEWVERSION model.getEnv().set(GRB_IntParam_LazyConstraints, 1); model.getEnv().set(GRB_IntParam_Seed, seed); #else model.getEnv().set(GRB_IntParam_DualReductions, 0); // Dual reductions must be disabled when using lazy constraints #endif model.set(GRB_StringAttr_ModelName, "Emparelhamento perfeito with GUROBI"); // name to the problem model.set(GRB_IntAttr_ModelSense, GRB_MAXIMIZE); // is a minimization problem // Add one binary variable for each edge and also sets its cost in //the objective function for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { sprintf(name,"x_%s_%s",vname[g.u(e)].c_str(),vname[g.v(e)].c_str()); x[e] = model.addVar(0.0, 1.0, weight[e],GRB_BINARY,name); } model.update(); // run update to use model inserted variables // Add degree constraint for each node (sum of solution edges incident to a node is 2) for (ListGraph::NodeIt v(g); v!=INVALID; ++v) { GRBLinExpr expr; for (ListGraph::IncEdgeIt e(g,v); e!=INVALID; ++e) expr += x[e]; //aqui model.addConstr(expr == 2 ); what? ignorou! model.addConstr(expr == 1); } try { model.update(); // Process any pending model modifications. if (time_limit >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,time_limit); model.update(); // Process any pending model modifications. model.write("model.lp"); system("cat model.lp"); model.optimize(); double soma=0.0; int i = 0; for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { lpvar[e] = x[e].get(GRB_DoubleAttr_X); if (lpvar[e] > 1-BC_EPS ) { soma += weight[e]; cout << "Achei, x("<< vname[g.u(e)] << " , " << vname[g.v(e)] << ") = " << lpvar[e] <<"\n"; tsp.BestCircuit[i] = g.u(e); tsp.BestCircuit[i+1] = g.v(e); i = i+2; } } cout << "Solution cost = "<< soma << endl; ViewTspCircuit(tsp); }catch (...) { if (tsp.BestCircuitValue < DBL_MAX) { cout << "Heuristic obtained optimum solution" << endl; ViewTspCircuit(tsp); return 0; }else { cout << "Graph is infeasible" << endl; return 1; } } }