Beispiel #1
0
void seleciona_propagandas(int n, double C, double V[N], double P[N], double w[N][N], int S[N], double *UpperBound, long maxtime) {
	GRBVar y[N][N];
	GRBVar x[N];

	int seed=0;
	GRBEnv env = GRBEnv();
	GRBModel model = GRBModel(env);
	model.getEnv().set(GRB_IntParam_Seed, seed);
	model.set(GRB_StringAttr_ModelName, "Alocacao Propaganda"); // prob. name
	model.set(GRB_IntAttr_ModelSense, GRB_MAXIMIZE); // is a minimization problem  

	for(int i = 0; i < n; i++) {
		char name[100];
		sprintf(name,"x_%d",i);
		x[i] = model.addVar(0.0, 1.0, V[i],GRB_BINARY, name); 
	}

	for( int i = 0; i < n; i++) {

		for(int j = i+1; j < n; j++) {
			char name[100];
			sprintf(name,"y_%d_%d",i, j);
			y[i][j] = model.addVar(0.0, 1.0, w[i][j], GRB_BINARY, name); 
		}
	}
	
	model.update();
	
	GRBLinExpr expr;
	for(int i = 0; i < n; i++) {
		expr += (x[i] * P[i]);
	}
	model.addConstr(expr <= C);
	model.update();
	
	for(int i = 0; i < n; i++) {
		
		for(int j =i+1; j < n; j++) {
			model.addConstr(y[i][j] <= x[i]);
			model.addConstr(y[i][j] <= x[j]);
			model.addConstr(x[i] + x[j] <= (y[i][j] + 1));
		}
	}
	model.update();
	
	model.write("model.lp");
	
	model.optimize();
	
	*UpperBound = model.get(GRB_DoubleAttr_ObjVal);
	
}
Beispiel #2
0
void AlignmentLP::ConstructLP(SpeechSolution *proposal) {
  try {
  GRBEnv env = GRBEnv();
  GRBModel model = GRBModel(env);
  //model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE);

  // Create all the variables.
  s.resize(cs_.problems_size());
  s2.resize(cs_.problems_size());
  //position_var.resize(cs_.problems_size()); 
  // Create the hmms. 
  for (uint u = 0; u < s.size(); ++u) {
    const ClusterProblem &problem = cs_.problem(u);
    int M = problem.num_steps;
    s[u].resize(M);
    s2[u].resize(M);
    //position_var.resize(M); 
    for (int m = 0; m < M; ++m) {
      s[u][m].resize(problem.num_states);
      s2[u][m].resize(problem.num_states);

      for (uint n = 0; n < s[u][m].size(); ++n) {
        s[u][m][n].resize(cs_.num_hidden(0));
        {
          stringstream buf;
          buf << "s2_" << u << "_" << m << "_" << n;
          s2[u][m][n] = 
            model.addVar(0.0, 1.0, 0.0, 
                         VAR_TYPE, buf.str());
        }

        for (uint o = 0; o < s[u][m][n].size(); ++o) {
          s[u][m][n][o].resize(3);
          for (uint f = 0; f <= 2; ++f) {
            stringstream buf;
            buf << "s_" << u << "_" << m << "_" << n << "_" << o << "_" << f;
            double score = distances_[u]->get_distance(m, o);
            s[u][m][n][o][f] = 
              model.addVar(0.0, 1.0, score, 
                           VAR_TYPE, buf.str());
          }
        }
      }
      // position_var[u][m].resize(cs_.num_types());
      // for (uint l = 0; l < position_var[u][m].size(); ++l) {
      //   position_var[u][m][l].resize(cs_.num_hidden(0));
      //   for (uint o = 0; o < position_var[u][m][l].size(); ++o) {
      //     stringstream buf;
      //     buf << "position_" << u << "_" << m << "_" <<  l << "_" << o;
      //     position_var[u][m][l][o] =
      //       model.addVar(0.0, 1.0, 0.0, 
      //                    VAR_TYPE, buf.str());
      //   }
      // }
    }
  }
  r.resize(cs_.num_types());
  for (uint l = 0; l < r.size(); ++l) {
    r[l].resize(cs_.num_hidden(0));
    for (uint o = 0; o < r[l].size(); ++o) {
      stringstream buf;
      buf << "r_" << l << "_" << o;
      r[l][o] = 
        model.addVar(0.0, 1.0, 0.0, 
                     VAR_TYPE, buf.str());
    }
  }

  t.resize(cs_.problems_size());
  for (uint u = 0; u < t.size(); ++u) {
    const ClusterProblem &problem = cs_.problem(u);
    t[u].resize(problem.num_states);
    for (uint n = 0; n < t[u].size(); ++n) {
      t[u][n].resize(cs_.num_hidden(0));
      for (uint o = 0; o < t[u][n].size(); ++o) {
        stringstream buf;
        buf << "t_" << u << "_" << n << "_" << o;
        t[u][n][o] = 
          model.addVar(0.0, 1.0, 0.0, 
                       VAR_TYPE, buf.str());
      }
    }
  }
  model.update();
  // Make constraints.
  // Constraint for M

  // for all l, sum_q r(l,o) = 1
  for (int l = 0; l < cs_.num_types(); ++l) {
    // Sum out o's.
    GRBLinExpr sum;
    for (int o = 0; o < cs_.num_hidden(0); ++o) {
      sum += r[l][o];
    }
    // Equal to 1.
    model.addConstr(sum == 1);
  }
  cerr << "Done Constraint 1" << endl;

  // Constraint for N
  // for all m,n,o, i, s(u, m, n, o) = s(m-1, n, o, 0) +  
  // s(m-1, n, o, 1)
  
  for (int u = 0; u < cs_.problems_size(); ++u) {
    const ClusterProblem &problem = cs_.problem(u);
    int M = problem.num_steps;
    int N = problem.num_states;

    for (int m = 0; m < M; ++m) {
      for (int n = 0; n < N; ++n) {
        for (int o = 0; o < cs_.num_hidden(0); ++o) {

          if (m != 0 && n != 0) {            
            GRBLinExpr sum;
            model.addConstr(s[u][m][n][o][0] + 
                            s[u][m][n][o][2] == 
                            s[u][m - 1][n][o][0] + 
                            s[u][m - 1][n][o][1], "incoming");
          }

          if (m != M - 1 && n != N - 1) {
            model.addConstr(s[u][m][n][o][0] + 
                            s[u][m][n][o][1] == 
                            s[u][m + 1][n][o][0] + 
                            s[u][m + 1][n][o][2], "Outgoing");            
          }
          GRBLinExpr sum, sum2;
          for (int o2 = 0; o2 < cs_.num_hidden(0); ++o2) {
            sum += s[u][m][n][o2][1];
            sum2 += s[u][m][n][o2][2];
          }
          model.addConstr(s2[u][m][n] == sum, "Outgoing");
          if (m != M - 1 && n != N - 1) {
            model.addConstr(sum2 == 
                            s2[u][m + 1][n + 1], "Outgoing");
          }
        }
      }
    }
    {
      GRBLinExpr sum;
      for (int o = 0; o < cs_.num_hidden(0); ++o) {
        sum += s[u][0][0][o][1];
      }
      model.addConstr(sum == 1, "Starting");
    }
    
    {
      GRBLinExpr sum;
      for (int o = 0; o < cs_.num_hidden(0); ++o) {
        sum += s[u][problem.num_steps - 1][problem.num_states - 1][o][0];
      }
      model.addConstr(sum == 1);
    }
  }

  // Tying constraints 3.
  // forall n, o, r(y_n, o) = t(n,o)
  for (int u = 0; u < cs_.problems_size(); ++u) {
    const ClusterProblem &problem = cs_.problem(u);
    for (int n = 0; n < problem.num_states; ++n) {
      GRBLinExpr sum;
      for (int o = 0; o < cs_.num_hidden(0); ++o) {
        sum += t[u][n][o];
      }
      model.addConstr(sum == 1);
    }
    for (int n = 0; n < problem.num_states; ++n) {
      int l = problem.MapState(n);
      for (int o = 0; o < cs_.num_hidden(0); ++o) {
        model.addConstr(r[l][o] == t[u][n][o]);

        GRBLinExpr sum;
        for (int m = 0; m < problem.num_steps; ++m) {
          sum += s[u][m][n][o][1];
        }
        model.addConstr(sum == t[u][n][o]);
      }
    }
  }
  cerr << "Done Constraint 3" << endl;
  
  if (true)  {
    for (int u = 0; u < cs_.problems_size(); ++u) {
      const ClusterProblem &problem = cs_.problem(u);
      int M = problem.num_steps;
      int N = problem.num_states;
      for (int m = 0; m < M; ++m) {
        for (uint l = 0; l < r.size(); ++l) {
          vector <int> locations;
          for (int n = 0; n < N; ++n) {
            if ((int)l == problem.MapState(n)) {
              locations.push_back(n);
            }
          }

          for (int o = 0; o < cs_.num_hidden(0); ++o) {
            GRBLinExpr sum;
            for (uint occ_index = 0; occ_index < locations.size(); ++occ_index) {
              int n = locations[occ_index];
              sum += s[u][m][n][o][0] + s[u][m][n][o][1] + s[u][m][n][o][2];
            }
            //model.addConstr(position_var[u][m][l][o] == sum);
            model.addConstr(sum <= r[l][o]);
          }
        }
      }
    }
  }

  // model.addConstr(r[7][2] == 0.5);
  // model.addConstr(r[7][3] == 0.5);
  // model.addConstr(r[0][1] == 0.5);
  // model.addConstr(r[0][6] == 0.5);
  // model.addConstr(r[13][4] == 0.5);
  // model.addConstr(r[13][9] == 0.5);
  model.update();
  //model.write("temp.lp");

  // 
  // // Done!
   model.optimize();
   if (model.get(GRB_IntAttr_Status) != GRB_OPTIMAL) {
     model.computeIIS();
     model.write("temp.ilp");
   }

  vector<double> costs;
  for (uint u = 0; u < s.size(); ++u) {
    SpeechAlignment *align = proposal->mutable_alignment(u);
    const ClusterProblem &problem = cs_.problem(u);
    vector<int> *state_hidden = align->mutable_hidden_alignment();
    vector<int> *state_align = align->mutable_alignment();
    state_hidden->resize(problem.num_steps);
    state_align->resize(problem.num_steps);
    
    int M = problem.num_steps;
    int N = 0;
    for (int m = 0; m < M; ++m) {
      N = s[u][m].size();
      costs.resize(s[u][m].size());
      for (uint n = 0; n < s[u][m].size(); ++n) {
        for (uint o = 0; o < s[u][m][n].size(); ++o) {
          for (uint f = 0; f <= 2; ++f) {
            if (s[u][m][n][o][f].get(GRB_DoubleAttr_X) != 0) {
              (*state_hidden)[m] = o;
              (*state_align)[m] = problem.MapState(n);
              string position;
              if (f == 0) {
                position = "I";
              } else if (f == 1) {
                position = "B";
              } else { 
                position = "O";
              }
              cerr << "s " << m << " " << n << " " << o << " " << position << " "
                   << s[u][m][n][o][f].get(GRB_DoubleAttr_X) 
                   << " " << s[u][m][n][o][f].get(GRB_DoubleAttr_Obj) 
                   << " " << problem.MapState(n) << endl;
              costs[n] += s[u][m][n][o][f].get(GRB_DoubleAttr_X) 
                * s[u][m][n][o][f].get(GRB_DoubleAttr_Obj);
            }
          }
        }
      }
    }
    for (int n = 0; n < N; ++n) {
      cerr << n << " " << costs[n] << endl;
    }
  }


  for (uint u = 0; u < t.size(); ++u) {
    for (uint n = 0; n < t[u].size(); ++n) {
      for (uint o = 0; o < t[u][n].size(); ++o) {
        if (t[u][n][o].get(GRB_DoubleAttr_X) != 0) {
          cerr << "t " <<  n << " " << o << " " <<
            t[u][n][o].get(GRB_DoubleAttr_X) << endl;
        }
      }
    }
  }

  for (uint l = 0; l < r.size(); ++l) {
    for (uint o = 0; o < r[l].size(); ++o) {
      if (r[l][o].get(GRB_DoubleAttr_X) != 0) {
        cerr << "r " << l << " " << o << " " <<
          r[l][o].get(GRB_DoubleAttr_X) << endl;
      }
    }
  }


  } catch(GRBException e) {
    cout << "Error code = " << e.getErrorCode() << endl;
    cout << e.getMessage() << endl;
  } catch(...) {
    cout << "Exception during optimization" << endl;
  }
}
Beispiel #3
0
int
main(int argc,
     char *argv[])
{
  if (argc < 2)
  {
    cout << "Usage: feasopt_c++ filename" << endl;
    return 1;
  }

  GRBEnv* env = 0;
  GRBConstr* c = 0;
  try
  {
    env = new GRBEnv();
    GRBModel feasmodel = GRBModel(*env, argv[1]);
    
    // Create a copy to use FeasRelax feature later */
    GRBModel feasmodel1 = GRBModel(feasmodel);

    // clear objective
    feasmodel.setObjective(GRBLinExpr(0.0));

    // add slack variables
    c = feasmodel.getConstrs();
    for (int i = 0; i < feasmodel.get(GRB_IntAttr_NumConstrs); ++i)
    {
      char sense = c[i].get(GRB_CharAttr_Sense);
      if (sense != '>')
      {
        double coef = -1.0;
        feasmodel.addVar(0.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, 1,
                         &c[i], &coef, "ArtN_" +
                         c[i].get(GRB_StringAttr_ConstrName));
      }
      if (sense != '<')
      {
        double coef = 1.0;
        feasmodel.addVar(0.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, 1,
                         &c[i], &coef, "ArtP_" +
                         c[i].get(GRB_StringAttr_ConstrName));
      }
    }
    feasmodel.update();

    // optimize modified model
    feasmodel.write("feasopt.lp");
    feasmodel.optimize();

    // use FeasRelax feature */
    feasmodel1.feasRelax(GRB_FEASRELAX_LINEAR, true, false, true);
    feasmodel1.write("feasopt1.lp");
    feasmodel1.optimize();
  }
  catch (GRBException e)
  {
    cout << "Error code = " << e.getErrorCode() << endl;
    cout << e.getMessage() << endl;
  }
  catch (...)
  {
    cout << "Error during optimization" << endl;
  }

  delete[] c;
  delete env;
  return 0;
}
Beispiel #4
0
int
main(int   argc,
     char *argv[])
{
  try {
    GRBEnv env = GRBEnv();
    GRBModel model = GRBModel(env);

    GRBVar vars[n][n][n];
    int i, j, v;

    // Create 3-D array of model variables

    for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
        for (v = 0; v < n; v++) {
          string s = "G_" + itos(i) + "_" + itos(j) + "_" + itos(v);
          vars[i][j][v] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, s);
        }
      }
    }

    // Integrate variables into model

    model.update();

    // Add constraints

    // Each cell must take one value

    for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
        GRBLinExpr expr = 0;
        for (v = 0; v < n; v++)
          expr += vars[i][j][v];
        string s = "V_" + itos(i) + "_" + itos(j);
        model.addConstr(expr, GRB_EQUAL, 1.0, s);
      }
    }

    // Each value appears once per row

    for (i = 0; i < n; i++) {
      for (v = 0; v < n; v++) {
        GRBLinExpr expr = 0;
        for (j = 0; j < n; j++)
          expr += vars[i][j][v];
        string s = "R_" + itos(i) + "_" + itos(v);
        model.addConstr(expr == 1.0, s);
      }
    }

    // Each value appears once per column

    for (j = 0; j < n; j++) {
      for (v = 0; v < n; v++) {
        GRBLinExpr expr = 0;
        for (i = 0; i < n; i++)
          expr += vars[i][j][v];
        string s = "C_" + itos(j) + "_" + itos(v);
        model.addConstr(expr == 1.0, s);
      }
    }

    // Each value appears once per sub-grid

    for (v = 0; v < n; v++) {
      for (int i0 = 0; i0 < sd; i0++) {
        for (int j0 = 0; j0 < sd; j0++) {
          GRBLinExpr expr = 0;
          for (int i1 = 0; i1 < sd; i1++) {
            for (int j1 = 0; j1 < sd; j1++) {
              expr += vars[i0*sd+i1][j0*sd+j1][v];
            }
          }

          string s = "Sub_" + itos(v) + "_" + itos(i0) + "_" + itos(j0);
          model.addConstr(expr == 1.0, s);
        }
      }
    }

    // Fix variables associated with pre-specified cells

    char input[10];
    for (i = 0; i < n; i++) {
      cin >> input;
      for (j = 0; j < n; j++) {
        int val = (int) input[j] - 48 - 1; // 0-based

        if (val >= 0)
          vars[i][j][val].set(GRB_DoubleAttr_LB, 1.0);
      }
    }

    // Optimize model

    model.optimize();

    // Write model to file

    model.write("sudoku.lp");

    cout << endl;
    for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
        for (v = 0; v < n; v++) {
          if (vars[i][j][v].get(GRB_DoubleAttr_X) > 0.5)
            cout << v+1;
        }
      }
      cout << endl;
    }
    cout << endl;
  } catch(GRBException e) {
    cout << "Error code = " << e.getErrorCode() << endl;
    cout << e.getMessage() << endl;
  } catch (...) {
    cout << "Error during optimization" << endl;
  }

  return 0;
}
Beispiel #5
0
int main(int argc,char *argv[]) {
  srand48(1);
  if (argc!=2) {cout<<endl<<"Usage: "<< argv[0]<<"  <filename>"<< endl << endl;
    cout << "Example:      " << argv[0] << " arq1.in" << endl << endl; exit(0);}
	
  ifstream ifile;
  ifile.open(argv[1]);  if (!ifile) return(false);  

  int n, m;
  ifile >> n; ifile >> m;
  vector<double> jobsize(n);
  vector<double> machinespeed(m);
  for(int i=0; i<n; i++) ifile >> jobsize[i];
  for(int i=0; i<m; i++) ifile >> machinespeed[i];
  ifile.close();

  cout << endl;
  cout << "Numero de tarefas: " << n << endl;
  cout << "Tamanho das tarefas" << endl;
  for(int i=0; i<n; i++)
    cout << "T_" << i << ": " << jobsize[i] << endl;
  cout << "Velocidade das maquinas" << endl;
  for(int i=0; i<m; i++)
    cout << "M_" << i << ": " << machinespeed[i] << endl;
  cout << endl << endl;
  
  try {
/*--------------------------------------------------------------------------------- */	
/*--------------------------- ALTERE DAQUI PARA ABAIXO ---------------------------- */
/*--------------------------------------------------------------------------------- */	

    // Voce deve atualizar esta variavel com valores 0 e 1 de tal forma que
    // tarefa_maquina[i][j] = 1 SE_E_SOMENTE_SE a tarefa i foi escalonada na maq. j
    vector<vector<int> > tarefa_maquina(n, vector<int>(m));

    // mais abaixo eh feito um escalonamento aleatorio.
    // Nao se esqueca de alterar a geracao do escalonamento aleatorio para o
    // escalonamento obtido pelo seu programa linear inteiro


    // cabecalho comum para os programas lineares (descomente)
     int seed=0;
     GRBEnv env = GRBEnv();
     GRBModel model = GRBModel(env);
     model.getEnv().set(GRB_IntParam_Seed, seed);
     model.set(GRB_StringAttr_ModelName, "Escalonamento de Tarefas"); // prob. name
     model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem  

	GRBVar min;
	
	GRBVar x[m][n];

	min = model.addVar(0, 30000, 1 , GRB_CONTINUOUS, "min");

	
	int i,j;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++) {
			char name[100];
			sprintf(name,"I%dM%d",i,j);
			x[i][j] = model.addVar(0, 1, 0 , GRB_BINARY, name);	
		}
	}
		
	model.update();

	//cada tarefa em 1 máquina
	
	for (int i=0; i<n; i++){
		GRBLinExpr sum2;
      		for (int j=0; j<m; j++){
			sum2= sum2 + x[j][i];
		}
		model.addConstr(sum2 == 1);
	}	

	//min eh pior caso
	for(int j=0; j<m; j++){
		GRBLinExpr sum3;
		for (i=0; i<n ; i++) {
			sum3 = sum3 + jobsize[i]*x[j][i]/ machinespeed[j];
		}
		model.addConstr(min >= sum3);
	}

	model.update();
	model.write("model.lp");
	system("cat model.lp");

	model.optimize();
	// Verifica se obteve solucao otima
	if (model.get(GRB_IntAttr_Status) != GRB_OPTIMAL) {
       cout << "Erro, sistema impossivel" << endl;
       exit(1);
	}
    for (int i=0; i<n; i++){
      for (int j=0; j<m; j++){
	if(x[j][i].get(GRB_DoubleAttr_X)>0.999)
		tarefa_maquina[i][j] = 1; 
	else
		tarefa_maquina[i][j] = 0; 
	}
	}
 

	  
/*--------------------------------------------------------------------------------- */	
/*--------------------------- ALTERE DAQUI PARA CIMA ------------------------------ */
/*--------------------------------------------------------------------------------- */	

    cout << "\n\n";
      double makespan=0;
      cout << "Escalonamento obtido das tarefas nas maquinas\n";
      cout << "Notacao para tarefas : T_id(tamanho_original)\n";
      cout << "Notacao para maquinas: M_id(velocidade)\n\n";
      
      for (int j=0; j<m; j++) {
	double tmaq=0.0;
	cout << "M_"<<j<<"("<< machinespeed[j] << ") : ";
	for(int i=0; i<n; i++) {
	  if (tarefa_maquina[i][j] == 1) {
	    cout << "T_" << i << "(" << jobsize[i] << ") ";
	    tmaq += jobsize[i] / machinespeed[j];
	  }
	}
	cout << endl << "Tempo gasto pela maquina M_" <<j << ": " << tmaq << endl<<endl;
	if (tmaq>makespan) makespan = tmaq;
      }
      cout << "\nTempo para completar todas as tarefas: " << makespan << "s\n\n";
      //  } else  cout << "No solution" << "\n";
  }
  // catch (GRBException e) {
  //   cout << "Error code = " << e.getErrorCode() << endl;
  //   cout << e.getMessage() << endl;
  // }
  catch (...) {
    cout << "Exception during optimization" << endl;
  }
  return 0;
}
int main(int argc, char *argv[])
{
	GRBEnv* env = 0;
	GRBVar* covered = 0; // we want to maximize demand covered
	GRBVar* facility = 0;
	int max_n_Facilities = 10;

	try
	{
		const string filename = "/Users/katarzyna/Dropbox/matlab/2015-05 PKITS/aij_matrix.txt";

		std::vector<std::vector<long int> > aij_matrix;
		readMatrix_aij(filename, aij_matrix);

		std::cout << "matrix size "<< aij_matrix.size() <<" x "<< aij_matrix[0].size() << std::endl;

		// Model
		env = new GRBEnv();
		GRBModel model = GRBModel(*env);
		model.set(GRB_StringAttr_ModelName, "minimize number of facilities");

		// Demand coverage decision variable, covered[i] == 1 if demand is covered
		covered = model.addVars(aij_matrix.size(), GRB_BINARY);
		model.update();

		// Facility open variables: facility[j] == 1 if facility j is open.
		facility = model.addVars(aij_matrix.size(), GRB_BINARY);
		model.update();


		// Set the objective to maximize the demand covered
		for (unsigned int i = 0; i < aij_matrix.size(); ++i)
		{
			ostringstream vname;
			vname << "Demand " << i;
			covered[i].set(GRB_DoubleAttr_Obj, 1);
			covered[i].set(GRB_StringAttr_VarName, vname.str());
		}

		for (unsigned int i = 0; i < aij_matrix.size(); ++i)
		{
			ostringstream vname;
			vname << "Open " << i;
			facility[i].set(GRB_DoubleAttr_Obj, 0);
			facility[i].set(GRB_StringAttr_VarName, vname.str());
		}

		// The objective is to maximize the total demand covered
		model.set(GRB_IntAttr_ModelSense, 0);

		// Update model
		model.update();

		// Constraints

		// If demand i is covered by at least one station, then covered[i] == 1
		for (unsigned int i = 0; i < aij_matrix.size(); ++i)
		{
			GRBLinExpr demand_is_covered = 0;
			for (unsigned int j = 0; j < aij_matrix.size(); ++j)
			{
				demand_is_covered += aij_matrix[i][j] * facility[j];
			}
			ostringstream cname;
			cname << "Demand_i_is_covered " << i;
			model.addConstr(demand_is_covered >= covered[i], cname.str());
		}

		// We allow no more than n facilities
		GRBLinExpr facilities_to_open = 0;
		for (unsigned int j = 0; j < aij_matrix.size(); ++j) {
			facilities_to_open += facility[j];
		}

		ostringstream vname;
		vname << "Max facility... ";
		model.addConstr(facilities_to_open <= max_n_Facilities);

		model.update();

		// Solve
		model.optimize();

		model.write("/Users/katarzyna/Dropbox/matlab/2015-05 PKITS/output.lp");

		// Print solution
		cout << "\nTOTAL COSTS: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
		cout << "SOLUTION:" << endl;
		int sum_d = 0;
		for (unsigned int i = 0; i < aij_matrix.size(); ++i)
		{
			if (covered[i].get(GRB_DoubleAttr_X) == 1.0)
			{
				//cout << "Demand " << i << " covered." << endl;
				sum_d += 1;
			}
		}

		int sum_f = 0;
		for (unsigned int i = 0; i < aij_matrix.size(); ++i)
		{
			if (facility[i].get(GRB_DoubleAttr_X) == 1.0)
			{
				cout << "Facility " << i << " is opened." << endl;
				sum_f += 1;
			}
		}
		cout << sum_f << " facilities is open." << endl;
		cout << sum_d << " customers is covered." << endl;


	} catch (GRBException e)
	{
		cout << "Error code = " << e.getErrorCode() << endl;
		cout << e.getMessage() << endl;
	} catch (...)
	{
		cout << "Exception during optimization" << endl;
	}
}
Beispiel #7
0
int main(int argc,char *argv[]) {
  srand48(1);
  if (argc!=2) {cout<<endl<<"Usage: "<< argv[0]<<"  <filename>"<< endl << endl;
    cout << "Example:      " << argv[0] << " arq1.in" << endl << endl; exit(0);}
	
  ifstream ifile;
  ifile.open(argv[1]);  if (!ifile) return(false);  

  int n, m;
  ifile >> n; ifile >> m;
  vector<double> jobsize(n);
  vector<double> machinespeed(m);
  for(int i=0; i<n; i++) ifile >> jobsize[i];
  for(int i=0; i<m; i++) ifile >> machinespeed[i];
  ifile.close();

  cout << endl;
  cout << "Numero de tarefas: " << n << endl;
  cout << "Tamanho das tarefas" << endl;
  for(int i=0; i<n; i++)
    cout << "T_" << i << ": " << jobsize[i] << endl;
  cout << "Velocidade das maquinas" << endl;
  for(int i=0; i<m; i++)
    cout << "M_" << i << ": " << machinespeed[i] << endl;
  cout << endl << endl;
  
  try {
/*--------------------------------------------------------------------------------- */	
/*--------------------------- ALTERE DAQUI PARA ABAIXO ---------------------------- */
/*--------------------------------------------------------------------------------- */	

    // Voce deve atualizar esta variavel com valores 0 e 1 de tal forma que
    // tarefa_maquina[i][j] = 1 SE_E_SOMENTE_SE a tarefa i foi escalonada na maq. j
    vector<vector<int> > tarefa_maquina(n, vector<int>(m));

    // mais abaixo eh feito um escalonamento aleatorio.
    // Nao se esqueca de alterar a geracao do escalonamento aleatorio para o
    // escalonamento obtido pelo seu programa linear inteiro

    
    // cabecalho comum para os programas lineares (descomente)
     int seed=0;
     GRBEnv env = GRBEnv();
     GRBModel model = GRBModel(env);
     model.getEnv().set(GRB_IntParam_Seed, seed);
     model.set(GRB_StringAttr_ModelName, "Escalonamento de Tarefas"); // prob. name
     model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem  

    // Lembretes e sintaxes de alguns comandos:
    // GRBVar = nome do tipo das variaveis do Gurobi
    //
     //vector<GRBVar> x[m];
     double TP[m][n];
     GRBVar max = model.addVar(0,10000,1,GRB_CONTINUOUS,"max");
    // Para inserir uma variavel:
    // <variavel_do_tipo_GRBVar> =
    //            model.addVar(<lower_bound>,
    //                         <upper_bound> , 
    //                         <valor_na_funcao_objetivo>,
    //                         <GRB_CONTINUOUS ou GRB_BINARY GRB_INTEGER>
    //                         <string_do_nome_da_variavel>);
    //
    // Este comando deve ser executado depois de inserir todas as variaveis e antes de
    // inserir as restricoes.
     model.update();
    //
    // Para declarar variavel que armazena expressoes
     // for(int i = 0; i<n; i++) { //para cada maquina
     //   GRBLinExpr expr;
     //   for(int j = 0; j<m;j++) { //para cada tarefa
     // 	 expr+=x[m*i+j];
     //   }
     //   model.addConstr(expr >= 0);
     // }
    //
    // Para inserir uma restricao linear:
    // model.addConstr( <restricao_linear> );
    //
    // Comando para escrever o modelo produzido em um arquivo texto (apenas para debugar)
     model.update(); //Tem que dar update de novo pra ver as restricoes
     model.write("model.lp"); system("cat model.lp");
    //
    // Depois que construiu seu programa linear / linear inteiro, execute este comando
    // para resolver o programa linear
     model.optimize();
    //
    // Verifica se obteve solucao otima
     if (model.get(GRB_IntAttr_Status) != GRB_OPTIMAL) {
       cout << "Erro, sistema impossivel" << endl;
       exit(1);
     }
    //
    // Para obter o valor da variavel do programa linear/linear inteiro
    // deve ser executado apos o model.optimize()
    // 	<variavel_do_tipo_GRBVar>.get(GRB_DoubleAttr_X)

    
    // Faz um escalonamento aleatorio.
    // Remova esta parte e coloque o escalonamento
    // gerado pelo seu programa linear inteiro.
    for (int i=0; i<n; i++) 
      for (int j=0; j<m; j++)
	tarefa_maquina[i][j] = 0; // deixa cada maq. sem atribuicao
    // for (int i=0; i<n; i++)
    //   for (int j=0; j<m; j++)
    // 	//if(x[j][i].get(GRB_DoubleAttr_X) >= 0.999) {
    // 	//  cout << j << "  " << i << endl;
    // 	  tarefa_maquina[i][j] = 1;
    // 	}
	  
/*--------------------------------------------------------------------------------- */	
/*--------------------------- ALTERE DAQUI PARA CIMA ------------------------------ */
/*--------------------------------------------------------------------------------- */	

    cout << "\n\n";
      double makespan=0;
      cout << "Escalonamento obtido das tarefas nas maquinas\n";
      cout << "Notacao para tarefas : T_id(tamanho_original)\n";
      cout << "Notacao para maquinas: M_id(velocidade)\n\n";
      
      for (int j=0; j<m; j++) {
	double tmaq=0.0;
	cout << "M_"<<j<<"("<< machinespeed[j] << ") : ";
	for(int i=0; i<n; i++) {
	  if (tarefa_maquina[i][j] == 1) {
	    cout << "T_" << i << "(" << jobsize[i] << ") ";
	    tmaq += jobsize[i] / machinespeed[j];
	  }
	}
	cout << endl << "Tempo gasto pela maquina M_" <<j << ": " << tmaq << endl<<endl;
	if (tmaq>makespan) makespan = tmaq;
      }
      cout << "\nTempo para completar todas as tarefas: " << makespan << "s\n\n";
      //  } else  cout << "No solution" << "\n";
  }
  // catch (GRBException e) {
  //   cout << "Error code = " << e.getErrorCode() << endl;
  //   cout << e.getMessage() << endl;
  // }
  catch (...) {
    cout << "Exception during optimization" << endl;
  }
  return 0;
}
Beispiel #8
0
int main (int argc, char * argv[]) {
    chrono :: steady_clock :: time_point tBegin = chrono :: steady_clock :: now();
    string I ("0");
    ulint timeLimit = 10;

    if (argc >= 2) {
        I = string (argv[1]);
    }

    if (argc >= 3) {
        timeLimit = atoi(argv[2]);
    }

    ulint nComplete, k, t, n, m, root;
    double d;

    cin >> nComplete >> d >> k >> t >> n >> m >> root;

    vector <ulint> penalty (nComplete); // vector with de penalties of each vectex
    vector < list < pair <ulint, ulint> > > adj (nComplete); // adjacency lists for the graph

    for (ulint v = 0; v < nComplete; v++) {
        cin >> penalty[v];
    }

    vector <ulint> solutionV (nComplete, 0);

    // reading solution vertices
    for (ulint i = 0; i < n; i++) {
        ulint v;
        cin >> v;
        solutionV[v] = 1;
    }

    vector < pair < pair <ulint, ulint> , ulint> > E (m); // vector of edges with the format ((u, v), w)
    map < pair <ulint, ulint>, ulint> mE; // map an edge to its ID
    vector < vector <ulint> > paths (m);

    // reading graph
    for (ulint e = 0; e < m; e++) {
        ulint u, v, w, pathSize;
        cin >> u >> v >> w >> pathSize;
        adj[u].push_back(make_pair(v, w));
        adj[v].push_back(make_pair(u, w));
        E[e] = make_pair(make_pair(u, v), w);
        mE[make_pair(u, v)] = e;
        mE[make_pair(v, u)] = e;
        paths[e] = vector <ulint> (pathSize);
        for (ulint i = 0; i < pathSize; i++) {
            cin >> paths[e][i];
        }
    }

    try {
        string N = itos(nComplete);
        stringstream ssD;
        ssD << fixed << setprecision(1) << d;
        string D = ssD.str();
        D.erase(remove(D.begin(), D.end(), '.'), D.end());
        string K = itos(k);
        string T = itos(t);

        ifstream remainingTimeFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/remainingTime.txt");
        lint remainingTime = 0;
        if (remainingTimeFile.is_open()) {
            remainingTimeFile >> remainingTime;
        }
        if (remainingTime > 0) {
            timeLimit += remainingTime;
        }

        GRBEnv env = GRBEnv();

        env.set(GRB_IntParam_LazyConstraints, 1);
        env.set(GRB_IntParam_LogToConsole, 0);
        env.set(GRB_StringParam_LogFile, "./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/log2.txt");
        env.set(GRB_DoubleParam_TimeLimit, ((double) timeLimit));

        GRBModel model = GRBModel(env);

        model.getEnv().set(GRB_IntParam_LazyConstraints, 1);
        model.getEnv().set(GRB_IntParam_LogToConsole, 0);
        model.getEnv().set(GRB_StringParam_LogFile, "./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/log2.txt");
        model.getEnv().set(GRB_DoubleParam_TimeLimit, ((double) timeLimit));

        vector <GRBVar> y (nComplete);

        // ∀ v ∈ V
        for (ulint v = 0; v < nComplete; v++) {
            // y_v ∈ {0.0, 1.0}
            y[v] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "y_" + itos(v));
        }

        vector <GRBVar> x (m);

        // ∀ e ∈ E
        for (ulint e = 0; e < m; e++) {
            ulint u, v;
            u = E[e].first.first;
            v = E[e].first.second;
            // y_e ∈ {0.0, 1.0}
            x[e] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "x_" + itos(u) + "_" + itos(v));
        }

        model.update();

        GRBLinExpr obj = 0.0;

        // obj = ∑ ce * xe
        for (ulint e = 0; e < m; e++) {
            ulint w;
            w = E[e].second;
            obj += w * x[e];
        }

        // obj += ∑ πv * (1 - yv)
        for (ulint v = 0; v < nComplete; v++) {
            obj += penalty[v] * (1.0 - y[v]);
        }

        model.setObjective(obj, GRB_MINIMIZE);

        // yu == 1
        model.addConstr(y[root] == 1.0, "c_0");

        // dominance
        // ∀ v ∈ V
        for (ulint v = 0; v < nComplete; v++) {
            if (solutionV[v] == 1) {
                GRBLinExpr constr = 0.0;
                constr += y[v];
                model.addConstr(constr == 1, "c_1_" + itos(v));
            }
        }

        // each vertex must have exactly two edges adjacent to itself
        // ∀ v ∈ V
        for (ulint v = 0; v < nComplete; v++) {
            // ∑ xe == 2 * yv , e ∈ δ({v})
            GRBLinExpr constr = 0.0;
            for (list < pair <ulint, ulint> > :: iterator it = adj[v].begin(); it != adj[v].end(); it++) {
                ulint w = (*it).first; // destination
                ulint e = mE[make_pair(v, w)];
                constr += x[e];
            }
            model.addConstr(constr == 2.0 * y[v], "c_2_" + itos(v));
        }

        subtourelim cb = subtourelim(y, x, nComplete, m, E, mE, root);
        model.setCallback(&cb);

        model.optimize();

        if (model.get(GRB_IntAttr_SolCount) > 0) {
            ulint solutionCost = 0;
            set <ulint> solutionVectices;
            vector < pair <ulint, ulint> > solutionEdges;
            solutionCost = round(model.get(GRB_DoubleAttr_ObjVal));
            for (ulint v = 0; v < nComplete; v++) {
                if (y[v].get(GRB_DoubleAttr_X) >= 0.5) {
                    solutionVectices.insert(v);
                }
            }
            for (ulint e = 0; e < m; e++) {
                if (x[e].get(GRB_DoubleAttr_X) >= 0.5) {
                    for (ulint i = 0; i < paths[e].size() - 1; i++) {
                        pair <ulint, ulint> edge;
                        if (paths[e][i] < paths[e][i + 1]) {
                            edge.first = paths[e][i];
                            edge.second = paths[e][i + 1];
                        } else {
                            edge.first = paths[e][i + 1];
                            edge.second = paths[e][i];
                        }
                        solutionEdges.push_back(edge);
                    }
                }
            }
            cout << solutionVectices.size() << ' ' << solutionEdges.size() << ' ' << solutionCost << endl;
            for (set <ulint> :: iterator it = solutionVectices.begin(); it != solutionVectices.end(); it++) {
                ulint v = *it;
                cout << v << endl;
            }
            for (vector < pair <ulint, ulint> > :: iterator it = solutionEdges.begin(); it != solutionEdges.end(); it++) {
                pair <ulint, ulint> e = *it;
                cout << e.first << " " << e.second << endl;
            }
        } else {
            cout << "0 0 0" << endl;
        }

        // exporting model
        model.write("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/model2.lp");

        ofstream objValFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/objVal2.txt", ofstream :: out);
        objValFile << model.get(GRB_DoubleAttr_ObjVal);
        objValFile.close();

        ofstream gapFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/gap2.txt", ofstream :: out);
        gapFile << model.get(GRB_DoubleAttr_MIPGap);
        gapFile.close();

        chrono :: steady_clock :: time_point tEnd = chrono :: steady_clock :: now();
        chrono :: nanoseconds elapsedTime = chrono :: duration_cast <chrono :: nanoseconds> (tEnd - tBegin);
        ofstream elapsedTimeFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/elapsedTime2.txt", ofstream :: out);
        elapsedTimeFile << elapsedTime.count();
        elapsedTimeFile.close();
    } catch (GRBException e) {
int main(int argc, char *argv[]) {

	// do we want to force integer solution?
	// if false, we solve a linear program without the integrity constraint
	bool integer_solution = false;
	// if objective_min_N is true then we solve the problem which minimizes total
	// number of vehicles in the simulation.
	// Otherwise, we minimize number of rebalancing trips
	bool objective_min_N = true;

	GRBEnv* env = 0; //< gurobi env
	GRBVar** rij = 0; // number of empty vehicles traveling between stations
	GRBVar** vi = 0; // number of vehicles available at station i

	// stations coordinates
	std::vector<std::vector<double> > stations;
	// distances or cost of traveling between the stations
	// internal vector stores "to where" and external vector stores "from where"
	std::vector<std::vector<double> > cost;
	// origin counts, size of n_rebalancing_periods x n_stations
	std::vector<std::vector<double> > origin_counts;
	// destination counts, size of n_rebalancing_periods x n_stations
	std::vector<std::vector<double> > dest_counts;
	// counts of vehicles in transit to each station, size of n_rebalancing_periods x n_stations
	std::vector<std::vector<double> > in_transit_counts;
	// cost of one idle vehicle in the system, when objective minimizes # vehicles, then set cost to 1,
	// when objective minimizes number of rebalancing vehicles then set cost to a huge number
	// (to make sure that this is always more expensive that rebalancing as it adds more vehicles to the system)
	double cost_of_veh = 1.0;
	double rebalancing_cost = 1.0;
	// what constraints do you want to take into account

	// input and output files declaration
	// simple_model
	//	bool simple_model = true;
	//	const string stationsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/sampleFiles/stationsXY.txt";
	//	const string costMatrixFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/sampleFiles/costM3x3TT.txt";
	//	const string originCountsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/sampleFiles/origCounts3x3TT.txt";
	//	const string destinationCountsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/sampleFiles/destCounts3x3TT.txt";
	//	const string inTransitCountsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/sampleFiles/inTransit3x3TT.txt";
	//	const string modelOutput = "rebalancing_formulation_simple.lp";
	//	const string solutionOutput = "rebalancing_solution_simple.sol";

	//	// simmobility files
	//		// ubuntu
	bool simple_model = false;
	const string stationsFile = "/home/kasia/Dropbox/matlab/2016-03-Demand_generation/facility_location/stations_ecbd34.txt";
	const string costMatrixFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/RebTimeInSecs34Stations.txt";
	const string originCountsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/origCounts_rebEvery900_stations34.txt";
	const string destinationCountsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/destCounts_rebEvery900_stations34.txt";
	const string inTransitCountsFile = "/home/kasia/Dropbox/matlab/2015-09_FleetSizeEstimation/inTransitReb900Stations34";
	const string modelOutput = "formulation_rebalancing.lp";
	const string solutionOutput = "rebalancing_solution.sol";

	// mac
	//		stationsFile = "/Users/katarzyna/Dropbox/matlab/2016-03-Demand_generation/facility_location/stations_ecbd34.txt";
	//		costMatrixFile = "/Users/katarzyna/Dropbox/matlab/2015-09_FleetSizeEstimation/RebTime34Stations.txt";
	//		originCountsFile = "/Users/katarzyna/Dropbox/matlab/2015-09_FleetSizeEstimation/origCounts_rebEvery900_stations34.txt";
	//		destinationCountsFile = "/Users/katarzyna/Dropbox/matlab/2015-09_FleetSizeEstimation/destCounts_rebEvery900_stations34.txt";


	//readFiles(stationsFile, stations);
	readFiles(costMatrixFile, cost);
	readFiles(originCountsFile, origin_counts);
	readFiles(destinationCountsFile, dest_counts);
	readFiles(inTransitCountsFile, in_transit_counts);

	//round cost of traveling between stations to be a multiple of the rebalancing period
	int reb_period = 1;
	if(!simple_model) {
		reb_period = 900; // in minutes, output from costOfRebalancing.m is in secs
	}

	int rounded_cost[cost.size()][cost.size()];
	for (unsigned int i = 0; i < cost.size(); i++){
		for (unsigned int j = 0; j < cost[0].size(); j++){
			if (i != j) {
				// cost in seconds from the beginning of the simulation
				rounded_cost[i][j] = roundUp((int)cost[i][j], reb_period);
				//std::cout << "roundUp((int)cost[" << i <<"][" << j << "] = " << rounded_cost[i][j] << std::endl;
			} else {
				rounded_cost[i][j] = 99999999; // 0
			}
		}
	}

	try {
		// number of stations in the network
		const int nStations = cost.size();
		const int nStSquare = pow (nStations, 2);
		//number of rebalancing periods = number of rows in the origin and destination counts, size of the first vector
		const int nRebPeriods = origin_counts.size();

		/***********************************************************************************
		 * Station matrix
		 ***********************************************************************************/
		// station matrix to access the elements of cost/rebalancing vectors
		// matrix form stores the indices of the cost vector i.e., for 3 stations [[0,1,2],[3,4,5],[6,7,8]]
		int stationMatrix [nStations][nStations];
		int indxCounter = 0;
		for(int i = 0; i < nStations; ++i) {
			for (int k = 0; k < nStations; ++k) {
				stationMatrix[i][k] = indxCounter;
				//std::cout << "stationMatrix["<< i<< "][" << k << "] = " << indxCounter << endl;
				indxCounter++;
			}
		}

		/***********************************************************************************
		 * Model
		 ***********************************************************************************/
		env = new GRBEnv();
		GRBModel model = GRBModel(*env);
		model.set(GRB_StringAttr_ModelName, "rebalancing");

		/***********************************************************************************
		 * Decision variables
		 ***********************************************************************************/
		int station;
		int time_;
		div_t divresult;
		// Number of vehicles available (idle) at each period of time and each station
		vi = new GRBVar* [nRebPeriods];
		// Number of empty vehicles traveling between stations
		rij = new GRBVar* [nRebPeriods];
		for ( time_ = 0; time_ < nRebPeriods; ++time_) {
			if (integer_solution) {
				vi[time_] = model.addVars(nStations, GRB_INTEGER);
				rij[time_] = model.addVars(nStSquare, GRB_INTEGER);
			} else {
				vi[time_] = model.addVars(nStations);
				rij[time_] = model.addVars(nStSquare);
			}
			model.update();
		}

		// Objective: minimize number of rebalancing trips
		if (!objective_min_N) {
			for ( time_ = 0; time_ < nRebPeriods; ++time_) {

				for (station = 0; station < nStations; ++station) {
					ostringstream cname;
					cname << "v_ti," << time_ << "," << station << ",0";

					// not minimized in the objective
					vi[time_][station].set(GRB_DoubleAttr_Obj, 0.0);
					vi[time_][station].set(GRB_StringAttr_VarName, cname.str());

				}
			}
			model.update();

			for ( time_ = 0; time_ < nRebPeriods; ++time_) {

				for(int depSt = 0; depSt < nStations; ++depSt){
					// std::cout << "departure station: " << depSt << std::endl;
					for (int arrSt = 0; arrSt < nStations; ++arrSt) {

						int idx = stationMatrix[depSt][arrSt];
						ostringstream vname;
						vname << "r_tij," << time_ << "," << depSt << ","<< arrSt;
						//std::cout << "nEmptyVhsTime." << time_ << "." << depSt << "."<< arrSt << "."<< idx << std::endl;

						if (depSt == arrSt) {
							// origin == destination
							// this variable should not exist because we do not send vehicles within the same station
							rij[time_][idx].set(GRB_DoubleAttr_Obj, 0.0);
							rij[time_][idx].set(GRB_StringAttr_VarName, vname.str());
							continue;
						}
						// std::cout << "nEmptyVhsTime." << time_ << ".indx." << station << ".from."<< divresult.quot << ".to." << divresult.rem << std:: endl;

						rij[time_][idx].set(GRB_DoubleAttr_Obj, rebalancing_cost * rounded_cost[depSt][arrSt]); // rebalancing_cost
						rij[time_][idx].set(GRB_StringAttr_VarName, vname.str());
					}
				}
			}
		} else { // Objective: minimize the total number of vehicles at time_ == 0
			// integer constraint relaxed
			ostringstream cname;
			ostringstream vname;
			for ( time_ = 0; time_ < nRebPeriods; ++time_) {

				for(int depSt = 0; depSt < nStations; ++depSt){
					cname.str("");
					cname.clear();
					cname << "v_ti," << time_ <<"," << depSt << ",0";
					if (time_ != 0) {
						cost_of_veh = 0.0;
					} else {
						cost_of_veh = 1.0;
					}
					vi[time_][depSt].set(GRB_DoubleAttr_Obj, cost_of_veh);
					vi[time_][depSt].set(GRB_StringAttr_VarName, cname.str());

					model.update();

					for (int arrSt = 0; arrSt < nStations; ++arrSt) {
						vname.str("");
						vname.clear();
						vname << "r_tij," << time_ << "," << depSt << ","<< arrSt;
						// std::cout << "Adding variable: r_tij," << time_ << "," << depSt << ","<< arrSt << " =  \n" << std::flush;
						int idx = stationMatrix[depSt][arrSt];

						if (depSt == arrSt) {
							rij[time_][idx].set(GRB_DoubleAttr_Obj, 0.0);
							rij[time_][idx].set(GRB_StringAttr_VarName, vname.str());
							// std::cout << "vname = " << vname.str() << "\n" << std::flush;
							// std::cout << "vname after clear= " << vname.str() << "\n" << std::flush;
							// std::cout << "Added variable: r_tij," << time_ << "," << depSt << ","<< arrSt << " = 0.0\n" << std::flush;
							continue;
						}

						if (time_ != 0) {
							rebalancing_cost = 0.0;
						} else {
							rebalancing_cost = 1.0;
						}

						int travel_time = (int) (rounded_cost[arrSt][depSt]/reb_period);
						// divresult.rem is start time of the arriving trips
						divresult = div (nRebPeriods + time_ - travel_time, nRebPeriods);

						// to prevent overwriting if there is sth already assigned to this variable
						if (rij[divresult.rem][idx].get(GRB_DoubleAttr_Obj) > 0) {

							if (travel_time > 1) {
								for (int k = 1; k < travel_time; ++k) {
									divresult = div (nRebPeriods + time_ - travel_time + k, nRebPeriods);
									// to prevent overwriting if there is sth already assigned to this variable
									if (rij[divresult.rem][idx].get(GRB_DoubleAttr_Obj) > 0) {
										continue;
									}
									rij[divresult.rem][idx].set(GRB_DoubleAttr_Obj, rebalancing_cost);
									vname.str("");
									vname.clear();
									vname << "r_tij," << divresult.rem << "," << depSt << ","<< arrSt;
									rij[divresult.rem][idx].set(GRB_StringAttr_VarName, vname.str());
									//std::cout << "Added variable: r_tij," << divresult.rem << "," << depSt << ","<< arrSt << " = " << rebalancing_cost << "\n" << std::flush;
								}
							}
							continue;
						}

						rij[divresult.rem][idx].set(GRB_DoubleAttr_Obj, rebalancing_cost);
						vname.str("");
						vname.clear();
						vname << "r_tij," << divresult.rem << "," << depSt << ","<< arrSt;
						rij[divresult.rem][idx].set(GRB_StringAttr_VarName, vname.str());
						//std::cout << "Added variable: r_tij," << divresult.rem << "," << depSt << ","<< arrSt << " = " << rebalancing_cost << "\n" << std::flush;

						if (travel_time > 1) {
							for (int k = 1; k < travel_time; ++k) {
								divresult = div (nRebPeriods + time_ - travel_time + k, nRebPeriods);
								// to prevent overwriting if there is sth already assigned to this variable
								if (rij[divresult.rem][idx].get(GRB_DoubleAttr_Obj) > 0) {
									continue;
								}
								rij[divresult.rem][idx].set(GRB_DoubleAttr_Obj, rebalancing_cost);
								vname.str("");
								vname.clear();
								vname << "r_tij," << divresult.rem << "," << depSt << ","<< arrSt;
								rij[divresult.rem][idx].set(GRB_StringAttr_VarName, vname.str());
								//std::cout << "Added variable: r_tij," << divresult.rem << "," << depSt << ","<< arrSt << " = " << rebalancing_cost << "\n" << std::flush;
							}
						}
					}
				}
			}
		}
		model.update();

		/***********************************************************************************
		 * Objective function
		 ***********************************************************************************/
		// The objective is to minimize the number of vehicles traveling in the network (and cost associated with it)
		// Optimization sense:  The default +1.0 value indicates that the objective is to minimize the
		// objective. Setting this attribute to -1 changes the sense to maximization
		model.set(GRB_IntAttr_ModelSense, 1);
		model.update();

		/***********************************************************************************
		 * Constraint 1: The number of vehicles must be sufficient to serve the demand
		 ***********************************************************************************/
		// This constraint is set to ensure that the number of vehicles available at each station i
		// is sufficient to serve the demand within this station.
		// If there is not enough vehicles, then we do rebalancing to make sure we can serve the trips
		for ( time_ = 0; time_ < nRebPeriods; ++time_) {
			// Current demand
			int booking_requests[nStations];
			for (int i = 0; i < nStations; ++i) {
				// booking_requests = departing_vehicles - arriving_vehicles (how many more vehicles do we need)
				booking_requests[i] = origin_counts[time_][i] - dest_counts[time_][i];
				// std::cout << origin_counts[time_][i] << " - " << dest_counts[time_][i] << " = " << dem_curr[i] << std::endl;
			}

			GRBLinExpr reb_dep = 0;
			GRBLinExpr reb_arr = 0;

			for(int depSt = 0; depSt < nStations; ++depSt){
				// std::cout << "departure station: " << depSt << std::endl;
				for (int arrSt = 0; arrSt < nStations; ++arrSt) {

					if (depSt != arrSt) {
						int idx = stationMatrix[depSt][arrSt];
						int idx2 = stationMatrix[arrSt][depSt];
						reb_dep += rij[time_][idx];
						// std::cout << "rounded_cost = " << (int)rounded_cost[depSt][arrSt]/reb_period -1 << std::endl;
						// cost is expressed in the number of reb periods, i.e., 1,2,3,...nRebPeriods
						int travel_cost = (int) (rounded_cost[depSt][arrSt]/reb_period); // maybe ceil would be better than just int
						// ceil version of the above line
						// int travel_cost = (int) ceil((rounded_cost[depSt][arrSt]/reb_period));
						if (travel_cost > time_) {
							int dep_time = nRebPeriods + time_ - travel_cost;
							reb_arr += rij[dep_time][idx2];
						} else {
							int dep_time = time_ - travel_cost;
							reb_arr += rij[dep_time][idx2];
						}
					}
				}
				ostringstream cname;
				cname << "demand_ti" << time_ << "." << depSt;
				model.addConstr(vi[time_][depSt] + reb_arr - reb_dep >= booking_requests[depSt], cname.str());

				//std::cout << "Constraint 1 demand: " << time_  << "." << depSt << std::endl;
				reb_arr.clear();
				reb_dep.clear();
			}
		}
		model.update();
		std::cout << "Constraint set 1 added." << std::endl;

		/***********************************************************************************
		 * Constraint 2: Constant number of vehicles over time
		 ***********************************************************************************/
		// This constraint is set to ensure that the total number of vehicles in the system does not change
		// over time
		// the total number of vehicles in the system is equal to the sum of the vehicles owned by each station
		// vehicles owned by station i: available_veh + cust_arriving + cust_in_transit_to_station + empty_arr + empty_in_transit

		int cust_balance_at[nStations];
		int cust_vhs_at_t[time_];
		for ( time_ = 0; time_ < nRebPeriods; ++time_) {
			cust_vhs_at_t[time_] = 0;
			for (int i = 0; i < nStations; ++i) {
				// vhs_owned is the number of vehicles owned by station i
				// this number does not account for rebalancing vehicles
				// vhs_owned = arriving_costomers + in_transit_to_station
				cust_balance_at[i] = dest_counts[time_][i] + in_transit_counts[time_][i];
				// std::cout << "vhs_owned[" << i << "] = " << vhs_owned[i] << std::endl;
				cust_vhs_at_t[time_] += cust_balance_at[i];
			}
			if (time_ == 0) { // one print function to validate the above loop
				std::cout << "cust_vhs_at_t[" << time_ << "] = " << cust_vhs_at_t[time_] << std::endl;
			}
		}

		GRBLinExpr idle_veh = 0; // Gurobi Linear Expression, total number of idle vehicles now
		GRBLinExpr reb_arr = 0; // Gurobi Linear Expression, total number of rebalancing vehicles arriving and in transit to station i

		GRBLinExpr idle_veh_prev = 0; // Gurobi Linear Expression, total number of idle vehicles at previous interval
		GRBLinExpr reb_arr_prev = 0; // Gurobi Linear Expression, total number of rebalancing vehicles arriving and in transit to station i at previous time

		for ( time_ = 0; time_ < nRebPeriods; ++time_) {
			std::cout << "time_ = " << time_ << std::endl;

			// adding variables at current time t
			for(int i = 0; i < nStations; ++i) {
				// idle vehicles at station i at time t
				idle_veh += vi[time_][i];

				for(int j = 0; j < nStations; ++j) {
					if (i != j) {

						// travel_time is expressed in the number of reb periods, i.e., 1,2,3,...nRebPeriods
						// travel_time for trips arriving to i from j
						int travel_time = (int) (rounded_cost[j][i]/reb_period);
						// index of vehicles arriving at i from j (departed from j to i travel_time ago)
						int idx_arr = stationMatrix[j][i];
						// divresult.rem is start time of the arriving trips
						divresult = div (nRebPeriods + time_ - travel_time, nRebPeriods);
						// std::cout << "Current time = " << time_ << ", travel_time = " << travel_time << ", divresult.rem = " << divresult.rem << ", idx_arr = "<< idx_arr << std::endl;
						reb_arr += rij[divresult.rem][idx_arr];
						// empty trips in transit (not arriving yet)
						// if tt > 1 -> all trips started after divresult.rem and before time_
						if (travel_time > 1) {
							for (int k = 1; k < travel_time; ++k) {
								divresult = div (nRebPeriods + time_ - travel_time + k, nRebPeriods);
								// std::cout << "if travel_time > 1 => " << time_ << ", travel_time = " << travel_time << ", divresult.rem = " << divresult.rem << ", idx_arr = "<< idx_arr << std::endl;
								reb_arr += rij[divresult.rem][idx_arr];
							}
						}
					}
				}
			}

			// adding variables at time (t-1)
			for(int i = 0; i < nStations; ++i) {
				// idle vehicles at station i at time (t - 1)
				divresult = div (nRebPeriods + time_ - 1, nRebPeriods);
				idle_veh_prev += vi[divresult.rem][i];

				for(int j = 0; j < nStations; ++j) {
					if (i != j) {

						// travel_time is expressed in the number of reb periods, i.e., 1,2,3,...nRebPeriods
						// travel_time for trips arriving to i from j
						int travel_time = (int) (rounded_cost[j][i]/reb_period);
						// index of vehicles arriving at i from j (departed from j to i travel_time ago)
						int idx_arr = stationMatrix[j][i];
						// divresult.rem is start time of the arriving trips
						divresult = div (nRebPeriods + time_ - 1 - travel_time, nRebPeriods);
						// std::cout << "Previous time = " << nRebPeriods + time_ - 1 << ", travel_time = " << travel_time << ", divresult.rem = " << divresult.rem << ", idx_arr = "<< idx_arr << std::endl;
						reb_arr_prev += rij[divresult.rem][idx_arr];
						// empty trips in transit (not arriving yet)
						// if tt > 1 -> all trips started after divresult.rem and before time_
						if (travel_time > 1) {
							for (int k = 1; k < travel_time; ++k) {
								divresult = div (nRebPeriods + time_ - 1 - travel_time + k, nRebPeriods);
								reb_arr_prev += rij[divresult.rem][idx_arr];
							}
						}
					}
				}
			}

			// add constraints
			ostringstream cname;
			cname << "supply_t" << time_ ;

			// total number of vehicles at time t == total number of vehicles at time (t-1)
			divresult = div (nRebPeriods + time_ - 1, nRebPeriods);
			model.addConstr(idle_veh + reb_arr + cust_vhs_at_t[time_] == idle_veh_prev + reb_arr_prev + cust_vhs_at_t[divresult.rem], cname.str());
			model.update();

			idle_veh.clear();
			idle_veh_prev.clear();
			reb_arr.clear();
			reb_arr_prev.clear();

		} // end constraints loop: for ( time_ = 0; time_ < nRebPeriods; ++time_)
		std::cout << "Constraint set 2 added." << std::endl;

		/***********************************************************************************
		 * Constraint 3: Flow conservation at station i
		 ***********************************************************************************/
		// This constraint is set to ensure that the number of vehicles available at station i at time t
		// is equal to the number of vehicles available at this station in previous time interval
		// plus whatever has arrived minus whatever has departed
		for ( time_ = 0; time_ < nRebPeriods; ++time_) {
			// Current demand
			int dem_curr[nStations];
			for (int i = 0; i < nStations; ++i) {
				// current demand = arriving_vehicles - departing_vehicles
				dem_curr[i] = dest_counts[time_][i] - origin_counts[time_][i];
				// std::cout << origin_counts[time_][i] << " - " << dest_counts[time_][i] << " = " << dem_curr[i] << std::endl;
			}

			GRBLinExpr reb_dep = 0;
			GRBLinExpr reb_arr = 0;

			for(int depSt = 0; depSt < nStations; ++depSt){
				// std::cout << "departure station: " << depSt << std::endl;
				for (int arrSt = 0; arrSt < nStations; ++arrSt) {

					if (depSt != arrSt) {
						int idx = stationMatrix[depSt][arrSt];
						int idx2 = stationMatrix[arrSt][depSt];
						reb_dep += rij[time_][idx];
						// std::cout << "rounded_cost = " << (int)rounded_cost[depSt][arrSt]/reb_period -1 << std::endl;
						int travel_cost = (int) (rounded_cost[depSt][arrSt]/reb_period);
						if (travel_cost > time_) {
							int dep_time = nRebPeriods + time_ - travel_cost;
							reb_arr += rij[dep_time][idx2];
						} else {
							int dep_time = time_ - travel_cost;
							reb_arr += rij[dep_time][idx2];
						}
					}
				}
				ostringstream cname;
				cname << "flow_ti" << time_ << "." << depSt;
				if (time_ != nRebPeriods - 1) {
					model.addConstr(vi[time_ + 1][depSt] ==
							vi[time_][depSt] + reb_arr - reb_dep + dem_curr[depSt], cname.str());
				} else {
					// if we are in the last interval then we compare against the first interval of the next day
					// here: vi(t=0) == vi(t=Tp)
					model.addConstr(vi[0][depSt] ==
							vi[time_][depSt] + reb_arr - reb_dep + dem_curr[depSt], cname.str());
				}
				//std::cout << "Constraint 1 vi @: " << time_  << "." << depSt << std::endl;
				reb_arr.clear();
				reb_dep.clear();
			}
		}
		model.update();
		std::cout << "Constraint set 3 added." << std::endl;
		/***********************************************************************************
		 * Solve the problem and print solution to the console and to the file
		 ***********************************************************************************/
		model.optimize();
		model.write(modelOutput);

		int total_demand = 0;
		int dem_curr[nStations];
		for (int i = 0; i < nStations; ++i) {
			dem_curr[i] = dest_counts[0][i] + in_transit_counts[0][i];
			total_demand += dem_curr[i];
		}

		double numOfVeh = model.get(GRB_DoubleAttr_ObjVal) + total_demand; //plus rebalancing counts

		cout << "\nTOTAL NUMBER OF VEHICLES: " << numOfVeh << std::endl;
		cout << "\nTOTAL NUMBER OF AVAILABLE VEH AT TIME 0: " << model.get(GRB_DoubleAttr_ObjVal) << std::endl;
		//		cout << "SOLUTION:" << endl;
		//
		//		for (time_ = 0; time_ < nRebPeriods; ++time_){
		//
		//			for(int depSt = 0; depSt < nStations; ++depSt){
		//				for (int arrSt = 0; arrSt < nStations; ++arrSt) {
		//					if(depSt != arrSt) {
		//						int idx = stationMatrix[depSt][arrSt];
		//						cout << "At time " << time_ << ", rebalancing from station " << depSt <<
		//								" to station " << arrSt << " send "  <<
		//								empty_veh[time_][idx].get(GRB_DoubleAttr_X) << " vehicles." << std::endl;
		//					}
		//				}
		//			}
		//		}
		//
		//		for (time_ = 0; time_ < nRebPeriods; ++time_){
		//			for(int arrSt = 0; arrSt < nStations; ++arrSt){
		//				cout << "At time " << time_ << " at station " << arrSt <<
		//						" number of available vehicles: " << vhs_st_i[time_][arrSt].get(GRB_DoubleAttr_X) << std::endl;
		//			}
		//			cout << "At time " << time_ << " number of vehicles in transit: "
		//					<< in_transit[time_].get(GRB_DoubleAttr_X) << std::endl;
		//		}

		model.write(solutionOutput);

	} catch(GRBException e) {
		cout << "Error code = " << e.getErrorCode() << std::endl;
		cout << e.getMessage() << std::endl;
	} catch(...) {
		cout << "Exception during optimization" << std::endl;
	}
	return 0;
}
Beispiel #10
0
int
main(int argc,
     char *argv[])
{
  GRBEnv* env = 0;
  GRBVar* open = 0;
  GRBVar** transport = 0;
  int transportCt = 0;
  try
  {

    // Number of plants and warehouses
    const int nPlants = 5;
    const int nWarehouses = 4;

    // Warehouse demand in thousands of units
    double Demand[] = { 15, 18, 14, 20 };

    // Plant capacity in thousands of units
    double Capacity[] = { 20, 22, 17, 19, 18 };

    // Fixed costs for each plant
    double FixedCosts[] =
      { 12000, 15000, 17000, 13000, 16000 };

    // Transportation costs per thousand units
    double TransCosts[][nPlants] = {
                                     { 4000, 2000, 3000, 2500, 4500 },
                                     { 2500, 2600, 3400, 3000, 4000 },
                                     { 1200, 1800, 2600, 4100, 3000 },
                                     { 2200, 2600, 3100, 3700, 3200 }
                                   };

    // Model
    env = new GRBEnv();
    GRBModel model = GRBModel(*env);
    model.set(GRB_StringAttr_ModelName, "facility");

    // Plant open decision variables: open[p] == 1 if plant p is open.
    open = model.addVars(nPlants, GRB_BINARY);
    model.update();
    for (int p = 0; p < nPlants; ++p)
    {
      ostringstream vname;
      vname << "Open" << p;
      open[p].set(GRB_DoubleAttr_Obj, FixedCosts[p]);
      open[p].set(GRB_StringAttr_VarName, vname.str());
    }

    // Transportation decision variables: how much to transport from
    // a plant p to a warehouse w
    transport = new GRBVar* [nWarehouses];
    for (int w = 0; w < nWarehouses; ++w)
    {
      transport[w] = model.addVars(nPlants);
      transportCt++;
      model.update();
      for (int p = 0; p < nPlants; ++p)
      {
        ostringstream vname;
        vname << "Trans" << p << "." << w;
        transport[w][p].set(GRB_DoubleAttr_Obj, TransCosts[w][p]);
        transport[w][p].set(GRB_StringAttr_VarName, vname.str());
      }
    }

    // The objective is to minimize the total fixed and variable costs
    model.set(GRB_IntAttr_ModelSense, 1);

    // Update model to integrate new variables
    model.update();
    model.write("prob.lp");

    // Production constraints
    // Note that the right-hand limit sets the production to zero if
    // the plant is closed
    for (int p = 0; p < nPlants; ++p)
    {
      GRBLinExpr ptot = 0;
      for (int w = 0; w < nWarehouses; ++w)
      {
        ptot += transport[w][p];
      }
      ostringstream cname;
      cname << "Capacity" << p;
      model.addConstr(ptot <= Capacity[p] * open[p], cname.str());
    }

    // Demand constraints
    for (int w = 0; w < nWarehouses; ++w)
    {
      GRBLinExpr dtot = 0;
      for (int p = 0; p < nPlants; ++p)
      {
        dtot += transport[w][p];
      }
      ostringstream cname;
      cname << "Demand" << w;
      model.addConstr(dtot == Demand[w], cname.str());
    }

    // Guess at the starting point: close the plant with the highest
    // fixed costs; open all others

    // First, open all plants
    for (int p = 0; p < nPlants; ++p)
    {
      open[p].set(GRB_DoubleAttr_Start, 1.0);
    }

    // Now close the plant with the highest fixed cost
    cout << "Initial guess:" << endl;
    double maxFixed = -GRB_INFINITY;
    for (int p = 0; p < nPlants; ++p)
    {
      if (FixedCosts[p] > maxFixed)
      {
        maxFixed = FixedCosts[p];
      }
    }
    for (int p = 0; p < nPlants; ++p)
    {
      if (FixedCosts[p] == maxFixed)
      {
        open[3].set(GRB_DoubleAttr_Start, 0.0);
        cout << "Closing plant " << p << endl << endl;
        break;
      }
    }

    // Use barrier to solve root relaxation
    model.getEnv().set(GRB_IntParam_Method, GRB_METHOD_BARRIER);

    // Solve
    model.optimize();

    // Print solution
    cout << "\nTOTAL COSTS: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
    cout << "SOLUTION:" << endl;
    for (int p = 0; p < nPlants; ++p)
    {
      if (open[p].get(GRB_DoubleAttr_X) == 1.0)
      {
        cout << "Plant " << p << " open:" << endl;
        for (int w = 0; w < nWarehouses; ++w)
        {
          if (transport[w][p].get(GRB_DoubleAttr_X) > 0.0001)
          {
            cout << "  Transport " <<
            transport[w][p].get(GRB_DoubleAttr_X) <<
            " units to warehouse " << w << endl;
          }
        }
      }
      else
      {
        cout << "Plant " << p << " closed!" << endl;
      }
    }

  }
  catch (GRBException e)
  {
    cout << "Error code = " << e.getErrorCode() << endl;
    cout << e.getMessage() << endl;
  }
  catch (...)
  {
    cout << "Exception during optimization" << endl;
  }

  delete[] open;
  for (int i = 0; i < transportCt; ++i) {
    delete[] transport[i];
  }
  delete[] transport;
  delete env;
  return 0;
}
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;
    }
  }
}