vector <double> solve(int verbose, vector <vector <double> > M) { vector <double> solution; try { GRBEnv env = GRBEnv(); int numPoints = M.size(); int numCircles = M.back().size(); GRBVar p[numPoints]; double coeff[numPoints]; GRBModel model = GRBModel(env); GRBLinExpr expr; if(!verbose) model.getEnv().set(GRB_IntParam_OutputFlag, 0); for (int i=0;i<numPoints;i++){ p[i] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY); coeff[i] = 1.0; } expr.addTerms(coeff, p,numPoints); model.update(); model.setObjective(expr, GRB_MINIMIZE); for(int i=0;i<numCircles;i++){ GRBLinExpr cexpr; double ccoeff[numPoints]; for(int j=0;j<numPoints;j++){ ccoeff[j] = M[j].back(); M[j].pop_back(); } cexpr.addTerms(ccoeff,p,numPoints); model.addConstr(cexpr, GRB_GREATER_EQUAL,1.0); } // Optimize model model.optimize(); for (int i=0;i<numPoints;i++){ solution.push_back((double)p[i].get(GRB_DoubleAttr_X)); } } catch(GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch(...) { cout << "Exception during optimization" << endl; } return solution; }
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); }
int monitoramento_em_grafo_bipartido( ListGraph &g, NodeName &vname, ListGraph::NodeMap<double> &custo, ListGraph::NodeMap<int> &solucao) { int seed=0; GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); model.getEnv().set(GRB_IntParam_Seed, seed); model.set(GRB_StringAttr_ModelName, "Monitoramento em Grafo Bipartido"); // prob. name model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem // ------------------------------------------------------ // Construa o modelo daqui para baixo // ------------------------------------------------------ // Exemplos de como voce pode declarar variaveis indexadas nos vertices ou nas arestas. // Nao necessariamente voce precisa dos dois tipos // ListGraph::NodeMap<GRBVar> x(g); // variables for each node // ListGraph::EdgeMap<GRBVar> y(g); // variables for each edge ListGraph::NodeMap<GRBVar> x(g); // variables for each node ListGraph::EdgeMap<GRBVar> y(g); // variables for each edge int name = 0; char namme[100]; for(ListGraph::NodeIt v(g); v != INVALID; ++v) { sprintf(namme,"PC_%s",vname[v].c_str()); x[v] = model.addVar(0.0, 1.0, custo[v],GRB_CONTINUOUS,namme); } model.update(); try { for(ListGraph::EdgeIt e(g); e != INVALID; ++e) { //Para cada aresta, um dos lados e 1 GRBLinExpr expr; expr += x[g.u(e)]; expr += x[g.v(e)]; model.addConstr(expr >= 1); } model.update(); // ------------------------------------------------------ // Construa o modelo daqui para cima // ------------------------------------------------------ //model.write("model.lp"); system("cat model.lp"); model.optimize(); for (ListGraph::NodeIt v(g); v!=INVALID; ++v) { if (x[v].get(GRB_DoubleAttr_X)>1-EPS) solucao[v] = 1; else solucao[v] = 0; //solucao[v] = 1; } return(1); } catch (...) {cout << "Error during callback..." << endl; return(0);} }
int main(int argc, char *argv[]) { int k,found; Digraph g; // graph declaration string digraph_kpaths_filename, source_node_name, target_node_name; DiNodeName vname(g); // name of graph nodes Digraph::NodeMap<double> px(g),py(g); // xy-coodinates for each node Digraph::NodeMap<int> vcolor(g);// color of nodes Digraph::ArcMap<int> ecolor(g); // color of edges ArcWeight lpvar(g); // used to obtain the contents of the LP variables ArcWeight weight(g); // edge weights Digraph::ArcMap<GRBVar> x(g); // binary variables for each arc vector <DiNode> V; DiNode source,target; int seed=0; 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"); // double cutoff; // used to prune non promissing branches (of the B&B tree) if (argc!=5) {cout<<endl<<"Usage: "<< argv[0]<<" <digraph_kpaths_filename> <source_node_name> <target_node_name> <k>"<< endl << endl; cout << "Example: " << argv[0] << " digr_triang_sparse_100 12 50 5" << endl << endl; exit(0);} digraph_kpaths_filename = argv[1]; source_node_name = argv[2]; target_node_name = argv[3]; k = atoi(argv[4]); GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); model.getEnv().set(GRB_IntParam_Seed, seed); model.set(GRB_StringAttr_ModelName, "Oriented k-Paths with GUROBI"); // prob. name model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem ReadListDigraph(digraph_kpaths_filename,g,vname,weight,px,py,0); found=0; for (DiNodeIt v(g);v!=INVALID;++v) if(vname[v]==source_node_name){source=v;found=1;break;} if (!found) {cout<<"Could not find source node "<<source_node_name<<endl;exit(0);} found=0; for (DiNodeIt v(g);v!=INVALID;++v) if(vname[v]==target_node_name){target=v;found=1;break;} if (!found) {cout<<"Could not find target node "<<target_node_name<<endl;exit(0);} kPaths_Instance T(g,vname,px,py,weight,source,target,k); //for (DiNodeIt v(g);v!=INVALID;++v){ if(v==T.V[0])vcolor[v]=RED; else vcolor[v]=BLUE;} //for (int i=1;i<T.nt;i++) vcolor[T.V[i]] = MAGENTA; //for (ArcIt e(g); e != INVALID; ++e) ecolor[e] = BLUE; //ViewListDigraph(g,vname,px,py,vcolor,ecolor,"Triangulated graph"); // Generate the binary variables and the objective function // Add one binary variable for each edge and set its cost in the objective function for (Digraph::ArcIt e(g); e != INVALID; ++e) { char name[100]; sprintf(name,"X_%s_%s",vname[g.source(e)].c_str(),vname[g.target(e)].c_str()); x[e] = model.addVar(0.0, 1.0, weight[e],GRB_CONTINUOUS,name); } model.update(); // run update to use model inserted variables try { //if (time_limit >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,time_limit); //model.getEnv().set(GRB_DoubleParam_ImproveStartTime,10); //try better sol. aft. 10s // if (cutoff > 0) model.getEnv().set(GRB_DoubleParam_Cutoff, cutoff ); //model.write("model.lp"); system("cat model.lp"); // Add degree constraint for each node (sum of solution edges incident to a node is 2) for (Digraph::NodeIt v(g); v!=INVALID; ++v) { GRBLinExpr exprin, exprout; for (Digraph::InArcIt e(g,v); e != INVALID; ++e) exprin += x[e]; for (Digraph::OutArcIt e(g,v); e != INVALID; ++e) exprout += x[e]; if (v==source) model.addConstr(exprout - exprin == k ); else if (v==target) model.addConstr(exprin - exprout == k ); else model.addConstr(exprin - exprout == 0 ); } model.optimize(); double soma=0.0; for (DiNodeIt v(g);v!=INVALID;++v) vcolor[v]=BLUE; // all nodes BLUE vcolor[source]=RED; // change the colors of the source node vcolor[target]=RED; // and the target node to RED for (Digraph::ArcIt e(g); e!=INVALID; ++e) { lpvar[e] = x[e].get(GRB_DoubleAttr_X); if (lpvar[e] > 1.0 - EPS) soma += weight[e]; } cout << "kPaths Tree Value = " << soma << endl; //----------------------------------------------------------------- // By Lucas Prado Melo: coloring paths by bfs bool ok = true; for(int i=0; i < k && ok; i++) { queue<DiNode> q; Digraph::NodeMap<Arc> pre(g, INVALID); q.push(source); while (!q.empty()) { DiNode cur = q.front(); q.pop(); for(Digraph::OutArcIt e(g, cur); e!=INVALID; ++e) { DiNode nxt = g.runningNode(e); if (pre[nxt] == INVALID && ecolor[e] == NOCOLOR && lpvar[e] > 1.0 - EPS) { pre[nxt] = e; q.push(nxt); } } } if (pre[target] == INVALID) ok = false; else { DiNode x = target; while (x != source) { ecolor[pre[x]] = 3+i%6; // use colors 3(RED) to 8(CYAN), see myutils.h x = g.oppositeNode(x, pre[x]); } } } if (!ok) {cout << "Nao eh possivel encontrar os " << k << " caminhos!" << endl;} for(Digraph::ArcIt e(g); e!=INVALID; ++e) { if (lpvar[e] > 1.0 - EPS && ecolor[e] == NOCOLOR ) { cout << "Alguma(s) aresta(s) nao pertencem a qualquer caminho!" << endl; break; } } for(Digraph::ArcIt e(g); e!=INVALID; ++e) { if (lpvar[e] < 1.0-EPS && lpvar[e] > EPS) { ecolor[e] = GRAY; } } for(Digraph::ArcIt e(g); e!=INVALID; ++e) { if (lpvar[e] < 1.0-EPS && lpvar[e] > EPS) { cout << "Alguma(s) aresta(s) possuem valor fracionario! (marcadas com cor cinza claro)" << endl; break; } } //----------------------------------------------------------------- cout << "kPaths Tree Value = " << soma << endl; ViewListDigraph(g,vname,px,py,vcolor,ecolor, "minimum kPaths cost in graph with "+IntToString(T.nnodes)+ " nodes and "+IntToString(k)+" paths: "+DoubleToString(soma)); } catch (...) {cout << "Error during callback..." << endl; } return 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; }
// 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[]) { 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; }
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[]) { if (argc < 2) { cout << "Usage: tsp_c++ filename" << endl; return 1; } int n = atoi(argv[1]); double* x = new double[n]; double* y = new double[n]; for (int i = 0; i < n; i++) { x[i] = ((double) rand())/RAND_MAX; y[i] = ((double) rand())/RAND_MAX; } GRBEnv *env = NULL; GRBVar **vars = new GRBVar*[n]; try { int i, j; env = new GRBEnv(); GRBModel model = GRBModel(*env); // Must disable dual reductions when using lazy constraints model.getEnv().set(GRB_IntParam_DualReductions, 0); // Create binary decision variables for (i = 0; i < n; i++) vars[i] = model.addVars(n); model.update(); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { vars[i][j].set(GRB_CharAttr_VType, GRB_BINARY); vars[i][j].set(GRB_DoubleAttr_Obj, distance(x, y, i, j)); vars[i][j].set(GRB_StringAttr_VarName, "x_"+itos(i)+"_"+itos(j)); } } // Integrate new variables model.update(); // Degree-2 constraints for (i = 0; i < n; i++) { GRBLinExpr expr = 0; for (j = 0; j < n; j++) expr += vars[i][j]; model.addConstr(expr == 2, "deg2_"+itos(i)); } // Forbid edge from node back to itself for (i = 0; i < n; i++) vars[i][i].set(GRB_DoubleAttr_UB, 0); // Symmetric TSP for (i = 0; i < n; i++) for (j = 0; j < i; j++) model.addConstr(vars[i][j] == vars[j][i]); // Set callback function subtourelim cb = subtourelim(vars, n); model.setCallback(&cb); // Optimize model model.optimize(); // Extract solution if (model.get(GRB_IntAttr_SolCount) > 0) { double **sol = new double*[n]; for (i = 0; i < n; i++) sol[i] = model.get(GRB_DoubleAttr_X, vars[i], n); int* tour = new int[n]; int len; findsubtour(n, sol, &len, tour); cout << "Tour: "; for (i = 0; i < len; i++) cout << tour[i] << " "; cout << endl; for (i = 0; i < n; i++) delete[] sol[i]; delete[] sol; delete[] tour; } } catch (GRBException e) { cout << "Error number: " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Error during optimization" << endl; } for (int i = 0; i < n; i++) delete[] vars[i]; delete[] vars; delete[] x; delete[] y; delete env; return 0; }
std::map<std::string,int> ILP(char* argv) { map<string, int > results; GRBVar* vars = 0; // if (argc < 2) { // cout << "Usage: lp_c++ filename" << endl; // return 1; // } try { GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env, argv); //model.getEnv().set(GRB_DoubleParam_IntFeasTol,1e-6); model.getEnv().set(GRB_DoubleParam_Heuristics,0.95); model.getEnv().set(GRB_DoubleParam_TimeLimit,timeMax); model.getEnv().set(GRB_DoubleParam_MIPGap, ilpGap); vars = model.getVars(); model.optimize(); int optimstatus = model.get(GRB_IntAttr_Status); if (optimstatus == GRB_INF_OR_UNBD) { model.getEnv().set(GRB_IntParam_Presolve, 0); model.optimize(); optimstatus = model.get(GRB_IntAttr_Status); } if (optimstatus == GRB_OPTIMAL) { double objval = model.get(GRB_DoubleAttr_ObjVal); cout << "Optimal objective: " << objval << endl; for(int i =0; i<model.get(GRB_IntAttr_NumVars);i++){ string varName = vars[i].get(GRB_StringAttr_VarName); results[varName] = vars[i].get(GRB_DoubleAttr_X); // cout << vars[i].get(GRB_StringAttr_VarName) << " " << vars[i].get(GRB_DoubleAttr_X) << endl; } ofstream varNames; ofstream varResults; varNames.open("varName.txt"); varResults.open("varResults.txt"); for(int i =0; i<model.get(GRB_IntAttr_NumVars);i++){ string varName = vars[i].get(GRB_StringAttr_VarName); results[varName] = vars[i].get(GRB_DoubleAttr_X)+0.5; // +0.5 to make sure its round if(varName == "co2o3storagey3" ){ cout << "gotte ya" <<endl; } varNames << varName << "\n"; varResults << varName << " "<< results[varName] << "\n"; //cout << vars[i].get(GRB_StringAttr_VarName) << " " << vars[i].get(GRB_DoubleAttr_X) << endl; } varNames.close(); varResults.close(); cout << "size of results is " << sizeof(results)*results.size()<< endl; cout << "using mapSize function, size is " << mapSize(results)<<endl; toFile(results,mapSize(results)); } else if (optimstatus == GRB_INFEASIBLE) { cout << "Model is infeasible" << endl; // compute and write out IIS //model.computeIIS(); //model.write("model.ilp"); } else if (optimstatus == GRB_UNBOUNDED) { cout << "Model is unbounded" << endl; } else { cout << "Optimization was stopped with status = " << optimstatus << endl; double objval = model.get(GRB_DoubleAttr_ObjVal); cout << "Optimal objective: " << objval << endl; for(int i =0; i<model.get(GRB_IntAttr_NumVars);i++){ string varName = vars[i].get(GRB_StringAttr_VarName); results[varName] = vars[i].get(GRB_DoubleAttr_X); // cout << vars[i].get(GRB_StringAttr_VarName) << " " << vars[i].get(GRB_DoubleAttr_X) << endl; } ofstream varNames; ofstream varResults; varNames.open("varName.txt"); varResults.open("varResults.txt"); for(int i =0; i<model.get(GRB_IntAttr_NumVars);i++){ string varName = vars[i].get(GRB_StringAttr_VarName); results[varName] = vars[i].get(GRB_DoubleAttr_X)+0.5; // +0.5 to make sure its round if(varName == "co2o3storagey3" ){ cout << "gotte ya" <<endl; } varNames << varName << "\n"; varResults << varName << " = "<< results[varName] << "\n"; //cout << vars[i].get(GRB_StringAttr_VarName) << " " << vars[i].get(GRB_DoubleAttr_X) << endl; } varNames.close(); varResults.close(); } } catch(GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Error during optimization" << endl; } return results; //return 0; }
void solve(Instance inst, bool hsol = false){ clock_t t0 = CURTIME; ArcflowMKP graph(inst); const vector<Item> &items = inst.items; GRBEnv* env = new GRBEnv(); GRBModel master = GRBModel(*env); master.set(GRB_StringAttr_ModelName, "GG"); master.getEnv().set(GRB_IntParam_OutputFlag, 0); master.getEnv().set(GRB_IntParam_Threads, 1); master.getEnv().set(GRB_IntParam_Method, 0); GRBConstr rows[inst.m]; for(int i = 0; i < inst.m; i++){ GRBLinExpr lin = 0; rows[i] = master.addConstr(lin >= items[i].demand); } master.update(); vector<GRBVar> vars; for(int i = 0; i < inst.m; i++){ GRBColumn col = GRBColumn(); col.addTerm(1, rows[i]); vars.push_back(master.addVar(0, GRB_INFINITY, 1, GRB_CONTINUOUS, col)); } printf("m: %d\n", inst.m); vector<double> values(inst.m); for(int itr = inst.m; ; itr++){ master.optimize(); printf("%d: %.6f (%.2fs)\n", itr, master.get(GRB_DoubleAttr_ObjVal), TIMEDIF(t0)); for(int i = 0; i < inst.m; i++) values[i] = rows[i].get(GRB_DoubleAttr_Pi); vector<int_pair> sol = graph.knapsack(values, 1+EPSILON); if(sol.empty()) break; GRBColumn col = GRBColumn(); ForEach(itr, sol) col.addTerm(itr->second, rows[itr->first]); vars.push_back(master.addVar(0, GRB_INFINITY, 1, GRB_CONTINUOUS, col)); master.update(); } printf("zlp: %.6f\n", master.get(GRB_DoubleAttr_ObjVal)); printf("nvars: %d\n", master.get(GRB_IntAttr_NumVars)); printf("time: %.2fs\n", TIMEDIF(t0)); if(hsol){ // find an heuristic solution if hsol = true ForEach(itr, vars) itr->set(GRB_CharAttr_VType, GRB_INTEGER); master.getEnv().set(GRB_IntParam_OutputFlag, 1); master.getEnv().set(GRB_IntParam_Threads, 1); //master.getEnv().set(GRB_IntParam_Presolve, 1); //master.getEnv().set(GRB_IntParam_Method, 2); master.getEnv().set(GRB_IntParam_MIPFocus, 1); master.getEnv().set(GRB_DoubleParam_Heuristics, 1); master.getEnv().set(GRB_DoubleParam_MIPGap, 0); master.getEnv().set(GRB_DoubleParam_MIPGapAbs, 1-1e-5); master.optimize(); printf("Total run time: %.2f seconds\n", TIMEDIF(t0)); } free(env); }
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(); int p; for (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]; int w; for (w = 0; w < nWarehouses; ++w) { transport[w] = model.addVars(nPlants); transportCt++; model.update(); for (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(); // Production constraints // Note that the right-hand limit sets the production to zero if // the plant is closed for (p = 0; p < nPlants; ++p) { GRBLinExpr ptot = 0; for (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 (w = 0; w < nWarehouses; ++w) { GRBLinExpr dtot = 0; for (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 (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 (p = 0; p < nPlants; ++p) { if (FixedCosts[p] > maxFixed) { maxFixed = FixedCosts[p]; } } for (p = 0; p < nPlants; ++p) { if (FixedCosts[p] == maxFixed) { open[p].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 (p = 0; p < nPlants; ++p) { if (open[p].get(GRB_DoubleAttr_X) == 1.0) { cout << "Plant " << p << " open:" << endl; for (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; }
// Start the optimization SolverResult SolverGurobi::runOptimizer() { if (!getInitialized()) initialize(); try { // Create Gurobi environment and set parameters GRBEnv env = GRBEnv(); env.set(GRB_IntParam_OutputFlag, 0); GRBModel model = GRBModel(env); // Get problem info int numVars = constraints->getNumVariables(); int numConstraints = constraints->getNumConstraints(); // Get variables auto variables = constraints->getVariables(); // Create array of model variables GRBVar vars[numVars]; for (int i = 0; i < numVars; i++) { //vars[i] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY); // Set variable type char type = GRB_CONTINUOUS; if (variables.at(i)->getType() == VariableType::BINARY) { type = GRB_BINARY; } else if (variables.at(i)->getType() == VariableType::INTEGER) { type = GRB_INTEGER; } vars[i] = model.addVar(variables.at(i)->getLowerBound(), variables.at(i)->getUpperBound(), variables.at(i)->getCost(), type); } // Integrate variables into model model.update(); // Set starting points (does not help much...) for (int i = 0; i < numVars; i++) vars[i].set(GRB_DoubleAttr_Start, variables.at(i)->getValue()); /* * Add constraints Ax <= b (or Ax = b) * by evaluating gradient and build A matrix */ DenseVector x = DenseVector::Zero(numVars); DenseVector dx = constraints->evalJacobian(x); // Get constraint bounds std::vector<double> clb; std::vector<double> cub; constraints->getConstraintBounds(clb,cub); std::vector<int> rowGradient, colGradient; constraints->structureJacobian(rowGradient, colGradient); int nnzJacobian = constraints->getNumNonZerosJacobian(); // Add constraints one row at the time for (int row = 0; row < numConstraints; row++) { // Build constraint GRBLinExpr expr = 0; // Loop through all non-zeros (inefficient) for (int i = 0; i < nnzJacobian; i++) { if (rowGradient.at(i) == row) { int j = colGradient.at(i); expr += dx(i)*vars[j]; } } // Add constraint to model if (clb.at(row) == cub.at(row)) { model.addConstr(expr, GRB_EQUAL, cub.at(row)); } else { model.addConstr(expr, GRB_LESS_EQUAL, cub.at(row)); } } // More efficient method - avoids dense matrix // std::vector<int> rows = {1,1,1,2,2,3,4,4,4,4,4,5}; // std::vector<int>::iterator start,stop; // start = rows.begin(); // stop = start; // while (start != rows.end()) // { // while (stop != rows.end()) // { // if (*stop == *start) // ++stop; // else // break; // } // for (std::vector<int>::iterator it = start; it != stop; ++it) // cout << *it << endl; // start = stop; // } model.update(); assert(numVars == model.get(GRB_IntAttr_NumVars)); assert(numConstraints == model.get(GRB_IntAttr_NumConstrs)); // Optimize model model.optimize(); // Check status int optimstatus = model.get(GRB_IntAttr_Status); if (optimstatus == GRB_INF_OR_UNBD) { model.getEnv().set(GRB_IntParam_Presolve, 0); model.optimize(); optimstatus = model.get(GRB_IntAttr_Status); } // Create result object SolverResult result(SolverStatus::ERROR, INF, std::vector<double>(numVars,0)); // Check Gurobi status if (optimstatus == GRB_OPTIMAL) { result.status = SolverStatus::OPTIMAL; // Get solution info result.objectiveValue = model.get(GRB_DoubleAttr_ObjVal); std::vector<double> optimalSolution; for (int i = 0; i < numVars; i++) { optimalSolution.push_back(vars[i].get(GRB_DoubleAttr_X)); } result.primalVariables = optimalSolution; /* * Reduced costs and constraint duals are * only available for continuous models */ std::vector<double> reducedCosts; std::vector<double> constraintDuals; if (!model.get(GRB_IntAttr_IsMIP)) { for (int i = 0; i < numVars; i++) { // Get reduced costs (related to range constraint duals) reducedCosts.push_back(vars[i].get(GRB_DoubleAttr_RC)); } for (int i = 0; i < numConstraints; i++) { GRBConstr c = model.getConstr(i); double pi = c.get(GRB_DoubleAttr_Pi); constraintDuals.push_back(pi); } } result.lowerBoundDualVariables = reducedCosts; result.upperBoundDualVariables = reducedCosts; result.constraintDualVariables = constraintDuals; return result; } else if (optimstatus == GRB_INFEASIBLE) { result.status = SolverStatus::INFEASIBLE; result.objectiveValue = INF; // compute and write out IIS // model.computeIIS(); // model.write("problem.lp"); return result; } else if (optimstatus == GRB_UNBOUNDED) { result.status = SolverStatus::UNBOUNDED; result.objectiveValue = -INF; return result; } else { result.status = SolverStatus::ERROR; result.objectiveValue = INF; return result; } } catch(GRBException e) { cout << "SolverGurobi: Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; return SolverResult(SolverStatus::ERROR, INF, std::vector<double>(constraints->getNumVariables(),0)); } catch (...) { cout << "SolverGurobi: Error during optimization!" << endl; return SolverResult(SolverStatus::ERROR, INF, std::vector<double>(constraints->getNumVariables(),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) {
void solve(const Instance &inst, bool print_inst = false, bool pyout = false) { Arcflow afg(inst); char vtype = inst.vtype; GRBEnv* env = new GRBEnv(); GRBModel model = GRBModel(*env); model.set(GRB_StringAttr_ModelName, "flow"); model.getEnv().set(GRB_IntParam_OutputFlag, 1); model.getEnv().set(GRB_IntParam_Threads, 1); model.getEnv().set(GRB_IntParam_Presolve, 1); // model.getEnv().set(GRB_IntParam_Method, 0); model.getEnv().set(GRB_IntParam_Method, 2); model.getEnv().set(GRB_IntParam_MIPFocus, 1); // model.getEnv().set(GRB_IntParam_RINS, 1); model.getEnv().set(GRB_DoubleParam_Heuristics, 1); model.getEnv().set(GRB_DoubleParam_MIPGap, 0); model.getEnv().set(GRB_DoubleParam_MIPGapAbs, 1-1e-5); // model.getEnv().set(GRB_DoubleParam_ImproveStartTime, 60); // model.getEnv().set(GRB_DoubleParam_ImproveStartGap, 1); vector<Arc> As(afg.A); sort(all(As)); map<Arc, GRBVar> va; int lastv = afg.Ts[0]-1; for (int i = 0; i < inst.nbtypes; i++) { lastv = min(lastv, afg.Ts[i]-1); } for (int i = 0; i < 3; i++) { for (const Arc &a : As) { if (i == 1 && a.u != afg.S) { continue; } if (i == 2 && a.v <= lastv) { continue; } if (i == 0 && (a.u == afg.S || a.v > lastv)) { continue; } if (a.label == afg.LOSS || inst.relax_domains) { va[a] = model.addVar( 0.0, inst.n, 0, vtype); } else { va[a] = model.addVar( 0.0, inst.items[a.label].demand, 0, vtype); } } } model.update(); for (int i = 0; i < inst.nbtypes; i++) { GRBVar &feedback = va[Arc(afg.Ts[i], afg.S, afg.LOSS)]; feedback.set(GRB_DoubleAttr_Obj, inst.Cs[i]); if (inst.Qs[i] >= 0) { feedback.set(GRB_DoubleAttr_UB, inst.Qs[i]); } } vector<vector<Arc>> Al(inst.nsizes); vector<vector<Arc>> in(afg.NV); vector<vector<Arc>> out(afg.NV); for (const Arc &a : As) { if (a.label != afg.LOSS) { Al[a.label].push_back(a); } out[a.u].push_back(a); in[a.v].push_back(a); } for (int i = 0; i < inst.m; i++) { GRBLinExpr lin = 0; for (int it = 0; it < inst.nsizes; it++) { if (inst.items[it].type == i) { for (const Arc &a : Al[it]) { lin += va[a]; } } } if (inst.ctypes[i] == '>' || inst.relax_domains) { model.addConstr(lin >= inst.demands[i]); } else { model.addConstr(lin == inst.demands[i]); } } for (int u = 0; u < afg.NV; u++) { GRBLinExpr lin = 0; for (const Arc &a : in[u]) { lin += va[a]; } for (const Arc &a : out[u]) { lin -= va[a]; } model.addConstr(lin == 0); } Al.clear(); in.clear(); out.clear(); double pre = TIMEDIF(afg.tstart); model.optimize(); printf("Preprocessing time: %.2f seconds\n", pre); double tg = model.get(GRB_DoubleAttr_Runtime); printf("Gurobi run time: %.2f seconds\n", tg); printf("Total run time: %.2f seconds\n", tg+pre); if (inst.vtype == 'I') { map<Arc, int> flow; for (const auto &a : va) { double x = a.second.get(GRB_DoubleAttr_X); int rx = static_cast<int>(round(x)); assert(x - rx <= EPS); if (rx > 0) { int u = a.first.u; int v = a.first.v; int lbl = a.first.label; Arc a(u, v, lbl); flow[a] = rx; } } ArcflowSol solution(inst, flow, afg.S, afg.Ts, afg.LOSS, true); solution.print_solution(print_inst, pyout); } free(env); }
int main(int argc, char *argv[]) { int nt; Digraph g; // graph declaration string digraph_steiner_filename; DiNodeName vname(g); // name of graph nodes Digraph::NodeMap<double> px(g),py(g); // xy-coodinates for each node Digraph::NodeMap<int> vcolor(g);// color of nodes Digraph::ArcMap<int> ecolor(g); // color of edges ArcWeight lpvar(g); // used to obtain the contents of the LP variables ArcWeight weight(g); // edge weights Digraph::ArcMap<GRBVar> x(g); // binary variables for each arc vector <DiNode> V; int seed=0; 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 // double cutoff; // used to prune non promissing branches (of the B&B tree) if (argc!=2) {cout<< endl << "Usage: "<< argv[0]<<" <digraph_steiner_filename>"<< endl << endl; cout << "Examples: " << argv[0] << " gr_berlin52.steiner" << endl; cout << " " << argv[0] << " gr_usa48.steiner" << endl << endl; exit(0);} digraph_steiner_filename = argv[1]; //int time_limit = 3600; // solution must be obtained within time_limit seconds GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); model.getEnv().set(GRB_IntParam_LazyConstraints, 1); model.getEnv().set(GRB_IntParam_Seed, seed); model.set(GRB_StringAttr_ModelName, "Oriented Steiner Tree with GUROBI"); // prob. name model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem ReadListDigraphSteiner(digraph_steiner_filename,g,vname,weight,px,py,1,nt,V); Steiner_Instance T(g,vname,px,py,weight,nt,V); //for (DiNodeIt v(g);v!=INVALID;++v){ if(v==T.V[0])vcolor[v]=RED; else vcolor[v]=BLUE;} //for (int i=1;i<T.nt;i++) vcolor[T.V[i]] = MAGENTA; //for (ArcIt e(g); e != INVALID; ++e) ecolor[e] = BLUE; //ViewListDigraph(g,vname,px,py,vcolor,ecolor,"Triangulated graph"); // Generate the binary variables and the objective function // Add one binary variable for each edge and set its cost in the objective function for (Digraph::ArcIt e(g); e != INVALID; ++e) { char name[100]; sprintf(name,"X_%s_%s",vname[g.source(e)].c_str(),vname[g.target(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 try { //if (time_limit >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,time_limit); //model.getEnv().set(GRB_DoubleParam_ImproveStartTime,10); //try better sol. aft. 10s // if (cutoff > 0) model.getEnv().set(GRB_DoubleParam_Cutoff, cutoff ); ConnectivityCuts cb = ConnectivityCuts(T , x); model.setCallback(&cb); model.update(); //model.write("model.lp"); system("cat model.lp"); model.optimize(); double soma=0.0; for (DiNodeIt v(g);v!=INVALID;++v) vcolor[v]=BLUE; // all nodes BLUE for (int i=0;i<T.nt;i++) vcolor[T.V[i]]=MAGENTA; // change terminals to MAGENTA vcolor[T.V[0]]=RED; // change root to RED for (Digraph::ArcIt e(g); e!=INVALID; ++e) { lpvar[e] = x[e].get(GRB_DoubleAttr_X); if (lpvar[e] > 1.0 - EPS) { soma += weight[e]; ecolor[e] = RED; } else ecolor[e] = NOCOLOR; } cout << "Steiner Tree Value = " << soma << endl; ViewListDigraph(g,vname,px,py,vcolor,ecolor, "Steiner Tree cost in graph with "+IntToString(T.nnodes)+ " nodes and "+IntToString(T.nt)+" terminals: "+DoubleToString(soma)); } catch (...) {cout << "Error during callback..." << endl; } 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; } } }