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);} }
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 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[]) { 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; } }
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[]) { GRBEnv* env = 0; GRBVar* nutrition = 0; GRBVar* buy = 0; try { // Nutrition guidelines, based on // USDA Dietary Guidelines for Americans, 2005 // http://www.health.gov/DietaryGuidelines/dga2005/ const int nCategories = 4; string Categories[] = { "calories", "protein", "fat", "sodium" }; double minNutrition[] = { 1800, 91, 0, 0 }; double maxNutrition[] = { 2200, GRB_INFINITY, 65, 1779 }; // Set of foods const int nFoods = 9; string Foods[] = { "hamburger", "chicken", "hot dog", "fries", "macaroni", "pizza", "salad", "milk", "ice cream" }; double cost[] = { 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59 }; // Nutrition values for the foods double nutritionValues[][nCategories] = { { 410, 24, 26, 730 }, // hamburger { 420, 32, 10, 1190 }, // chicken { 560, 20, 32, 1800 }, // hot dog { 380, 4, 19, 270 }, // fries { 320, 12, 10, 930 }, // macaroni { 320, 15, 12, 820 }, // pizza { 320, 31, 12, 1230 }, // salad { 100, 8, 2.5, 125 }, // milk { 330, 8, 10, 180 } // ice cream }; // Model env = new GRBEnv(); GRBModel model = GRBModel(*env); model.set(GRB_StringAttr_ModelName, "diet"); // Create decision variables for the nutrition information, // which we limit via bounds nutrition = model.addVars(minNutrition, maxNutrition, 0, 0, Categories, nCategories); // Create decision variables for the foods to buy buy = model.addVars(0, 0, cost, 0, Foods, nFoods); // The objective is to minimize the costs model.set(GRB_IntAttr_ModelSense, 1); // Update model to integrate new variables model.update(); // Nutrition constraints for (int i = 0; i < nCategories; ++i) { GRBLinExpr ntot = 0; for (int j = 0; j < nFoods; ++j) { ntot += nutritionValues[j][i] * buy[j]; } model.addConstr(ntot == nutrition[i], Categories[i]); } // Solve model.optimize(); printSolution(model, nCategories, nFoods, buy, nutrition); // Add constraint cout << "\nAdding constraint: at most 6 servings of dairy" << endl; model.addConstr(buy[7] + buy[8] <= 6.0, "limit_dairy"); // Solve model.optimize(); printSolution(model, nCategories, nFoods, buy, nutrition); } catch (GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Exception during optimization" << endl; } delete[] nutrition; delete[] buy; delete env; 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; GRBConstr* c = 0; GRBVar* v = 0; GRBVar** x = 0; GRBVar* slacks = 0; GRBVar* totShifts = 0; GRBVar* diffShifts = 0; int xCt = 0; try { // Sample data const int nShifts = 14; const int nWorkers = 7; // Sets of days and workers string Shifts[] = { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string Workers[] = { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" }; // Number of workers required for each shift double shiftRequirements[] = { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Worker availability: 0 if the worker is unavailable for a shift double availability[][nShifts] = { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model env = new GRBEnv(); GRBModel model = GRBModel(*env); model.set(GRB_StringAttr_ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. This is no longer a pure assignment model, so we must // use binary variables. x = new GRBVar*[nWorkers]; for (int w = 0; w < nWorkers; ++w) { x[w] = model.addVars(nShifts); xCt++; model.update(); for (int s = 0; s < nShifts; ++s) { ostringstream vname; vname << Workers[w] << "." << Shifts[s]; x[w][s].set(GRB_DoubleAttr_UB, availability[w][s]); x[w][s].set(GRB_CharAttr_VType, GRB_BINARY); x[w][s].set(GRB_StringAttr_VarName, vname.str()); } } // Slack variables for each shift constraint so that the shifts can // be satisfied slacks = model.addVars(nShifts); model.update(); for (int s = 0; s < nShifts; ++s) { ostringstream vname; vname << Shifts[s] << "Slack"; slacks[s].set(GRB_StringAttr_VarName, vname.str()); } // Variable to represent the total slack GRBVar totSlack = model.addVar(0, GRB_INFINITY, 0, GRB_CONTINUOUS, "totSlack"); // Variables to count the total shifts worked by each worker totShifts = model.addVars(nWorkers); model.update(); for (int w = 0; w < nWorkers; ++w) { ostringstream vname; vname << Workers[w] << "TotShifts"; totShifts[w].set(GRB_StringAttr_VarName, vname.str()); } // Update model to integrate new variables model.update(); GRBLinExpr lhs; // Constraint: assign exactly shiftRequirements[s] workers // to each shift s for (int s = 0; s < nShifts; ++s) { lhs = 0; lhs += slacks[s]; for (int w = 0; w < nWorkers; ++w) { lhs += x[w][s]; } model.addConstr(lhs == shiftRequirements[s], Shifts[s]); } // Constraint: set totSlack equal to the total slack lhs = 0; for (int s = 0; s < nShifts; ++s) { lhs += slacks[s]; } model.addConstr(lhs == totSlack, "totSlack"); // Constraint: compute the total number of shifts for each worker for (int w = 0; w < nWorkers; ++w) { lhs = 0; for (int s = 0; s < nShifts; ++s) { lhs += x[w][s]; } ostringstream vname; vname << "totShifts" << Workers[w]; model.addConstr(lhs == totShifts[w], vname.str()); } // Objective: minimize the total slack GRBLinExpr obj = 0; obj += totSlack; model.setObjective(obj); // Optimize int status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts); if (status != GRB_OPTIMAL) { return 1; } // Constrain the slack by setting its upper and lower bounds totSlack.set(GRB_DoubleAttr_UB, totSlack.get(GRB_DoubleAttr_X)); totSlack.set(GRB_DoubleAttr_LB, totSlack.get(GRB_DoubleAttr_X)); // Variable to count the average number of shifts worked GRBVar avgShifts = model.addVar(0, GRB_INFINITY, 0, GRB_CONTINUOUS, "avgShifts"); // Variables to count the difference from average for each worker; // note that these variables can take negative values. diffShifts = model.addVars(nWorkers); model.update(); for (int w = 0; w < nWorkers; ++w) { ostringstream vname; vname << Workers[w] << "Diff"; diffShifts[w].set(GRB_StringAttr_VarName, vname.str()); diffShifts[w].set(GRB_DoubleAttr_LB, -GRB_INFINITY); } // Update model to integrate new variables model.update(); // Constraint: compute the average number of shifts worked lhs = 0; for (int w = 0; w < nWorkers; ++w) { lhs += totShifts[w]; } model.addConstr(lhs == nWorkers * avgShifts, "avgShifts"); // Constraint: compute the difference from the average number of shifts for (int w = 0; w < nWorkers; ++w) { lhs = 0; lhs += totShifts[w]; lhs -= avgShifts; ostringstream vname; vname << Workers[w] << "Diff"; model.addConstr(lhs == diffShifts[w], vname.str()); } // Objective: minimize the sum of the square of the difference from the // average number of shifts worked GRBQuadExpr qobj; for (int w = 0; w < nWorkers; ++w) { qobj += diffShifts[w] * diffShifts[w]; } model.setObjective(qobj); // Optimize status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts); if (status != GRB_OPTIMAL) { return 1; } } catch (GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Exception during optimization" << endl; } delete[] c; delete[] v; for (int i = 0; i < xCt; ++i) { delete[] x[i]; } delete[] x; delete[] slacks; delete[] totShifts; delete[] diffShifts; delete env; return 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(); 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; }
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; }
int main(int argc, char *argv[]) { Digraph g; // graph declaration string digraph_matching_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 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_matching_filename>"<<endl<<endl; cout << "Example: " << argv[0] << " digr_bipartite_100_10" << endl << endl; exit(0);} digraph_matching_filename = argv[1]; ReadListDigraph(digraph_matching_filename,g,vname,weight,px,py,0); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); model.set(GRB_IntAttr_ModelSense, GRB_MAXIMIZE); // is a maximization problem /* LPI variables */ Digraph::ArcMap<GRBVar> x(g); // variable for connections, 1=connected, 0=not connected GRBLinExpr expressao; for (Digraph::ArcIt e(g); e != INVALID; ++e) { x[e] = model.addVar(0.0, 1.0, weight[e], GRB_CONTINUOUS); // Exercise: Using bipartite graphs, explain why we can use continuous // variables and still obtain integer solutions } model.update(); for (Digraph::NodeIt v(g); v!=INVALID; ++v) { GRBLinExpr exprin, exprout; int n_arcs_in=0,n_arcs_out=0; // for each node, the number of arcs leaving is at most 1 // remember: the graph is bipartite, with arcs going from one part to the other for (Digraph::InArcIt e(g,v); e != INVALID; ++e) {exprin += x[e]; n_arcs_in++;} if (n_arcs_in > 0) {model.addConstr(exprin <= 1 ); vcolor[v] = BLUE;} // for each node, the number of arcs entering is at most 1 for (Digraph::OutArcIt e(g,v); e != INVALID; ++e) {exprout += x[e]; n_arcs_out++;} if (n_arcs_out > 0) {model.addConstr(exprout <= 1 ); vcolor[v] = RED;} } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% try { model.optimize(); double soma=0.0; int cor=0; 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] = (cor % 8) + 2; cor++; } else ecolor[e] = NOCOLOR; } cout << "Maximum Bipartite Matching = " << soma << endl; // Esta rotina precisa do programa neato/dot do Graphviz ViewListDigraph(g,vname,px,py,vcolor,ecolor, "maximum weighted matching in graph with "+IntToString(countNodes(g))+ " nodes:"+DoubleToString(soma)); } catch(GRBException e) { cerr << "Nao foi possivel resolver o PLI." << endl; cerr << "Codigo de erro = " << e.getErrorCode() << endl; cerr << e.getMessage(); } 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[]) { 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; } } }