Exemple #1
0
//Generate a random complete euclidean ListGraph
bool GenerateRandomEuclideanListGraph(ListGraph &g,
		  NodeStringMap &vname, // node names
		  NodePosMap& px, // x-position of the nodes
		  NodePosMap& py, // y-position of the nodes
		  EdgeValueMap& weight, // weight of edges
		  int n, // number of nodes
		  double SizeX, // coordinate x is a random number in [0,SizeX)
		  double SizeY) // coordinate y is a random number in [0,SizeY)
{
  int i,j; // n=number of nodes
  Node *V;
  V = new Node[n];
  if (V==NULL){
    cout << "Memory allocation error, number of nodes " << n << " too large\n";
    exit(0);}
  
  for (i=0;i<n;i++) {   // insert nodes (random points in [0,100] x [0,100] )
    V[i] = g.addNode(); // generate a new node
    px[V[i]] = SizeX*drand48();
    py[V[i]] = SizeY*drand48();
    vname[V[i]] = IntToString(i+1); // name of the node is i+1
  }
  for (i=0;i<n;i++)
    for (j=i+1;j<n;j++) {
      Edge e = g.addEdge(V[i],V[j]);  // generate an edge
      weight[e] = sqrt(pow(px[V[i]]-px[V[j]],2) + pow(py[V[i]]-py[V[j]],2));
    }
  delete[] V;
  return(true);
}
void ViewTspCircuit(TSP_Data &tsp)
{
  ListGraph h;
  ListGraph::NodeMap<string> h_vname(h);  // node names
  ListGraph::NodeMap<Node> h_g2h(tsp.g);  // maps a node of g to a node of h
  ListGraph::NodeMap<double> h_posx(h);
  ListGraph::NodeMap<double> h_posy(h);
  ListGraph::NodeMap<int> vcolor(h);   // color of the vertices
  ListGraph::EdgeMap<int> acolor(h);  // color of edges
  ListGraph::EdgeMap<string> aname(h);  // name of edges
  for (ListGraph::NodeIt v(tsp.g); v!=INVALID; ++v) {
    Node hv;
    hv = h.addNode();
    h_g2h[v] = hv;
    h_posx[hv] = tsp.posx[v];
    h_posy[hv] = tsp.posy[v];
    h_vname[hv] = tsp.vname[v];
    vcolor[hv] = BLUE;
  }
  for (int i=0;i<tsp.NNodes;i++) {
    ListGraph::Node u,v;
    ListGraph::Edge a;
    u = tsp.BestCircuit[i]; 
    v = tsp.BestCircuit[(i+1) % tsp.NNodes]; 
    a = h.addEdge(h_g2h[u] , h_g2h[v]);
    aname[a] = "";
    acolor[a] = BLUE;
  }
  ViewListGraph(h,h_vname,aname,h_posx,h_posy,vcolor,acolor,"TSP Circuit with cost "+DoubleToString(tsp.BestCircuitValue));
}
Exemple #3
0
int ViewGomoryHuTree(ListGraph &g,
		     NodeStringMap &vname,
		     NodePosMap &px,  // xy-coodinates for each node
		     NodePosMap &py,  // 
		     GomoryHu<ListGraph, EdgeValueMap > &ght,
		     string text)
{
  ListGraph T;
  NodeNodeMap map(g);
  Edge te;
  EdgeStringMap tename(T);  // name of T edges
  EdgeValueMap teweight(T);  // name of T edges
  NodeStringMap tvname(T);  // name of T nodes
  NodePosMap tpx(T);  // xy-coodinates for each node
  NodePosMap tpy(T);  // 
  NodeColorMap tvcolor(T);   // color of the vertices
  EdgeColorMap tecolor(T);  // color of the edges
  
  for (NodeIt v(g); v != INVALID; ++v) {
    map[v] = T.addNode();
    tvname[map[v]] = vname[v];
    tvcolor[map[v]] = WHITE;
    tpx[map[v]] = px[v];
    tpy[map[v]] = py[v];
  }
  for (NodeIt u(g); u != INVALID; ++u) {
    if ((g).id(ght.predNode(u))==-1) continue;
    te = T.addEdge(map[u], map[ght.predNode(u)]);
    tename[te] = DoubleToString(ght.predValue(u));
    teweight[te] = ght.predValue(u);
    tecolor[te] = BLUE;
  }
  return(ViewListGraph(T,tvname,tename,tpx,tpy,tvcolor,tecolor,text));
}
Exemple #4
0
int ViewGomoryHuTree(ListGraph &g,
		     NodeStringMap& vname,
		     GomoryHu<ListGraph,
		     EdgeValueMap > &ght,
		     double threshold,
		     string text)
{
  ListGraph T;
  NodeNodeMap map(g);
  Edge te;
  EdgeStringMap tename(T);  // name of T edges
  NodeStringMap tvname(T);  // name of T nodes
  NodeColorMap tvcolor(T);   // color of the vertices
  EdgeColorMap tecolor(T);  // color of the edges
  
  for (NodeIt v(g); v != INVALID; ++v) {
    map[v] = T.addNode();
    tvname[map[v]] = vname[v];
    tvcolor[map[v]] = BLACK;
  }
  for (NodeIt u(g); u != INVALID; ++u) {
    if ((g).id(ght.predNode(u))==-1) continue;
    te = T.addEdge(map[u], map[ght.predNode(u)]);
    tename[te] = DoubleToString(ght.predValue(u));
    if (ght.predValue(u)<threshold-MY_EPS)
      tecolor[te] = RED;
    else
      tecolor[te] = BLUE;
  }
  return(ViewListGraph(g,tvname,tename,tvcolor,tecolor,text));
}
Exemple #5
0
ExtendedEdge::ExtendedEdge(ListGraph &g, ListGraph::Node u,
                           ListGraph::Node v, int pos_u, int pos_v){
    _adjacentNodes.push_back(g.id(u));
    _adjacentNodes.push_back(g.id(v));
    _adjacentNodesPos.push_back(pos_u);
    _adjacentNodesPos.push_back(pos_v);
    edge = g.addEdge(u,v);
    _id = g.id(edge);
    _length = 0;
}
Exemple #6
0
// Generate a triangulated ListGraph, building the Delaunay
// triangulation of random points
// Uses the geompack program, available in
// http://people.sc.fsu.edu/~jburkardt/cpp_src/geompack/geompack.html
bool GenerateTriangulatedListGraph(ListGraph &g, // return with generated graph
			  NodeStringMap &vname, // return with name of the nodes
			  NodePosMap& px, // return with x-position of the nodes
			  NodePosMap& py, // return with y-position of the nodes
			  EdgeValueMap& weight, // return with weight of edges
			  int n, // number of nodes 
			  double SizeX, // coordinate x is a random number in [0,SizeX)
			  double SizeY) // coordinate y is a random number in [0,SizeY)
{
  int i; // n=number of nodes
  int ntri; // number of Delaunay triangles
  Node *V = new Node[n];
  double *p = new double[2*n+2];// node coodinates are (x;y) = ( p[2*i] ; p[2*i+1] )
  int *tri = new int[6*n]; // Each 3 elements are the indexes of a triangle
  int *tri_nabe = new int[6*n];
  
  if ((V==NULL)||(p==NULL)||(tri==NULL)||(tri_nabe==NULL)){
    cout << "Memory allocation error, number of nodes " << n << " too large\n";
    exit(0);}

  for (i=0;i<n;i++) {
    V[i] = g.addNode();    // gera um vértice nó do grafo 
    px[V[i]] = SizeX*drand48();  // nodes are random points
    py[V[i]] = SizeY*drand48();
    p[2*i]   = px[V[i]];
    p[2*i+1] = py[V[i]];
    vname[V[i]] = IntToString(i+1);  // name of the node is i+1
  }
  if (r8tris2 ( n, p, &ntri, tri,  tri_nabe )) {  printf("ERROR\n");Pause(); }
  for (i=0;i<ntri;i++) { 
    int a,b,c;
    a = tri[3*i]-1; b = tri[3*i+1]-1; c = tri[3*i+2]-1;
    // each triangle if formed with nodes  V[a] , V[b] , V[c]
    // insert edges without duplications
    if ((findEdge(g,V[a],V[b])==INVALID) && (findEdge(g,V[b],V[a])==INVALID)){
      Edge e = g.addEdge(V[a],V[b]);  
      weight[e] = sqrt(pow(px[V[a]]-px[V[b]],2) + pow(py[V[a]]-py[V[b]],2));
    }
    if ((findEdge(g,V[a],V[c])==INVALID)  && (findEdge(g,V[c],V[a])==INVALID)){
      Edge e = g.addEdge(V[a],V[c]);  
      weight[e] = sqrt(pow(px[V[a]]-px[V[c]],2) + pow(py[V[a]]-py[V[c]],2));
    }
    if ((findEdge(g,V[b],V[c])==INVALID) && (findEdge(g,V[c],V[b])==INVALID)) {
      Edge e = g.addEdge(V[b],V[c]);  
      weight[e] = sqrt(pow(px[V[b]]-px[V[c]],2) + pow(py[V[b]]-py[V[c]],2));
    }
  }
  delete[] V;
  delete[] p;
  delete[] tri;
  delete[] tri_nabe;
  return(true);
}
int main( void ){

    Timer   T(true);
    
    int init_nodes_num, final_nodes_num, edge_addition_num;
    
    init_nodes_num      = 10;
    final_nodes_num     = 50;
    edge_addition_num   = 7;
    
    typedef ListEdgeSet< ListGraph >    EdgeSet;
    ListGraph                           mListGraph;
    EdgeSet                             mNewEdges( mListGraph );
    FullGraph                           fg(init_nodes_num);
    
    GraphCopy<FullGraph, ListGraph>     cg( fg, mListGraph); // Create the seed nodes
    cg.run();
    
    int mNumEdges   = countEdges( mListGraph );
    EdgeSet::Edge e;
    lemon::Random   mRandom;
    mRandom.seedFromTime();
    ListGraph::Node newNode, randNode;
    
    // new edges will be saved seperatly in an EdgeSet, not to change the original node degrees
    for ( int i = init_nodes_num; i < final_nodes_num; i++){
        mNumEdges   = countEdges( mListGraph );
        mNewEdges.clear();
        newNode     = mListGraph.addNode();

        while ( countEdges( mNewEdges ) != edge_addition_num ) {
            randNode = mListGraph.nodeFromId( mRandom[ mListGraph.maxNodeId() ] ) ;
            // --- CALCULATE THE PROBABILITY
            if ( mRandom.real() < (( (double)(countIncEdges(mListGraph, randNode)) / (double)( 2*mNumEdges ) )) ){
                if ( findEdge( mNewEdges, newNode, randNode ) == INVALID){ // does the edge already exist?
                    mNewEdges.addEdge(  newNode, randNode );
                }
            }
        }
        
        // Create the new edges in the original graph
        for (EdgeSet::EdgeIt e( mNewEdges ); e!=INVALID; ++e){
            mListGraph.addEdge( mNewEdges.u( e ), mNewEdges.v(e) );
        }
    }
    
    cout << T.realTime() << endl;
    
    cout << countEdges( mListGraph) << endl;
    cout << countEdges( fg ) << endl;
    
 }
MatrixGraph::MatrixGraph(const ListGraph& listGraph) {
  int edgesCount = listGraph.edgesCount();
  int vertexCount = listGraph.vertexCount();
  iMatrix = vector<vector<int> >(vertexCount, vector<int>(edgesCount, 0));
  int edge = 0;
  for (int i = 0; i < vertexCount; ++i) {
    for (auto v : listGraph.getLists()[i]) {
      iMatrix[i][edge] = -1;
      iMatrix[v][edge] = 1;
      ++edge;
    }
  }
}
Exemple #9
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");
}
Exemple #10
0
void ReadListGraphEdges(ListGraph &g,int nedges,ifstream & ifile,
#if __cplusplus >= 201103L
			std::unordered_map<string,Node> & string2node,
#else
			std::tr1::unordered_map<string,Node> & string2node,
#endif
			EdgeValueMap &weight)
{
  Node u,v;
  Edge a;
  string nomeu,nomev;
  double peso;
  for (int i=0;i<nedges;i++) {
    // format: <node_u>   <node_v>   <edge_weight>
    ifile >> nomeu;  ifile >> nomev; ifile >> peso;
    if (ifile.eof()) 
      {cout << "Reached unexpected end of file.\n"; exit(0);}
    auto test = string2node.find(nomeu);
    if (test == string2node.end()) {cout<<"ERROR: Unknown node: "<<nomeu<<endl;exit(0);}
    else u = string2node[nomeu];
    
    test = string2node.find(nomev);
    if (test == string2node.end()) {cout<<"ERROR: Unknown node: "<<nomev<<endl;exit(0);}
    else v = string2node[nomev];
    a = g.addEdge(u,v);
    weight[a] = peso;
  }
}
Exemple #11
0
// To read list of nodes in the format: <node_name>  <double1>  <double2>
void ReadListGraphNodes(ListGraph &g,int nnodes,ifstream & ifile,
#if __cplusplus >= 201103L
    std::unordered_map<string,Node> & string2node,
#else
    std::tr1::unordered_map<string,Node> & string2node,
#endif
			   NodeStringMap &vname,
			   NodePosMap  &posx,
			   NodePosMap  &posy)
{ string STR;  Node u,v;  string token;
  for (int i=0;i<nnodes;i++) {
    getline(ifile,STR);
    if (ifile.eof()) {cout<<"Reached unexpected end of file.\n";exit(0);}
    while (STR=="") getline(ifile,STR);
    { istringstream ins; // Declare an input string stream.
      ins.str(STR);        // Specify string to read.
      for (int p=0; getline(ins, token, ' ') ; p++) {
	if (p==0) {   // For example, to read:   node_name   posx   posy
	  auto test = string2node.find(token);
	  if (test!=string2node.end()){cout<<"ERROR: Repeated node: "<<token<<endl;exit(0);}
	  v = g.addNode(); string2node[token] = v; vname[v] = token;
	  posx[v]=DBL_MAX;  posy[v]=DBL_MAX; }
	else if (p==1) { posx[v] = atof(token.c_str());}
	else if (p==2) { posy[v] = atof(token.c_str());}
      }}
  }
}
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);}
}
Exemple #13
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);
}
Exemple #14
0
/**
	second relaxation of tsp
	idea:
		remove some (random) node
		take mst
		add shortest two edges of the removed node
*/
int TSPRelaxation::mstOnSubgraph()
{
	// create a copy of the graph
	ListGraph g;
	ListGraph::EdgeMap<int> weight(g);
	ListGraph::NodeMap<ListGraph::Node> nodemap(g);
	
	GraphCopy<ListGraph, ListGraph> copy(this->g, g);
	copy.edgeMap(this->weight, weight).nodeCrossRef(nodemap).run();
	
	// remove a random node
	// removed will contain the node of this->g corresponding to the removed one afterwards
	int del = rand() % countNodes(g);
	ListGraph::Node removed;
	for (ListGraph::NodeIt n(g); n != INVALID; ++n)
	{
		if (del == 0)
		{
			removed = nodemap[n];
			g.erase(n);
			break;
		}
		del--;
	}
	
	// calculate mst
	MST mst(g, weight);
	int w = mst.prim();
	
	// search for two shortest edges incident to the removed node
	int mins[] = {numeric_limits<int>::max(), numeric_limits<int>::max()};
	for (ListGraph::IncEdgeIt e(this->g, removed); e != INVALID; ++e)
	{ // iterate over all incident nodes
		if (this->weight[e] < mins[0])
		{ // shortest found yet
			mins[1] = mins[0];
			mins[0] = this->weight[e];
		}
		// 2nd-shortest
		else if (this->weight[e] < mins[1]) mins[1] = this->weight[e];
	}
	
	return w + mins[0] + mins[1];
}
Exemple #15
0
bool ReadEuclideanListGraph(string filename,
			    ListGraph &g,
			    NodeStringMap & vname,
			    EdgeValueMap  & custo,
			    NodePosMap    & posx,
			    NodePosMap    & posy,
                NodeBoolMap& is_terminal)
{
  int i,n,m, terminal;
  Node nu,nv;
  Edge a;
  char nomev[100];
  Node v;
  double px,py;
  
  ifstream ifile;  ifile.open(filename.c_str());  if (!ifile) return(false);
  PulaBrancoComentario(ifile);
  // format: <number_of_nodes>   -1
  // The value -1 is to indicate that there is no edge/arc, as edge weights
  // are given by the euclidean distance
  ifile >> n;    ifile >> m;
  if (m!=-1) {
    printf("Wrong format in the euclidean graph of file %s.\n",filename.c_str());
    return(false);
  }
  for (i=0;i<n;i++) {
    ifile >> nomev;  ifile >> px; ifile >> py; ifile >> terminal;
    v = g.addNode();    vname[v] = nomev;    posx[v] = px;    posy[v] = py;
      if(terminal == 0) is_terminal[v] = false;
      else is_terminal[v] = true;
  }

  for (NodeIt v(g); v!=INVALID; ++v) {
    NodeIt u(g);
    u=v;
    for (++u; u!=INVALID; ++u) {
      a = g.addEdge(u,v);
      custo[a] = sqrt((posx[u]-posx[v])*(posx[u]-posx[v]) + 
		      (posy[u]-posy[v])*(posy[u]-posy[v]));
    }
  }
  ifile.close();
  return(true);
}
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;
}
Exemple #17
0
int main( void ){
    
    Timer   T(true);
    
    int final_nodes_num, edge_addition_num;
    final_nodes_num     = 30000;
    edge_addition_num   = 7;
    
    ListGraph                           mGr;
    lemon::Random   mRandom;
    mRandom.seedFromTime();
    
    vector<int> nodeChoice;
    set<int>    mRndNodes;
    vector<int> targets(edge_addition_num, -1);
    int currentIndex = 0;
    
    // First targets are all nodes
    for(auto &v : targets){
        v = currentIndex++;
        mGr.addNode();
    }

    while (countNodes(mGr)<final_nodes_num ) {
        // Add new node and connect to targets
        currentIndex =  mGr.id( mGr.addNode() );
        for(const auto &v : targets ){
            mGr.addEdge( mGr.nodeFromId( currentIndex ), mGr.nodeFromId( v ) );
        }
        // Add the nodes, which were connented again
        nodeChoice.insert(nodeChoice.end(), targets.begin(), targets.end() );
        nodeChoice.insert(nodeChoice.end(), edge_addition_num, currentIndex);
        
        mRndNodes.clear();
        while (mRndNodes.size() < edge_addition_num) {
            mRndNodes.insert( nodeChoice[ mRandom.integer( nodeChoice.size() ) ] );
        }
        targets.clear();
        targets.insert(targets.begin(), mRndNodes.begin(), mRndNodes.end() );
    }
    
    cout << "time: " << T.realTime() << endl;
    cout << countNodes( mGr) << endl;
    cout << countEdges( mGr) << endl;
    
    
    graphWriter( mGr, "/Users/sonneundasche/Documents/FLI/DATA/05 LEMON Graphs/BaraBasiTEST.txt")
    .run();
    
    InDegMap<ListGraph>     inDeg(mGr);

    graphWriter( mGr, "/Users/sonneundasche/Documents/FLI/DATA/05 LEMON Graphs/BaraBasi_Degree_TEST.txt")
    .nodeMap("degree", inDeg)
    .skipEdges()
    .run();
    
  }
Exemple #18
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);}
  }
}
TEST_F(ClusteringCoefficientTest, AcyclicGraphTest)
{
    ListGraph ig;
    //Create vertex
    Vertex* x = new Vertex(1);

    //create neighbor vertices
    Vertex* v1 = new Vertex(2);
    Vertex* v2 = new Vertex(3);
    Vertex* v3 = new Vertex(4);
    Vertex* v4 = new Vertex(5);

    ig.addVertex(x);
    ig.addVertex(v1);
    ig.addVertex(v2);
    ig.addVertex(v3);
    ig.addVertex(v4);
    ig.addEdge(x, v1);
    ig.addEdge(x, v2);
    ig.addEdge(x, v3);
    ig.addEdge(v4, x);;

    typedef ClusteringCoefficient<ListGraph, Vertex> Clustering;
    typedef Clustering::Coefficient Coef;
    Clustering clustering;

    Coef c = clustering.vertexClusteringCoefficient(x);

    Coef epsilon = 0.001;

    ASSERT_TRUE(fabs(c - 0.0) <  epsilon);

    Coef c2 = clustering.clusteringCoefficient(ig, Vertex::Degree(4));
    ASSERT_TRUE(fabs(c2 - 0.0) <  epsilon);
}
Exemple #20
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);
}
int mai() {

	//RandGraphGen gen = *(new RandGraphGen(7, 100, 5, true));
	//gen.generate();
	//gen.saveToFile("testPrimKruskal");

	ListGraph mxg = *(new ListGraph());
	ListGraph mxgW1 = *(new ListGraph());
	ListGraph mxgW2 = *(new ListGraph());

	mxg.open("testPrimKruskal");
	std::cout << mxg << std::endl;

	std::cout << "Prim:\n";
	try {
		mxg.Prim(mxgW1);
		std::cout << mxgW1 << std::endl;
	}
	catch (std::runtime_error err) {
		std::cout << err.what() <<std::endl;
	}
	
	
	std::cout << "Kruskal:\n";
	try {
		mxg.Kruskal(mxgW2);
		std::cout << mxgW2 << std::endl;
	}
	catch (std::runtime_error err) {
		std::cout << err.what() << std::endl;
	}


  	std::cin.get();
	return 0;
}
std::vector<bool>balanced_min_cut(const ListGraph&g){
	assert(g.is_valid());

	#ifndef USE_CUT_ORDER
	return {};
	#else

	std::vector<int>out_begin;
	std::vector<int>out_dest;

	build_adj_array(out_begin, out_dest, 
		g.node_count(), g.arc.size(),
		[&](int x){return g.arc[x].source;},
		[&](int x){return g.arc[x].target;}
	);

	std::vector<int>part(g.node_count());

	// Call METIS
	int one = 1, two = 2, ignore, node_count = g.node_count();

	idx_t options[METIS_NOPTIONS];
	METIS_SetDefaultOptions(options);
	options[METIS_OPTION_NUMBERING] = 0;

	options[METIS_OPTION_CONTIG] = 1;
	options[METIS_OPTION_UFACTOR] = 100;

	//options[METIS_OPTION_NCUTS] = 10;

	METIS_PartGraphKway(
		(idx_t*)&node_count,
		(idx_t*)&one,
		(idx_t*)&out_begin[0],
		(idx_t*)&out_dest[0],
		nullptr,
		nullptr,
		nullptr,
		(idx_t*)&two,
		nullptr,
		nullptr,
		options,
		(idx_t*)&ignore,
		(idx_t*)&part[0]
	);

	std::vector<bool>part_ret(g.node_count());
	for(int i=0; i<g.node_count(); ++i)
		part_ret[i] = part[i] == 0;

	return std::move(part_ret);
	#endif
}
Exemple #23
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;
}
Exemple #24
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;
                        }
                    }
                }
            }
        }
    }
}
Exemple #25
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;
}
Exemple #26
0
int
HeuristicGroupTSP(ListGraph &g,  ListGraph::EdgeMap<double>& weights, vector<
                  set<ListGraph::Node> > &S, vector<ListGraph::Node> &sol, long
                  max_time,  double &best_time,  double &LB, string &alg_info)
{
  /**
   * Computa solucao heuristica para o Group TSP.
   *
   * Entrada:
   * @param   g           grafo simples utilizado
   * @param   weights     pesos das arestas
   * @param   S           vetor de grupos de vertices (ver def. do problema)
   * @param   max_time    tempo maximo (em seg) que o procedimento deve ocorrer
   *
   * Saida:
   * @param   sol         sequencia de vertices que representa ciclo
   * @param   best_time   momento em que solucao atual foi encontrada
   * @param   LB          limite inferior encontrado para custo otimo
   * @param   alg_info    informacoes de execucao do algoritmo, ex: cadeia de
   *                      heuristicas utilizadas
   *
   * @return          0 = nao foi possivel encontrar solucao
   *                  1 = solucao encontrada, mas nao necessariamente otima
   *                  2 = solucao otima encontrada
   */

  // Sample Algorithm
  // Until solution is not integral, sets highest variable to its closest
  // integer value.

  // Variables
  GroupTSPLPSolver::ReturnType rettype = GroupTSPLPSolver::OPTIMAL_FRACTIONARY;
  GroupTSPLPSolver solver(g, weights, S);
  ListGraph::NodeMap<double> lpsol_vertex(g);
  ListGraph::EdgeMap<double> lpsol_edge(g);
  ListGraph::NodeMap<bool> already_set(g, false);
  double objVal = 0;
  time_t start = time(NULL);

  LB = -1;

  // main loop
  cout << "STARTING\n";
  while (rettype == GroupTSPLPSolver::OPTIMAL_FRACTIONARY) {
    cout << "Solving..\n";
    rettype = solver.getSolution(lpsol_vertex, lpsol_edge, objVal);

    if (fabsl(LB - (-1)) < EPS) {
      LB = objVal;
    }


    if (rettype == GroupTSPLPSolver::OPTIMAL_FRACTIONARY) {
      // Round highest variable to closest value.
      double mx = -1;
      Node mx_idx=INVALID;

      for(NodeIt v(g); v!=INVALID; ++v) {
        if (!already_set[v]) {
          if (lpsol_vertex[v] > mx) {
            mx = lpsol_vertex[v];
            mx_idx = v;
          }
        }
      }

      if (mx_idx != INVALID) {
        // int val = (lpsol_vertex[mx_idx] > 0.5 ? 1 : 0);
        int val = calculateIntegralWithProportionalProbability(lpsol_vertex[mx_idx]);
        cout << "Fixing " << g.id(mx_idx) << " to " << val << "\n";
        solver.fixNodeVariable(mx_idx, val);
        already_set[mx_idx] = true;
      } else {
        // it seems we were unable to obtain a solution with integral x[e]
        break;
      }
    }
  }

  // OBTAIN SOLUTION
  best_time = time(NULL) - start;
  if (rettype != GroupTSPLPSolver::OPTIMAL_INTEGRAL) {
    return 0;
  } else {
    /* do dfs to find out the answer */
    ListGraph::NodeMap<bool> vis(g, false);

    for(ListGraph::NodeIt v(g); v != INVALID; ++v) {
      if ( lpsol_vertex[v] > 1.0 - EPS ) {
        queue<ListGraph::Node> q;
        vis[v] = true;
        q.push(v);

        while (!q.empty()) {
          ListGraph::Node u = q.front(); q.pop();
          sol.push_back(u);

          for(ListGraph::IncEdgeIt e(g, u); e != INVALID; ++e) {
            ListGraph::Node w = g.runningNode(e);
            if (lpsol_edge[e] > 1.0 - EPS && !vis[w]) {
              vis[w] = true;
              q.push(w);
              /* only pick one! */
              break;
            }
          }
        }

        break;
      }
    }

    // check if there are vertices outside the cycle
    for(NodeIt v(g); v != INVALID; ++v) {
      if (lpsol_vertex[v] > 1-EPS && !vis[v]) {
        sol.clear();
        return 0;
      }
    }
    return fabsl(objVal - LB) < EPS ? 2 : 1;
  }
}
Exemple #27
0
    void callback()
    { // --------------------------------------------------------------------------------
    // get the correct function to obtain the values of the lp variables
    if  (where==GRB_CB_MIPSOL) // if this condition is true, all variables are integer
        {solution_value = &subtourelim::getSolution;}
    else if ((where==GRB_CB_MIPNODE) &&  
        (getIntInfo(GRB_CB_MIPNODE_STATUS)==GRB_OPTIMAL))// node with optimal fractional solution
        {solution_value = &subtourelim::getNodeRel;}
    else return; // return, as this code do not take advantage of the other options
    // --------------------------------------------------------------------------------
    // Stores the edges with fractional values and integer values
    vector<Edge> FracEdges,OneEdges;
    // produces a subgraph h of g, with edges e with x[e]==1 
    // contracted, so we can apply Gomory-Hu tree in a small graph
    ListGraph::EdgeMap<bool> one_filter(tsp.g, false); // start without any edge
    ListGraph::EdgeMap<bool> non_zero_filter(tsp.g, false); // start without any edge
    for (EdgeIt e(tsp.g); e != INVALID; ++e) {
        if ((this->*solution_value)(x[e]) > 1-MY_EPS)
            OneEdges.push_back(e); // stores the edges with x[e]==1
        else if ((this->*solution_value)(x[e]) > MY_EPS)
            FracEdges.push_back(e); // includes edges with 0 < x[e] < 1
    }// define the subgraph with edges that have x[e]==1

    try {
        // --------------------------------------------------------------------------------
        // Use union-find to contract nodes (to obtain graph where each componente of g is contracted)
        //for (int i=0;i<tsp.NNodes;i++) UFIndexToNode[i]=INVALID;
        ListGraph::NodeMap<int> aux_map(tsp.g);
        UnionFind<ListGraph::NodeMap<int> > UFNodes(aux_map);
        for (NodeIt v(tsp.g); v!=INVALID; ++v) UFNodes.insert(v);
        for (vector<Edge>::iterator e_it=OneEdges.begin(); e_it != OneEdges.end(); ++e_it)
            UFNodes.join(tsp.g.u(*e_it),tsp.g.v(*e_it));// No problem if they are in a same component
        // --------------------------------------------------------------------------------
        // Put in a separate set all edges that are not inside a component 
        vector<Edge> CrossingEdges;
        for (EdgeIt e(tsp.g); e != INVALID; ++e) 
        if (UFNodes.find(tsp.g.u(e)) != UFNodes.find(tsp.g.v(e)))
            CrossingEdges.push_back(e);
        // --------------------------------------------------------------------------------
        // Generate an inverted list UFIndexToNode to find the node that represents a component
        vector<bool> ComponentIndex(tsp.NNodes);
        vector<Node> Index2h(tsp.NNodes);
        for(int i=0;i<tsp.NNodes;i++) ComponentIndex[i]=false;
        for (NodeIt v(tsp.g); v!=INVALID; ++v) ComponentIndex[UFNodes.find(v)]=true;
        // --------------------------------------------------------------------------------
        // Generate graph of components, add one node for each component and edges
        ListGraph h;
        EdgeValueMap h_capacity(h); 
        for(int i=0;i<tsp.NNodes;i++)  // add nodes to the graph h
            if (ComponentIndex[i]) Index2h[i]=h.addNode(); 
        for (vector<Edge>::iterator e_it=FracEdges.begin(); e_it != FracEdges.end(); ++e_it){
            Node  u = tsp.g.u(*e_it),              v = tsp.g.v(*e_it),
            hu = Index2h[UFNodes.find(u)],   hv = Index2h[UFNodes.find(v)];
            Edge a = h.addEdge(hu , hv );         // add edges to the graph h
            h_capacity[a] = (this->*solution_value)(x[*e_it]);
        }
        // create a map to terminals
        NodeBoolMap HasTerminal(h);
        for (NodeIt uit(tsp.g); uit!=INVALID; ++uit)
        {
            // if it is not a station
            if(!postos[uit]) 
            {
                HasTerminal[Index2h[UFNodes.find(uit)]] = true;
            }
        }
        // add the source to the 'terminal'
        HasTerminal[Index2h[UFNodes.find(source)]] = true;
        // --------------------------------------------------------------------------------
        GomoryHu<ListGraph, EdgeValueMap> ght(h, h_capacity);   ght.run();
        // The Gomory-Hu tree is given as a rooted directed tree. Each node has
        // an arc that points to its father. The root node has father -1.
        // Remember that each arc in this tree represents a cut and the value of
        // the arc is the weight of the corresponding cut. So, if an arc has weight
        // less than 2, then we found a violated cut and in this case, we insert the
        // corresponding constraint.

        NodeBoolMap cutmap(h);
        for (NodeIt u(h); u != INVALID; ++u) {
            GRBLinExpr expr = 0;
            if (ght.predNode(u)==INVALID) continue; // skip the root node
            if (ght.predValue(u) > 2.0 - MY_EPS) continue; // value of the cut is good
            
            // this cut violate this conditions
            // check if there is a terminal in both components
            if (HasTerminal[u] && HasTerminal[ght.predNode(u)])
            {
                ght.minCutMap(u, ght.predNode(u), cutmap);  // now, we have a violated cut
            
                // Percorre as arestas que cruzam alguma componente e insere as que pertencem ao corte
                for (vector<Edge>::iterator e_it=CrossingEdges.begin();e_it!=CrossingEdges.end();++e_it){
                    Node u=tsp.g.u(*e_it), v=tsp.g.v(*e_it),
                    hu = Index2h[UFNodes.find(u)], hv=Index2h[UFNodes.find(v)];
                    if (cutmap[hu] != cutmap[hv])
                    expr += x[*e_it];
                }
                addLazy( expr >= 2 );
            }
        }

        // Insere a restricao de sub caminho -------------------------------
        // -----------------------------------------------------------------
        // Mapeia as arestas da solucao
        int uncovered = 0;
        EdgeBoolMap covered(tsp.g, false);
        EdgeBoolMap active(tsp.g, false);
        for (EdgeIt a(tsp.g); a!=INVALID; ++a)
        {
            if (getSolution(x[a]) > 1 - MY_EPS)
            {
                active[a] = true;
                uncovered++;
            }
            else
            {
                active[a] = false;
            }
        }
        
        // -----------------------------------------------------------------
        // Percorre os caminhos e insere as restricoes de consumo
        GRBLinExpr expr = 0;
        Node u = source;
        bool changed = false;
        while (uncovered > 0)
        {
            // u := vertice atual
            // v := vertice destino
            // a := arco percorrido
            for (ListGraph::IncEdgeIt ait(tsp.g,u); ait!=INVALID; ++ait)
            {
                // verifica se o arco esta na solucao
                Edge a(ait);
                if (active[a] && !covered[a])
                {
                    // soma a distancia percorrida
                    changed = true;
                    expr += x[a]*tsp.weight[a];
                    
                    // verifica se o node destino e um posto
                    Node v = tsp.g.v(a);
                    if (u == v) 
                    {
                        v = tsp.g.u(a);
                    }
                    if (postos[v])
                    {
                        // se for um posto, termina aqui uma restricao de consumo
                        addLazy( expr <= delta);
                        expr = 0;
                    }
                    
                    // atualiza o valor do vertice atual e diminui as arestas
                    // que ainda nao foram cobertas
                    u = v;
                    covered[a] = true;
                    uncovered--;
                    break;                        
                }
            }

            // check the changed
            if (changed) 
            {
                changed = false;
            }
            else // it is a dead end 
            {
                break;
            }
        }
        // cout << "TERMINANDO CALLBACK" << endl;
    } catch (...) {
      cout << "Error during callback..." << endl;
    }
  }
Exemple #28
0
// ATENÇÃO: Não modifique a assinatura deste método.
bool brach_and_bound999999(TSP_Data_R &tsp, const vector<DNode> &terminais, const vector<DNode> &postos,
                           const DNode source,
                           int delta, int maxTime, vector<DNode> &sol, double &lbound){
    // Converte o TSP direcionado para um nao direcionado com duas arestas
    ListGraph graph;
    EdgeValueMap weights(graph);

    // Adiciona os nos
    for (ListDigraph::NodeIt u(tsp.g); u!=INVALID; ++u)
    {
        Node v = graph.addNode();
    }

    // Adiciona as arestas
    for (ListDigraph::ArcIt ait(tsp.g); ait!=INVALID; ++ait)
    {
        // pega os dois nos incidentes
        Arc a(ait);
        DNode u = tsp.g.source(a);
        DNode v = tsp.g.target(a);

        // cria a mesma aresta no grafo não direcionado
        Node gu = graph.nodeFromId(tsp.g.id(u));
        Node gv = graph.nodeFromId(tsp.g.id(v));

        // insere a aresta no grafo nao direcionado
        Edge e = graph.addEdge(gu, gv);
        
        // Atribui pesos as arestas
        weights[e] = tsp.weight[a];
    }

    NodeStringMap nodename(graph);
    NodePosMap posicaox(graph);
    NodePosMap posicaoy(graph);

    TSP_Data utsp(graph, nodename, posicaox, posicaoy, weights);

    // utiliza o convertido
    ListGraph::EdgeMap<GRBVar> x(graph);
    GRBEnv env = GRBEnv();
    GRBModel model = GRBModel(env);

    // TODO: [Opcional] Comente a linha abaixo caso não queira inserir cortes durante a execução do B&B
    model.getEnv().set(GRB_IntParam_LazyConstraints, 1);

    model.getEnv().set(GRB_IntParam_Seed, 0);
    model.set(GRB_StringAttr_ModelName, "TSPR - TSP with Refueling"); // name to the problem
    model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem

    // Add one binary variable for each arc and also sets its cost in the objective function
    for (EdgeIt e(utsp.g); e!=INVALID; ++e) {
        char name[100];
        
        Edge edge(e);
        unsigned uid = utsp.g.id(utsp.g.u(edge));
        unsigned vid = utsp.g.id(utsp.g.v(edge));

        sprintf(name,"x_%s_%s",tsp.vname[tsp.g.nodeFromId(uid)].c_str(),tsp.vname[tsp.g.nodeFromId(vid)].c_str());
        x[e] = model.addVar(0.0, 1.0, utsp.weight[e],GRB_BINARY,name);
    }
    model.update(); // run update to use model inserted variables

    // converte os terminais e os postos
    vector<Node> uterminais;
    for (auto t : terminais)
    {
        unsigned tid = tsp.g.id(t);
        uterminais.push_back(utsp.g.nodeFromId(tid));
    }

    NodeBoolMap upostos(utsp.g, false);
    for (auto p: postos)
    {
        unsigned pid = tsp.g.id(p);
        // upostos.push_back(utsp.g.nodeFromId(pid));
        upostos[utsp.g.nodeFromId(pid)] = true;
    }

    // Adicione restrições abaixo

    // (1) Nós terminais devem ser visitados exatamente uma vez
    for (auto v : uterminais) {
        GRBLinExpr expr = 0;
        for (IncEdgeIt e(utsp.g,v); e!=INVALID; ++e){
            expr += x[e];
        }
        model.addConstr(expr == 2 );
    }

    // (3) Nó source sempre presente no início do caminho
    Node usource = utsp.g.nodeFromId(tsp.g.id(source));
    GRBLinExpr expr = 0;
    for (IncEdgeIt e(utsp.g,usource); e!=INVALID; ++e){
        expr += x[e];
    }
    model.addConstr(expr >= 1 );

    try {
        model.update(); // Process any pending model modifications.
        //if (maxTime >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,maxTime);

        subtourelim cb = subtourelim(utsp , x, usource, upostos, delta);
        model.setCallback(&cb);

        // TODO: [Opcional] Pode-se utilizar o valor de uma solução heurística p/ acelerar o algoritmo B&B (cutoff value).
        //cutoff = tsp.BestCircuitValue-MY_EPS;
        double cutoff = 0.0;
        if (cutoff > MY_EPS) model.getEnv().set(GRB_DoubleParam_Cutoff, cutoff );
        model.update(); // Process any pending model modifications.
        model.optimize();

        // Obtém o status da otimização
        int status = model.get(GRB_IntAttr_Status);
        if(status == GRB_INFEASIBLE || status == GRB_INF_OR_UNBD){
            cout << "Modelo inviavel ou unbounded." << endl;
            return false;
        }

        // Limitante inferior e superior do modelo
        //lbound = model.get(GRB_DoubleAttr_ObjBoundC);

        if( model.get(GRB_IntAttr_SolCount) <= 0 ){
            cout << "Modelo nao encontrou nenhuma solucao viavel no tempo. LowerBound = " << lbound << endl;
            return false;
        }
        else if (status == GRB_OPTIMAL){
            if(verbose) cout << "O modelo foi resolvido ate a otimalidade." << endl;
        }
        else {
            if(verbose) cout << "O modelo encontrou uma solucao sub-otima (i.e. nao ha garantia de otimalidade)." << endl;
        }

        double custo_solucao = model.get(GRB_DoubleAttr_ObjVal);
        
        int uncovered=0;
        EdgeBoolMap cover(utsp.g, false);
        for (EdgeIt e(utsp.g); e!=INVALID; ++e)
        {
            if (BinaryIsOne(x[e].get(GRB_DoubleAttr_X)))
            {
                cover[e] = true;
                uncovered++;
            }
        }
        sol.push_back(tsp.g.nodeFromId(utsp.g.id(usource)));        
        convertSol(x, sol, tsp, utsp, usource, cover, uncovered);

        // Calculo manual do custo da solução (deve ser igual ao ObjVal do Gurobi).
        double soma=0.0;
        ArcName aname(tsp.g);
        vector<Arc> edgesSol;
        ArcColorMap acolor(tsp.g);
        // if( verbose ) cout << "####### " << endl << "Edges of Solution (B&B):" << endl;
        // for (EdgeIt e(utsp.g); e!=INVALID; ++e){
        //     if (BinaryIsOne(x[e].get(GRB_DoubleAttr_X))){ // Note que se este método serve para variáveis binárias, p/ inteiras terá de usar outro método.
        //         soma += utsp.weight[e];
        //         edgesSol.push_back(tsp.g.arcFromId(utsp.g.id(e)));
        //         if( verbose) cout << "(" << tsp.vname[tsp.g.nodeFromId(utsp.g.id(utsp.g.u(e)))] << "," << tsp.vname[tsp.g.nodeFromId(utsp.g.id(utsp.g.v(e)))] << ")" << endl;
        //         acolor[tsp.g.arcFromId(utsp.g.id(e))] = BLUE;
        //     }
        // }
        // if( verbose ) cout << "####### " << endl;
        if( verbose ) cout << "####### " << endl << "Edges of Solution (B&B):" << endl;
        DNode u = sol[0];
        for (int i=1; i<sol.size(); i++) 
        {
            DNode v = sol[i];
            soma += tsp.AdjMatD.Cost(u,v);
            if ( verbose ) cout << "(" << tsp.vname[u] << "," << tsp.vname[v] << ")" << endl;
            u = v;
        }
        if( verbose ) cout << "####### " << endl;

        if( verbose ) cout << "Custo calculado pelo B&B = "<< soma << " / " << custo_solucao << endl;
        if( verbose ){
            cout << "Caminho encontrado a partir do vértice de origem (" << tsp.vname[source] << "): ";
            for(auto node : sol){
                cout << tsp.vname[node] << " ";
            } // Obs: O caminho é gerado a partir do nó source, se o conjunto de arestas retornado pelo B&B for desconexo, o caminho retornado por 'path_search' será incompleto.
            cout << endl << "Custo calculado da solucao (caminho a partir do no origem) = " << solutionCost(tsp, sol) << endl;
            ostringstream out;
            out << "TSP with Refueling B&B, cost= " << custo_solucao;
            ViewListDigraph(tsp.g, tsp.vname, tsp.posx, tsp.posy, tsp.vcolor, acolor, out.str());
        }
        return true;
    }
    catch(GRBException e) {
        cerr << "Gurobi exception has been thrown." << endl;
        cerr << "Error code = " << e.getErrorCode() << endl;
        cerr << e.getMessage();
    }
    catch (...) {
        cout << "Model is infeasible"  << endl;
        return false;
    }
    return false;
}
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);}
}