void printSolution(GRBModel& model, int nCategories, int nFoods, GRBVar* buy, GRBVar* nutrition) throw(GRBException) { if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL) { cout << "\nCost: " << model.get(GRB_DoubleAttr_ObjVal) << endl; cout << "\nBuy:" << endl; for (int j = 0; j < nFoods; ++j) { if (buy[j].get(GRB_DoubleAttr_X) > 0.0001) { cout << buy[j].get(GRB_StringAttr_VarName) << " " << buy[j].get(GRB_DoubleAttr_X) << endl; } } cout << "\nNutrition:" << endl; for (int i = 0; i < nCategories; ++i) { cout << nutrition[i].get(GRB_StringAttr_VarName) << " " << nutrition[i].get(GRB_DoubleAttr_X) << endl; } } else { cout << "No solution" << endl; } }
int solveAndPrint(GRBModel& model, GRBVar& totSlack, int nWorkers, string* Workers, GRBVar* totShifts) throw(GRBException) { model.optimize(); int status = model.get(GRB_IntAttr_Status); if ((status == GRB_INF_OR_UNBD) || (status == GRB_INFEASIBLE) || (status == GRB_UNBOUNDED)) { cout << "The model cannot be solved " << "because it is infeasible or unbounded" << endl; return status; } if (status != GRB_OPTIMAL) { cout << "Optimization was stopped with status " << status << endl; return status; } // Print total slack and the number of shifts worked for each worker cout << endl << "Total slack required: " << totSlack.get(GRB_DoubleAttr_X) << endl; for (int w = 0; w < nWorkers; ++w) { cout << Workers[w] << " worked " << totShifts[w].get(GRB_DoubleAttr_X) << " shifts" << endl; } cout << endl; return status; }
int main(int argc, char *argv[]) { try { GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); // Create variables GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "x"); GRBVar y = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "y"); GRBVar z = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "z"); // Integrate new variables model.update(); // Set objective: maximize x + y + 2 z model.setObjective(x + y + 2 * z, GRB_MAXIMIZE); // Add constraint: x + 2 y + 3 z <= 4 model.addConstr(x + 2 * y + 3 * z <= 4, "c0"); // Add constraint: x + y >= 1 model.addConstr(x + y >= 1, "c1"); // Optimize model model.optimize(); cout << x.get(GRB_StringAttr_VarName) << " " << x.get(GRB_DoubleAttr_X) << endl; cout << y.get(GRB_StringAttr_VarName) << " " << y.get(GRB_DoubleAttr_X) << endl; cout << z.get(GRB_StringAttr_VarName) << " " << z.get(GRB_DoubleAttr_X) << endl; cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl; } catch(GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch(...) { cout << "Exception during optimization" << endl; } return 0; }
void seleciona_propagandas(int n, double C, double V[N], double P[N], double w[N][N], int S[N], double *UpperBound, long maxtime) { GRBVar y[N][N]; GRBVar x[N]; int seed=0; GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); model.getEnv().set(GRB_IntParam_Seed, seed); model.set(GRB_StringAttr_ModelName, "Alocacao Propaganda"); // prob. name model.set(GRB_IntAttr_ModelSense, GRB_MAXIMIZE); // is a minimization problem for(int i = 0; i < n; i++) { char name[100]; sprintf(name,"x_%d",i); x[i] = model.addVar(0.0, 1.0, V[i],GRB_BINARY, name); } for( int i = 0; i < n; i++) { for(int j = i+1; j < n; j++) { char name[100]; sprintf(name,"y_%d_%d",i, j); y[i][j] = model.addVar(0.0, 1.0, w[i][j], GRB_BINARY, name); } } model.update(); GRBLinExpr expr; for(int i = 0; i < n; i++) { expr += (x[i] * P[i]); } model.addConstr(expr <= C); model.update(); for(int i = 0; i < n; i++) { for(int j =i+1; j < n; j++) { model.addConstr(y[i][j] <= x[i]); model.addConstr(y[i][j] <= x[j]); model.addConstr(x[i] + x[j] <= (y[i][j] + 1)); } } model.update(); model.write("model.lp"); model.optimize(); *UpperBound = model.get(GRB_DoubleAttr_ObjVal); }
int main(int argc, char *argv[]) { try { GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); // Create variables GRBVar x1 = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_INTEGER, "x1"); GRBVar x2 = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_INTEGER, "x2"); // Integrate new variables model.update(); // Set objective: maximize 2 x1 + x2 model.setObjective(2 * x1 + x2, GRB_MAXIMIZE); // Add constraint: x2 + 0.1 x1 <= 8 model.addConstr(x2 + 0.1 * x1 <= 8, "c0"); // Add constraint: x2 + 5 x1 <= 70 model.addConstr(x2 + 5 * x1 <= 70, "c1"); // Optimize model model.optimize(); cout << x1.get(GRB_StringAttr_VarName) << " " << x1.get(GRB_DoubleAttr_X) << endl; cout << x2.get(GRB_StringAttr_VarName) << " " << x2.get(GRB_DoubleAttr_X) << endl; cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl; } 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[]) { if (argc < 2) { cout << "Usage: lpmod_c++ filename" << endl; return 1; } GRBEnv* env = 0; GRBVar* v = 0; try { // Read model and determine whether it is an LP env = new GRBEnv(); GRBModel model = GRBModel(*env, argv[1]); if (model.get(GRB_IntAttr_IsMIP) != 0) { cout << "The model is not a linear program" << endl; return 1; } model.optimize(); int status = model.get(GRB_IntAttr_Status); if ((status == GRB_INF_OR_UNBD) || (status == GRB_INFEASIBLE) || (status == GRB_UNBOUNDED)) { cout << "The model cannot be solved because it is " << "infeasible or unbounded" << endl; return 1; } if (status != GRB_OPTIMAL) { cout << "Optimization was stopped with status " << status << endl; return 0; } // Find the smallest variable value double minVal = GRB_INFINITY; int minVar = 0; v = model.getVars(); for (int j = 0; j < model.get(GRB_IntAttr_NumVars); ++j) { double sol = v[j].get(GRB_DoubleAttr_X); if ((sol > 0.0001) && (sol < minVal) && (v[j].get(GRB_DoubleAttr_LB) == 0.0)) { minVal = sol; minVar = j; } } cout << "\n*** Setting " << v[minVar].get(GRB_StringAttr_VarName) << " from " << minVal << " to zero ***" << endl << endl; v[minVar].set(GRB_DoubleAttr_UB, 0.0); // Solve from this starting point model.optimize(); // Save iteration & time info double warmCount = model.get(GRB_DoubleAttr_IterCount); double warmTime = model.get(GRB_DoubleAttr_Runtime); // Reset the model and resolve cout << "\n*** Resetting and solving " << "without an advanced start ***\n" << endl; model.reset(); model.optimize(); // Save iteration & time info double coldCount = model.get(GRB_DoubleAttr_IterCount); double coldTime = model.get(GRB_DoubleAttr_Runtime); cout << "\n*** Warm start: " << warmCount << " iterations, " << warmTime << " seconds" << endl; cout << "*** Cold start: " << coldCount << " iterations, " << coldTime << " seconds" << endl; } catch (GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Error during optimization" << endl; } delete[] v; delete env; 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; }
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); }
void BVH_balancing::Solve( const std::map<int, std::set<int> > &compatibility, size_t no_bones, std::map<int, int>& assignments ){ std::map<int, int> Bn_to_index, index_to_Bn; size_t index = 0; size_t no_branchings = compatibility.size(); assert( no_bones > 0 ); assert( no_branchings > 0 ); for( const auto& item : compatibility ){ if( Bn_to_index.count(item.first) > 0 ) { continue; } // skip if alredy mapped Bn_to_index[item.first] = index; index_to_Bn[index] = item.first; ++index; } // entire optimization goes inside a try catch statement. // in case of errors, I want it to crash! try{ GRBEnv env; GRBModel model = GRBModel( env ); /* CREATE VARIABLES */ std::vector<GRBVar> vars( no_bones * no_branchings ); for( size_t r = 0; r < no_bones; ++r ){ for( size_t c = 0; c < no_branchings; ++c ){ size_t idx = matIndex( r, c, no_branchings ); std::stringstream var_name; var_name << "A( " << r << ", " << c << " )"; assert( compatibility.count( index_to_Bn[c] ) > 0 ); bool is_connected = compatibility.at( index_to_Bn[c] ).count( r ); vars[idx] = model.addVar( 0.0, ( is_connected > 0 ? 1.0 : 0.0 ), 1.0, GRB_BINARY, var_name.str()); } } model.update(); // Create Objective Function. // for each branching node i : #bones( Bn_i )^2 // hence I need to sum the number of bones assigned to each branching node GRBQuadExpr obj; std::vector<GRBLinExpr> cols( no_branchings ); for( size_t c = 0; c < no_branchings; ++c ){ for( size_t r = 0; r < no_bones; ++r ){ size_t idx = matIndex( r, c, no_branchings ); cols[c] += vars[idx]; } } for( size_t c = 0; c < no_branchings; ++c ){ obj += cols[c] * cols[c]; } model.setObjective( obj ); model.update(); // create constraint : each bone can be assigned to only one branching node. // this means that the summation of each row's values must be equal to 1.0 for( size_t r = 0; r < no_bones; ++r ){ GRBLinExpr row_sum; for( size_t c = 0; c < no_branchings; ++c ){ size_t idx = matIndex( r, c, no_branchings ); row_sum += vars[idx]; } model.addConstr( row_sum == 1.0 ); } model.update(); // Optimize model.optimize(); int status = model.get(GRB_IntAttr_Status); if (status == GRB_OPTIMAL) { std::cout << "The optimal objective is " << model.get(GRB_DoubleAttr_ObjVal) << std::endl; // return results! // printResults(vars, no_bones, no_branchings ); getResults( index_to_Bn, vars, assignments, no_bones, no_branchings ); return; } /************************************/ /* ERROR HANDLING */ /************************************/ if (status == GRB_UNBOUNDED){ std::cout << "The model cannot be solved because it is unbounded" << std::endl; assert(false); } if ((status != GRB_INF_OR_UNBD) && (status != GRB_INFEASIBLE)) { std::cout << "Optimization was stopped with status " << status << std::endl; assert( false ); } GRBConstr* c = 0; // do IIS std::cout << "The model is infeasible; computing IIS" << std::endl; model.computeIIS(); std::cout << "\nThe following constraint(s) cannot be satisfied:" << std::endl; c = model.getConstrs(); for (int i = 0; i < model.get(GRB_IntAttr_NumConstrs); ++i){ if (c[i].get(GRB_IntAttr_IISConstr) == 1) { std::cout << c[i].get(GRB_StringAttr_ConstrName) << std::endl; } } } /* EXCEPTION HANDLING */ catch (GRBException e) { std::cout << "Error code = " << e.getErrorCode() << std::endl; std::cout << e.getMessage() << std::endl; assert( false ); } catch (...){ std::cout << "Exception during optimization" << std::endl; assert( false ); } }
ChannelsFitness ILPChannelingGurobi(DataStructure *dataStructure, double const alpha) { try { unsigned int messageCount; double alphaCoef = alpha; GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); //model.getEnv().set(GRB_DoubleParam_TimeLimit, 3600); ChannelsFitness cfResult; CAMessage *messages; messageCount = static_cast<unsigned int>(AggregateMessages(dataStructure, messages)); vector<int> w(messageCount); transform(messages, messages + messageCount, w.begin(), [](CAMessage &message) { return message.payload; }); int sumW = 0; for (int i = 0; i < messageCount; i++) { for (int j = 0; j < static_cast<int>(messages[i].nodes.size()); j++) { if (dataStructure->nodesOnBothChannels[messages[i].nodes[j]] != 1) { sumW += messages[i].payload; break; } } } if (alphaCoef < 0) alphaCoef = 1.0 / sumW; GRBVar z = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "z"); GRBVar Pa = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "Pa"); GRBVar Pb = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "Pb"); GRBVar Pg = model.addVar(0.0, GRB_INFINITY, 0.0, GRB_CONTINUOUS, "Pg"); vector<GRBVar> Uea(messageCount); vector<GRBVar> Ueb(messageCount); vector<GRBVar> xi(static_cast<unsigned int>(dataStructure->nodeCount)); generate_n(Uea.begin(), messageCount, [&model]() { return model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "Uea"); }); generate_n(Ueb.begin(), messageCount, [&model]() { return model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "Ueb"); }); generate_n(xi.begin(), dataStructure->nodeCount, [&model]() { return model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "xi"); }); model.update(); model.setObjective(z + alphaCoef * Pg, GRB_MINIMIZE); model.addConstr(Pa <= z); model.addConstr(Pb <= z); model.addConstr(Pa + Pb - sumW == Pg); model.addConstr(expSum(Uea, w) == Pa); model.addConstr(expSum(Ueb, w) == Pb); for (int e = 0; e < messageCount; e++) { for (int i = 0; i < static_cast<int>(messages[e].nodes.size()); i++) // Problem!!! { if (dataStructure->nodesOnBothChannels[messages[e].nodes[i]] != 1) { model.addConstr(xi[messages[e].nodes[i]] - Uea[e] <= 0); model.addConstr(xi[messages[e].nodes[i]] + Ueb[e] >= 1); } } } model.addConstr(xi[0] == 1); model.optimize(); switch (model.get(GRB_IntAttr_Status)) { case GRB_INFEASIBLE: case GRB_UNBOUNDED: cfResult.channelA = cfResult.channelB = cfResult.gateway = -1; return cfResult; case GRB_TIME_LIMIT: if (model.get(GRB_IntAttr_SolCount) <= 0) { cfResult.channelA = cfResult.channelB = cfResult.gateway = -1; return cfResult; } default: break; } for (int i = 0; i < dataStructure->nodeCount; i++) dataStructure->nodesChannel[i] = static_cast<char>(xi[i].get(GRB_DoubleAttr_X)); /*for(i = 0; i < number_variables; i++) { printf("%d ", static_cast<int>(glp_mip_col_val(mip,i+1))); }*/ cfResult.channelA = static_cast<int>(floor(Pa.get(GRB_DoubleAttr_X) + 0.5)); cfResult.channelB = static_cast<int>(floor(Pb.get(GRB_DoubleAttr_X) + 0.5)); cfResult.gateway = static_cast<int>(floor(Pg.get(GRB_DoubleAttr_X) + 0.5)); for (int i = 0; i < dataStructure->nodeCount; i++) { printf("%d ", static_cast<int>(xi[i].get(GRB_DoubleAttr_X))); } printf("\n"); printf("/ %d, %d, %d\n", cfResult.channelA, cfResult.channelB, cfResult.gateway); delete[] messages; return cfResult; } catch (GRBException e) { cout << e.getMessage() << "\n"; } }
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; }
// 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(){ float peso1, peso2, peso3,peso4; int origem, destino; // vértices para cada aresta; int id = 0; // id das arestas que leremos do arquivo para criar o grafo cin>>n; // quantidade de vértices do grafo; arestas = new short*[n]; coeficienteObjetv = new double*[n]; matrix_peso1 = new double*[n]; matrix_peso2 = new double*[n]; matrix_peso3 = new double*[n]; matrix_peso4 = new double*[n]; for (int i=0; i<n; i++){ arestas[i] = new short[n]; coeficienteObjetv[i] = new double[n]; matrix_peso1[i] = new double[n]; matrix_peso2[i] = new double[n]; matrix_peso3[i] = new double[n]; matrix_peso4[i] = new double[n]; } GRBEnv env = GRBEnv();; env.set("OutputFlag","0"); GRBModel model = GRBModel(env);; GRBVar **y, **x; float epslon = 0.0001; //cin>>epslon; y = new GRBVar*[n]; x = new GRBVar*[n]; for (int i=0; i<n;i++){ y[i] = new GRBVar[n]; x[i] = new GRBVar[n]; } int constrCont=0; // Create variables for (int i=0; i<n; i++){ for (int j=0; j<n; j++){ arestas[i][j] = 0; } } while (cin>>origem){ cin>>destino; cin>>peso1; cin>>peso2; cin>>peso3; cin>>peso4; coeficienteObjetv[origem][destino] = (peso1*epslon + peso2*epslon + peso3*epslon + peso4)*(-1); // o problema é de maximizacao x[origem][destino] = model.addVar(0.0, 100000, 0.0, GRB_CONTINUOUS, "x"+to_string(origem)+to_string(destino)); x[destino][origem] = model.addVar(0.0, 100000, 0.0, GRB_CONTINUOUS, "x"+to_string(destino)+to_string(origem)); y[origem][destino] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "y"+to_string(origem)+to_string(destino)); arestas[origem][destino] = 1; arestas[destino][origem] = 1; matrix_peso1[origem][destino] = peso1*(-1); matrix_peso2[origem][destino] = peso2*(-1); matrix_peso3[origem][destino] = peso3*(-1); matrix_peso4[origem][destino] = peso4*(-1); id++; } int nA = id; // quantidade de arestas do grafo int m = 1;// por default, o m falado por Lokman and Koksalan sera igual a 1 model.update(); // Set objective: GRBLinExpr exprObjet; for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ if (arestas[i][j] == 1) exprObjet.addTerms(&coeficienteObjetv[i][j], &y[i][j],1); } } model.setObjective(exprObjet,GRB_MAXIMIZE); // constraint 3.9 (FERNANDES, 2016) GRBLinExpr constr5 ; double coefff = 1; for (int j=0+1; j<n; j++){ if (arestas[0][j] == 1) constr5.addTerms(&coefff,&x[0][j],1); } model.addConstr(constr5, GRB_EQUAL, n-1,to_string(constrCont++)); // // Add constraint 3.10 (FERNANDES, 2016) double com = -1; for (int j=1; j<n; j++){ GRBLinExpr constr2 = 0; for (int i=0; i<n; i++){ if (arestas[i][j] == 1){ constr2.addTerms(&coefff,&x[i][j],1); constr2.addTerms(&com,&x[j][i],1); } } model.addConstr(constr2, GRB_EQUAL, 1,to_string(constrCont++)); } double coef = (double) n - 1; for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ if (arestas[i][j] == 1){ GRBLinExpr constr8; GRBLinExpr constr9; constr8.addTerms(&coef,&y[i][j],1); constr9.addTerms(&coefff ,&x[i][j],1); constr9.addTerms(&coefff ,&x[j][i],1); model.addConstr(constr8, GRB_GREATER_EQUAL, constr9,to_string(constrCont++)); } } } //cout<<"Modelo carregado"<<endl; for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ if (arestas[i][j] == 1){ GRBLinExpr constr22; GRBLinExpr constr33; constr22.addTerms(&coefff ,&y[i][j],1); constr33.addTerms(&coefff ,&x[i][j],1); constr33.addTerms(&coefff ,&x[j][i],1); // cout<<constr22<<GRB_LESS_EQUAL<<constr33<<endl; model.addConstr(constr22, GRB_LESS_EQUAL, constr33,to_string(constrCont++)); } } } int nn = 0; // o 'n' do algoritmo de Lokman and Koksalan //int kk_estrela = 0; // o 'k*' do algoritmo 2 de Lokman and Koksalan int MM = 100000000; // o 'M' do algoritmo 2 de Lokman and Koksalan int z4_k_estrela; // pra guardar o Z_p^(P^(b^(k*,n))) do algoritmo 2 de Lokman and Koksalan /* * Algoritmo 2 de Lokman and Koksalan */ try { times(&tempsInit); // para medir o tempo em caso limite pthread_t thread_time; pthread_attr_t attr; int nnnnnnnn=0; if(pthread_create(&thread_time, NULL, &tempo, (void*)nnnnnnnn)){ // on criee efectivement la thread de rechaufage cout<<"Error to create the thread"<<endl; exit(EXIT_FAILURE); } // bool auxbol = false; // vira true (e o será pra sempre) quando resolvemos um modelo diferente do SIMPLES int optimstatus; short **result = new short*[n]; for (int ii=0; ii<n; ii++){ result[ii] = new short[n]; } model.optimize(); // P0,4 --> n=0 (modelo SIMPLES) optimstatus = model.get(GRB_IntAttr_Status); int z1=0,z2=0,z3=0,z4=0; if (optimstatus != GRB_INFEASIBLE){ for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ if (arestas[i][j] == 1){ result[i][j] = y[i][j].get(GRB_DoubleAttr_X); // GUARDA O RESULTADO z1+=result[i][j]*matrix_peso1[i][j]; // calcula os pesos z2+=result[i][j]*matrix_peso2[i][j]; z3+=result[i][j]*matrix_peso3[i][j]; z4+=result[i][j]*matrix_peso4[i][j]; } } } S.push_back(result); Pesos ppp = (Pesos){z1,z2,z3,z4}; Z.push_back(ppp); nn++; } do{ // esse loop para quando z4_k_estrela==-MM z4_k_estrela =(-1)*MM; // guarda o maximo short **z_n_plus_1 = new short*[n]; for (int ii=0; ii<n; ii++){ z_n_plus_1[ii] = new short[n]; } int z1_estrela, z2_estrela, z3_estrela; for (int ki=-1; ki<nn; ki++){ // no algoritmo original, ki deve variar de 0 à n (existindo solucoes de 1 à n). //aqui, portanto, fazemos k de -1 à n-1, porque as solucoes vao de 0 à n-1 for (int kj=-1; kj<nn; kj++){ // como i de ver menor que j, a unica possibilidade é i=1 e j=2, pois p-2=2 //cout<<ki<<" "<<kj<<endl; //cout<< Z[ki].peso1<<" "<< Z[kj].peso2<<endl; //if (kj!=-1 && ki!=-1 && (Z[ki].peso1 + 1 <= Z[kj].peso1)){ //Primeiramente, prepara o b1 e b2 e b3 int b1,b2,b3; //b1 if (ki==-1) b1=(-1)*MM; // -M else { b1 = Z[ki].peso1 + 1; } //b2 if (kj==-1) b2=(-1)*MM; // -M else { if (Z[kj].peso1 >= b1){ b2 = Z[kj].peso2 + 1; } else b2=(-1)*MM; // -M } //b3 b3 = (-1)*MM; // Snk = vazio for (int ii=0; ii<S.size(); ii++){ if (Z[ii].peso1>=b1 && Z[ii].peso2>=b2) { if (Z[ii].peso3 > b3){ b3 = Z[ii].peso3; } } } if (b3!=(-1)*MM) b3=b3+1; // max + 1 //cout <<"b1= "<<b1<<" b2= "<<" "<<b2<<" b3= "<<b3<<endl; if (auxbol == true){ // remove as restricoes de z2>b2 e adiciona novas GRBConstr cb1 = model.getConstrByName("cb1"); GRBConstr cb2 = model.getConstrByName("cb2"); GRBConstr cb3 = model.getConstrByName("cb3"); model.remove(cb1); model.remove(cb2); model.remove(cb3); } GRBLinExpr cb1; GRBLinExpr cb2; GRBLinExpr cb3; for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ if (arestas[i][j] == 1){ cb1.addTerms(&matrix_peso1[i][j], &y[i][j],1); cb2.addTerms(&matrix_peso2[i][j], &y[i][j],1); cb3.addTerms(&matrix_peso3[i][j], &y[i][j],1); } } } model.addConstr(cb1, GRB_GREATER_EQUAL, b1,"cb1"); model.addConstr(cb2, GRB_GREATER_EQUAL, b2,"cb2"); model.addConstr(cb3, GRB_GREATER_EQUAL, b3,"cb3"); // AGORA RESOLVE-SE O MODELO auxbol=true; model.optimize(); optimstatus = model.get(GRB_IntAttr_Status); if (optimstatus != GRB_INFEASIBLE){ short **result = new short*[n]; for (int ii=0; ii<n; ii++){ result[ii] = new short[n]; } z1=0,z2=0,z3=0,z4=0; for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ if (arestas[i][j] == 1){ result[i][j] = y[i][j].get(GRB_DoubleAttr_X); // GUARDA O RESULTADO z1+=result[i][j]*matrix_peso1[i][j]; // calcula os pesos z2+=result[i][j]*matrix_peso2[i][j]; z3+=result[i][j]*matrix_peso3[i][j]; z4+=result[i][j]*matrix_peso4[i][j]; } } } if (z4>z4_k_estrela){ z1_estrela = z1; z2_estrela = z2; z3_estrela = z3; z4_k_estrela = z4; for (int i=0; i<n; i++){ for (int j=i+1; j<n; j++){ z_n_plus_1[i][j] = result[i][j]; } } } } //} } } if (z4_k_estrela!=(-1)*MM){ S.push_back(z_n_plus_1); Pesos pppp = (Pesos){z1_estrela,z2_estrela,z3_estrela,z4_k_estrela}; Z.push_back(pppp); nn++; //cout<<"nn = "<<nn<<endl; } } while (z4_k_estrela!=(-1)*MM); times(&tempsFinal1); /* current time */ // clock final clock_t user_time1 = (tempsFinal1.tms_utime - tempsInit.tms_utime); cout<<user_time1<<endl; cout<<(float) user_time1 / (float) sysconf(_SC_CLK_TCK)<<endl;//"Tempo do usuario por segundo : " cout<<"RESULTADO FINAL..."<<endl; printResultado(); } 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[]) { 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[]) { 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; }
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; }
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[]) { chrono :: steady_clock :: time_point tBegin = chrono :: steady_clock :: now(); string I ("0"); ulint timeLimit = 10; if (argc >= 2) { I = string (argv[1]); } if (argc >= 3) { timeLimit = atoi(argv[2]); } ulint nComplete, k, t, n, m, root; double d; cin >> nComplete >> d >> k >> t >> n >> m >> root; vector <ulint> penalty (nComplete); // vector with de penalties of each vectex vector < list < pair <ulint, ulint> > > adj (nComplete); // adjacency lists for the graph for (ulint v = 0; v < nComplete; v++) { cin >> penalty[v]; } vector <ulint> solutionV (nComplete, 0); // reading solution vertices for (ulint i = 0; i < n; i++) { ulint v; cin >> v; solutionV[v] = 1; } vector < pair < pair <ulint, ulint> , ulint> > E (m); // vector of edges with the format ((u, v), w) map < pair <ulint, ulint>, ulint> mE; // map an edge to its ID vector < vector <ulint> > paths (m); // reading graph for (ulint e = 0; e < m; e++) { ulint u, v, w, pathSize; cin >> u >> v >> w >> pathSize; adj[u].push_back(make_pair(v, w)); adj[v].push_back(make_pair(u, w)); E[e] = make_pair(make_pair(u, v), w); mE[make_pair(u, v)] = e; mE[make_pair(v, u)] = e; paths[e] = vector <ulint> (pathSize); for (ulint i = 0; i < pathSize; i++) { cin >> paths[e][i]; } } try { string N = itos(nComplete); stringstream ssD; ssD << fixed << setprecision(1) << d; string D = ssD.str(); D.erase(remove(D.begin(), D.end(), '.'), D.end()); string K = itos(k); string T = itos(t); ifstream remainingTimeFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/remainingTime.txt"); lint remainingTime = 0; if (remainingTimeFile.is_open()) { remainingTimeFile >> remainingTime; } if (remainingTime > 0) { timeLimit += remainingTime; } GRBEnv env = GRBEnv(); env.set(GRB_IntParam_LazyConstraints, 1); env.set(GRB_IntParam_LogToConsole, 0); env.set(GRB_StringParam_LogFile, "./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/log2.txt"); env.set(GRB_DoubleParam_TimeLimit, ((double) timeLimit)); GRBModel model = GRBModel(env); model.getEnv().set(GRB_IntParam_LazyConstraints, 1); model.getEnv().set(GRB_IntParam_LogToConsole, 0); model.getEnv().set(GRB_StringParam_LogFile, "./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/log2.txt"); model.getEnv().set(GRB_DoubleParam_TimeLimit, ((double) timeLimit)); vector <GRBVar> y (nComplete); // ∀ v ∈ V for (ulint v = 0; v < nComplete; v++) { // y_v ∈ {0.0, 1.0} y[v] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "y_" + itos(v)); } vector <GRBVar> x (m); // ∀ e ∈ E for (ulint e = 0; e < m; e++) { ulint u, v; u = E[e].first.first; v = E[e].first.second; // y_e ∈ {0.0, 1.0} x[e] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY, "x_" + itos(u) + "_" + itos(v)); } model.update(); GRBLinExpr obj = 0.0; // obj = ∑ ce * xe for (ulint e = 0; e < m; e++) { ulint w; w = E[e].second; obj += w * x[e]; } // obj += ∑ πv * (1 - yv) for (ulint v = 0; v < nComplete; v++) { obj += penalty[v] * (1.0 - y[v]); } model.setObjective(obj, GRB_MINIMIZE); // yu == 1 model.addConstr(y[root] == 1.0, "c_0"); // dominance // ∀ v ∈ V for (ulint v = 0; v < nComplete; v++) { if (solutionV[v] == 1) { GRBLinExpr constr = 0.0; constr += y[v]; model.addConstr(constr == 1, "c_1_" + itos(v)); } } // each vertex must have exactly two edges adjacent to itself // ∀ v ∈ V for (ulint v = 0; v < nComplete; v++) { // ∑ xe == 2 * yv , e ∈ δ({v}) GRBLinExpr constr = 0.0; for (list < pair <ulint, ulint> > :: iterator it = adj[v].begin(); it != adj[v].end(); it++) { ulint w = (*it).first; // destination ulint e = mE[make_pair(v, w)]; constr += x[e]; } model.addConstr(constr == 2.0 * y[v], "c_2_" + itos(v)); } subtourelim cb = subtourelim(y, x, nComplete, m, E, mE, root); model.setCallback(&cb); model.optimize(); if (model.get(GRB_IntAttr_SolCount) > 0) { ulint solutionCost = 0; set <ulint> solutionVectices; vector < pair <ulint, ulint> > solutionEdges; solutionCost = round(model.get(GRB_DoubleAttr_ObjVal)); for (ulint v = 0; v < nComplete; v++) { if (y[v].get(GRB_DoubleAttr_X) >= 0.5) { solutionVectices.insert(v); } } for (ulint e = 0; e < m; e++) { if (x[e].get(GRB_DoubleAttr_X) >= 0.5) { for (ulint i = 0; i < paths[e].size() - 1; i++) { pair <ulint, ulint> edge; if (paths[e][i] < paths[e][i + 1]) { edge.first = paths[e][i]; edge.second = paths[e][i + 1]; } else { edge.first = paths[e][i + 1]; edge.second = paths[e][i]; } solutionEdges.push_back(edge); } } } cout << solutionVectices.size() << ' ' << solutionEdges.size() << ' ' << solutionCost << endl; for (set <ulint> :: iterator it = solutionVectices.begin(); it != solutionVectices.end(); it++) { ulint v = *it; cout << v << endl; } for (vector < pair <ulint, ulint> > :: iterator it = solutionEdges.begin(); it != solutionEdges.end(); it++) { pair <ulint, ulint> e = *it; cout << e.first << " " << e.second << endl; } } else { cout << "0 0 0" << endl; } // exporting model model.write("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/model2.lp"); ofstream objValFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/objVal2.txt", ofstream :: out); objValFile << model.get(GRB_DoubleAttr_ObjVal); objValFile.close(); ofstream gapFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/gap2.txt", ofstream :: out); gapFile << model.get(GRB_DoubleAttr_MIPGap); gapFile.close(); chrono :: steady_clock :: time_point tEnd = chrono :: steady_clock :: now(); chrono :: nanoseconds elapsedTime = chrono :: duration_cast <chrono :: nanoseconds> (tEnd - tBegin); ofstream elapsedTimeFile ("./output/N" + N + "D" + D + "K" + K + "T" + T + "I" + I + "/elapsedTime2.txt", ofstream :: out); elapsedTimeFile << elapsedTime.count(); elapsedTimeFile.close(); } catch (GRBException e) {
int main(int argc, char *argv[]) { if (argc < 2) { cout << "Usage: feasopt_c++ filename" << endl; return 1; } GRBEnv* env = 0; GRBConstr* c = 0; try { env = new GRBEnv(); GRBModel feasmodel = GRBModel(*env, argv[1]); // Create a copy to use FeasRelax feature later */ GRBModel feasmodel1 = GRBModel(feasmodel); // clear objective feasmodel.setObjective(GRBLinExpr(0.0)); // add slack variables c = feasmodel.getConstrs(); for (int i = 0; i < feasmodel.get(GRB_IntAttr_NumConstrs); ++i) { char sense = c[i].get(GRB_CharAttr_Sense); if (sense != '>') { double coef = -1.0; feasmodel.addVar(0.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, 1, &c[i], &coef, "ArtN_" + c[i].get(GRB_StringAttr_ConstrName)); } if (sense != '<') { double coef = 1.0; feasmodel.addVar(0.0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, 1, &c[i], &coef, "ArtP_" + c[i].get(GRB_StringAttr_ConstrName)); } } feasmodel.update(); // optimize modified model feasmodel.write("feasopt.lp"); feasmodel.optimize(); // use FeasRelax feature */ feasmodel1.feasRelax(GRB_FEASRELAX_LINEAR, true, false, true); feasmodel1.write("feasopt1.lp"); feasmodel1.optimize(); } catch (GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Error during optimization" << endl; } delete[] c; delete env; return 0; }
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; } }
void AlignmentLP::ConstructLP(SpeechSolution *proposal) { try { GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); //model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // Create all the variables. s.resize(cs_.problems_size()); s2.resize(cs_.problems_size()); //position_var.resize(cs_.problems_size()); // Create the hmms. for (uint u = 0; u < s.size(); ++u) { const ClusterProblem &problem = cs_.problem(u); int M = problem.num_steps; s[u].resize(M); s2[u].resize(M); //position_var.resize(M); for (int m = 0; m < M; ++m) { s[u][m].resize(problem.num_states); s2[u][m].resize(problem.num_states); for (uint n = 0; n < s[u][m].size(); ++n) { s[u][m][n].resize(cs_.num_hidden(0)); { stringstream buf; buf << "s2_" << u << "_" << m << "_" << n; s2[u][m][n] = model.addVar(0.0, 1.0, 0.0, VAR_TYPE, buf.str()); } for (uint o = 0; o < s[u][m][n].size(); ++o) { s[u][m][n][o].resize(3); for (uint f = 0; f <= 2; ++f) { stringstream buf; buf << "s_" << u << "_" << m << "_" << n << "_" << o << "_" << f; double score = distances_[u]->get_distance(m, o); s[u][m][n][o][f] = model.addVar(0.0, 1.0, score, VAR_TYPE, buf.str()); } } } // position_var[u][m].resize(cs_.num_types()); // for (uint l = 0; l < position_var[u][m].size(); ++l) { // position_var[u][m][l].resize(cs_.num_hidden(0)); // for (uint o = 0; o < position_var[u][m][l].size(); ++o) { // stringstream buf; // buf << "position_" << u << "_" << m << "_" << l << "_" << o; // position_var[u][m][l][o] = // model.addVar(0.0, 1.0, 0.0, // VAR_TYPE, buf.str()); // } // } } } r.resize(cs_.num_types()); for (uint l = 0; l < r.size(); ++l) { r[l].resize(cs_.num_hidden(0)); for (uint o = 0; o < r[l].size(); ++o) { stringstream buf; buf << "r_" << l << "_" << o; r[l][o] = model.addVar(0.0, 1.0, 0.0, VAR_TYPE, buf.str()); } } t.resize(cs_.problems_size()); for (uint u = 0; u < t.size(); ++u) { const ClusterProblem &problem = cs_.problem(u); t[u].resize(problem.num_states); for (uint n = 0; n < t[u].size(); ++n) { t[u][n].resize(cs_.num_hidden(0)); for (uint o = 0; o < t[u][n].size(); ++o) { stringstream buf; buf << "t_" << u << "_" << n << "_" << o; t[u][n][o] = model.addVar(0.0, 1.0, 0.0, VAR_TYPE, buf.str()); } } } model.update(); // Make constraints. // Constraint for M // for all l, sum_q r(l,o) = 1 for (int l = 0; l < cs_.num_types(); ++l) { // Sum out o's. GRBLinExpr sum; for (int o = 0; o < cs_.num_hidden(0); ++o) { sum += r[l][o]; } // Equal to 1. model.addConstr(sum == 1); } cerr << "Done Constraint 1" << endl; // Constraint for N // for all m,n,o, i, s(u, m, n, o) = s(m-1, n, o, 0) + // s(m-1, n, o, 1) for (int u = 0; u < cs_.problems_size(); ++u) { const ClusterProblem &problem = cs_.problem(u); int M = problem.num_steps; int N = problem.num_states; for (int m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { for (int o = 0; o < cs_.num_hidden(0); ++o) { if (m != 0 && n != 0) { GRBLinExpr sum; model.addConstr(s[u][m][n][o][0] + s[u][m][n][o][2] == s[u][m - 1][n][o][0] + s[u][m - 1][n][o][1], "incoming"); } if (m != M - 1 && n != N - 1) { model.addConstr(s[u][m][n][o][0] + s[u][m][n][o][1] == s[u][m + 1][n][o][0] + s[u][m + 1][n][o][2], "Outgoing"); } GRBLinExpr sum, sum2; for (int o2 = 0; o2 < cs_.num_hidden(0); ++o2) { sum += s[u][m][n][o2][1]; sum2 += s[u][m][n][o2][2]; } model.addConstr(s2[u][m][n] == sum, "Outgoing"); if (m != M - 1 && n != N - 1) { model.addConstr(sum2 == s2[u][m + 1][n + 1], "Outgoing"); } } } } { GRBLinExpr sum; for (int o = 0; o < cs_.num_hidden(0); ++o) { sum += s[u][0][0][o][1]; } model.addConstr(sum == 1, "Starting"); } { GRBLinExpr sum; for (int o = 0; o < cs_.num_hidden(0); ++o) { sum += s[u][problem.num_steps - 1][problem.num_states - 1][o][0]; } model.addConstr(sum == 1); } } // Tying constraints 3. // forall n, o, r(y_n, o) = t(n,o) for (int u = 0; u < cs_.problems_size(); ++u) { const ClusterProblem &problem = cs_.problem(u); for (int n = 0; n < problem.num_states; ++n) { GRBLinExpr sum; for (int o = 0; o < cs_.num_hidden(0); ++o) { sum += t[u][n][o]; } model.addConstr(sum == 1); } for (int n = 0; n < problem.num_states; ++n) { int l = problem.MapState(n); for (int o = 0; o < cs_.num_hidden(0); ++o) { model.addConstr(r[l][o] == t[u][n][o]); GRBLinExpr sum; for (int m = 0; m < problem.num_steps; ++m) { sum += s[u][m][n][o][1]; } model.addConstr(sum == t[u][n][o]); } } } cerr << "Done Constraint 3" << endl; if (true) { for (int u = 0; u < cs_.problems_size(); ++u) { const ClusterProblem &problem = cs_.problem(u); int M = problem.num_steps; int N = problem.num_states; for (int m = 0; m < M; ++m) { for (uint l = 0; l < r.size(); ++l) { vector <int> locations; for (int n = 0; n < N; ++n) { if ((int)l == problem.MapState(n)) { locations.push_back(n); } } for (int o = 0; o < cs_.num_hidden(0); ++o) { GRBLinExpr sum; for (uint occ_index = 0; occ_index < locations.size(); ++occ_index) { int n = locations[occ_index]; sum += s[u][m][n][o][0] + s[u][m][n][o][1] + s[u][m][n][o][2]; } //model.addConstr(position_var[u][m][l][o] == sum); model.addConstr(sum <= r[l][o]); } } } } } // model.addConstr(r[7][2] == 0.5); // model.addConstr(r[7][3] == 0.5); // model.addConstr(r[0][1] == 0.5); // model.addConstr(r[0][6] == 0.5); // model.addConstr(r[13][4] == 0.5); // model.addConstr(r[13][9] == 0.5); model.update(); //model.write("temp.lp"); // // // Done! model.optimize(); if (model.get(GRB_IntAttr_Status) != GRB_OPTIMAL) { model.computeIIS(); model.write("temp.ilp"); } vector<double> costs; for (uint u = 0; u < s.size(); ++u) { SpeechAlignment *align = proposal->mutable_alignment(u); const ClusterProblem &problem = cs_.problem(u); vector<int> *state_hidden = align->mutable_hidden_alignment(); vector<int> *state_align = align->mutable_alignment(); state_hidden->resize(problem.num_steps); state_align->resize(problem.num_steps); int M = problem.num_steps; int N = 0; for (int m = 0; m < M; ++m) { N = s[u][m].size(); costs.resize(s[u][m].size()); for (uint n = 0; n < s[u][m].size(); ++n) { for (uint o = 0; o < s[u][m][n].size(); ++o) { for (uint f = 0; f <= 2; ++f) { if (s[u][m][n][o][f].get(GRB_DoubleAttr_X) != 0) { (*state_hidden)[m] = o; (*state_align)[m] = problem.MapState(n); string position; if (f == 0) { position = "I"; } else if (f == 1) { position = "B"; } else { position = "O"; } cerr << "s " << m << " " << n << " " << o << " " << position << " " << s[u][m][n][o][f].get(GRB_DoubleAttr_X) << " " << s[u][m][n][o][f].get(GRB_DoubleAttr_Obj) << " " << problem.MapState(n) << endl; costs[n] += s[u][m][n][o][f].get(GRB_DoubleAttr_X) * s[u][m][n][o][f].get(GRB_DoubleAttr_Obj); } } } } } for (int n = 0; n < N; ++n) { cerr << n << " " << costs[n] << endl; } } for (uint u = 0; u < t.size(); ++u) { for (uint n = 0; n < t[u].size(); ++n) { for (uint o = 0; o < t[u][n].size(); ++o) { if (t[u][n][o].get(GRB_DoubleAttr_X) != 0) { cerr << "t " << n << " " << o << " " << t[u][n][o].get(GRB_DoubleAttr_X) << endl; } } } } for (uint l = 0; l < r.size(); ++l) { for (uint o = 0; o < r[l].size(); ++o) { if (r[l][o].get(GRB_DoubleAttr_X) != 0) { cerr << "r " << l << " " << o << " " << r[l][o].get(GRB_DoubleAttr_X) << endl; } } } } catch(GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch(...) { cout << "Exception during optimization" << endl; } }
// 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)); } }