Пример #1
0
// 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);
}
Пример #2
0
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;
}
Пример #5
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);}
  }
}
Пример #6
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);
}
Пример #7
0
//指定一些特殊分支,要求搜索一条路径时尽可能多的通过这些特殊分支
//例如:搜索一条串联通风路径(通过多个用风地点的一条路径)
//采用二分匹配实现失败!!!
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;
}
Пример #8
0
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);}
}
Пример #11
0
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;
                        }
                    }
                }
            }
        }
    }
}
Пример #12
0
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);
}
Пример #13
0
// 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;
    }
  }
}