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; GRBConstr* c = 0; GRBVar* v = 0; GRBVar** x = 0; GRBVar* slacks = 0; GRBVar* totShifts = 0; GRBVar* diffShifts = 0; int xCt = 0; try { // Sample data const int nShifts = 14; const int nWorkers = 7; // Sets of days and workers string Shifts[] = { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string Workers[] = { "Amy", "Bob", "Cathy", "Dan", "Ed", "Fred", "Gu" }; // Number of workers required for each shift double shiftRequirements[] = { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Worker availability: 0 if the worker is unavailable for a shift double availability[][nShifts] = { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model env = new GRBEnv(); GRBModel model = GRBModel(*env); model.set(GRB_StringAttr_ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. This is no longer a pure assignment model, so we must // use binary variables. x = new GRBVar*[nWorkers]; for (int w = 0; w < nWorkers; ++w) { x[w] = model.addVars(nShifts); xCt++; model.update(); for (int s = 0; s < nShifts; ++s) { ostringstream vname; vname << Workers[w] << "." << Shifts[s]; x[w][s].set(GRB_DoubleAttr_UB, availability[w][s]); x[w][s].set(GRB_CharAttr_VType, GRB_BINARY); x[w][s].set(GRB_StringAttr_VarName, vname.str()); } } // Slack variables for each shift constraint so that the shifts can // be satisfied slacks = model.addVars(nShifts); model.update(); for (int s = 0; s < nShifts; ++s) { ostringstream vname; vname << Shifts[s] << "Slack"; slacks[s].set(GRB_StringAttr_VarName, vname.str()); } // Variable to represent the total slack GRBVar totSlack = model.addVar(0, GRB_INFINITY, 0, GRB_CONTINUOUS, "totSlack"); // Variables to count the total shifts worked by each worker totShifts = model.addVars(nWorkers); model.update(); for (int w = 0; w < nWorkers; ++w) { ostringstream vname; vname << Workers[w] << "TotShifts"; totShifts[w].set(GRB_StringAttr_VarName, vname.str()); } // Update model to integrate new variables model.update(); GRBLinExpr lhs; // Constraint: assign exactly shiftRequirements[s] workers // to each shift s for (int s = 0; s < nShifts; ++s) { lhs = 0; lhs += slacks[s]; for (int w = 0; w < nWorkers; ++w) { lhs += x[w][s]; } model.addConstr(lhs == shiftRequirements[s], Shifts[s]); } // Constraint: set totSlack equal to the total slack lhs = 0; for (int s = 0; s < nShifts; ++s) { lhs += slacks[s]; } model.addConstr(lhs == totSlack, "totSlack"); // Constraint: compute the total number of shifts for each worker for (int w = 0; w < nWorkers; ++w) { lhs = 0; for (int s = 0; s < nShifts; ++s) { lhs += x[w][s]; } ostringstream vname; vname << "totShifts" << Workers[w]; model.addConstr(lhs == totShifts[w], vname.str()); } // Objective: minimize the total slack GRBLinExpr obj = 0; obj += totSlack; model.setObjective(obj); // Optimize int status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts); if (status != GRB_OPTIMAL) { return 1; } // Constrain the slack by setting its upper and lower bounds totSlack.set(GRB_DoubleAttr_UB, totSlack.get(GRB_DoubleAttr_X)); totSlack.set(GRB_DoubleAttr_LB, totSlack.get(GRB_DoubleAttr_X)); // Variable to count the average number of shifts worked GRBVar avgShifts = model.addVar(0, GRB_INFINITY, 0, GRB_CONTINUOUS, "avgShifts"); // Variables to count the difference from average for each worker; // note that these variables can take negative values. diffShifts = model.addVars(nWorkers); model.update(); for (int w = 0; w < nWorkers; ++w) { ostringstream vname; vname << Workers[w] << "Diff"; diffShifts[w].set(GRB_StringAttr_VarName, vname.str()); diffShifts[w].set(GRB_DoubleAttr_LB, -GRB_INFINITY); } // Update model to integrate new variables model.update(); // Constraint: compute the average number of shifts worked lhs = 0; for (int w = 0; w < nWorkers; ++w) { lhs += totShifts[w]; } model.addConstr(lhs == nWorkers * avgShifts, "avgShifts"); // Constraint: compute the difference from the average number of shifts for (int w = 0; w < nWorkers; ++w) { lhs = 0; lhs += totShifts[w]; lhs -= avgShifts; ostringstream vname; vname << Workers[w] << "Diff"; model.addConstr(lhs == diffShifts[w], vname.str()); } // Objective: minimize the sum of the square of the difference from the // average number of shifts worked GRBQuadExpr qobj; for (int w = 0; w < nWorkers; ++w) { qobj += diffShifts[w] * diffShifts[w]; } model.setObjective(qobj); // Optimize status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts); if (status != GRB_OPTIMAL) { return 1; } } catch (GRBException e) { cout << "Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; } catch (...) { cout << "Exception during optimization" << endl; } delete[] c; delete[] v; for (int i = 0; i < xCt; ++i) { delete[] x[i]; } delete[] x; delete[] slacks; delete[] totShifts; delete[] diffShifts; delete env; return 0; }
int main (int argc, char * argv[]) { 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) {
// Start the optimization SolverResult SolverGurobi::runOptimizer() { if (!getInitialized()) initialize(); try { // Create Gurobi environment and set parameters GRBEnv env = GRBEnv(); env.set(GRB_IntParam_OutputFlag, 0); GRBModel model = GRBModel(env); // Get problem info int numVars = constraints->getNumVariables(); int numConstraints = constraints->getNumConstraints(); // Get variables auto variables = constraints->getVariables(); // Create array of model variables GRBVar vars[numVars]; for (int i = 0; i < numVars; i++) { //vars[i] = model.addVar(0.0, 1.0, 0.0, GRB_BINARY); // Set variable type char type = GRB_CONTINUOUS; if (variables.at(i)->getType() == VariableType::BINARY) { type = GRB_BINARY; } else if (variables.at(i)->getType() == VariableType::INTEGER) { type = GRB_INTEGER; } vars[i] = model.addVar(variables.at(i)->getLowerBound(), variables.at(i)->getUpperBound(), variables.at(i)->getCost(), type); } // Integrate variables into model model.update(); // Set starting points (does not help much...) for (int i = 0; i < numVars; i++) vars[i].set(GRB_DoubleAttr_Start, variables.at(i)->getValue()); /* * Add constraints Ax <= b (or Ax = b) * by evaluating gradient and build A matrix */ DenseVector x = DenseVector::Zero(numVars); DenseVector dx = constraints->evalJacobian(x); // Get constraint bounds std::vector<double> clb; std::vector<double> cub; constraints->getConstraintBounds(clb,cub); std::vector<int> rowGradient, colGradient; constraints->structureJacobian(rowGradient, colGradient); int nnzJacobian = constraints->getNumNonZerosJacobian(); // Add constraints one row at the time for (int row = 0; row < numConstraints; row++) { // Build constraint GRBLinExpr expr = 0; // Loop through all non-zeros (inefficient) for (int i = 0; i < nnzJacobian; i++) { if (rowGradient.at(i) == row) { int j = colGradient.at(i); expr += dx(i)*vars[j]; } } // Add constraint to model if (clb.at(row) == cub.at(row)) { model.addConstr(expr, GRB_EQUAL, cub.at(row)); } else { model.addConstr(expr, GRB_LESS_EQUAL, cub.at(row)); } } // More efficient method - avoids dense matrix // std::vector<int> rows = {1,1,1,2,2,3,4,4,4,4,4,5}; // std::vector<int>::iterator start,stop; // start = rows.begin(); // stop = start; // while (start != rows.end()) // { // while (stop != rows.end()) // { // if (*stop == *start) // ++stop; // else // break; // } // for (std::vector<int>::iterator it = start; it != stop; ++it) // cout << *it << endl; // start = stop; // } model.update(); assert(numVars == model.get(GRB_IntAttr_NumVars)); assert(numConstraints == model.get(GRB_IntAttr_NumConstrs)); // Optimize model model.optimize(); // Check status int optimstatus = model.get(GRB_IntAttr_Status); if (optimstatus == GRB_INF_OR_UNBD) { model.getEnv().set(GRB_IntParam_Presolve, 0); model.optimize(); optimstatus = model.get(GRB_IntAttr_Status); } // Create result object SolverResult result(SolverStatus::ERROR, INF, std::vector<double>(numVars,0)); // Check Gurobi status if (optimstatus == GRB_OPTIMAL) { result.status = SolverStatus::OPTIMAL; // Get solution info result.objectiveValue = model.get(GRB_DoubleAttr_ObjVal); std::vector<double> optimalSolution; for (int i = 0; i < numVars; i++) { optimalSolution.push_back(vars[i].get(GRB_DoubleAttr_X)); } result.primalVariables = optimalSolution; /* * Reduced costs and constraint duals are * only available for continuous models */ std::vector<double> reducedCosts; std::vector<double> constraintDuals; if (!model.get(GRB_IntAttr_IsMIP)) { for (int i = 0; i < numVars; i++) { // Get reduced costs (related to range constraint duals) reducedCosts.push_back(vars[i].get(GRB_DoubleAttr_RC)); } for (int i = 0; i < numConstraints; i++) { GRBConstr c = model.getConstr(i); double pi = c.get(GRB_DoubleAttr_Pi); constraintDuals.push_back(pi); } } result.lowerBoundDualVariables = reducedCosts; result.upperBoundDualVariables = reducedCosts; result.constraintDualVariables = constraintDuals; return result; } else if (optimstatus == GRB_INFEASIBLE) { result.status = SolverStatus::INFEASIBLE; result.objectiveValue = INF; // compute and write out IIS // model.computeIIS(); // model.write("problem.lp"); return result; } else if (optimstatus == GRB_UNBOUNDED) { result.status = SolverStatus::UNBOUNDED; result.objectiveValue = -INF; return result; } else { result.status = SolverStatus::ERROR; result.objectiveValue = INF; return result; } } catch(GRBException e) { cout << "SolverGurobi: Error code = " << e.getErrorCode() << endl; cout << e.getMessage() << endl; return SolverResult(SolverStatus::ERROR, INF, std::vector<double>(constraints->getNumVariables(),0)); } catch (...) { cout << "SolverGurobi: Error during optimization!" << endl; return SolverResult(SolverStatus::ERROR, INF, std::vector<double>(constraints->getNumVariables(),0)); } }
int main(int argc, char *argv[]) { int time_limit; char name[1000]; ListGraph g; EdgeWeight lpvar(g); EdgeWeight weight(g); NodeName vname(g); ListGraph::NodeMap<double> posx(g),posy(g); string filename; int seed=1; // uncomment one of these lines to change default pdf reader, or insert new one //set_pdfreader("open"); // pdf reader for Mac OS X //set_pdfreader("xpdf"); // pdf reader for Linux //set_pdfreader("evince"); // pdf reader for Linux srand48(seed); time_limit = 3600; // solution must be obtained within time_limit seconds if (argc!=2) {cout<< endl << "Usage: "<< argv[0]<<" <graph_filename>"<<endl << endl << "Example: " << argv[0] << " gr_berlin52" << endl << " " << argv[0] << " gr_att48" << endl << endl; exit(0);} else if (!FileExists(argv[1])) {cout<<"File "<<argv[1]<<" does not exist."<<endl; exit(0);} filename = argv[1]; // Read the graph if (!ReadListGraph(filename,g,vname,weight,posx,posy)) {cout<<"Error reading graph file "<<argv[1]<<"."<<endl;exit(0);} TSP_Data tsp(g,vname,posx,posy,weight); ListGraph::EdgeMap<GRBVar> x(g); GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); #if GUROBI_NEWVERSION model.getEnv().set(GRB_IntParam_LazyConstraints, 1); model.getEnv().set(GRB_IntParam_Seed, seed); #else model.getEnv().set(GRB_IntParam_DualReductions, 0); // Dual reductions must be disabled when using lazy constraints #endif model.set(GRB_StringAttr_ModelName, "Emparelhamento perfeito with GUROBI"); // name to the problem model.set(GRB_IntAttr_ModelSense, GRB_MAXIMIZE); // is a minimization problem // Add one binary variable for each edge and also sets its cost in //the objective function for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { sprintf(name,"x_%s_%s",vname[g.u(e)].c_str(),vname[g.v(e)].c_str()); x[e] = model.addVar(0.0, 1.0, weight[e],GRB_BINARY,name); } model.update(); // run update to use model inserted variables // Add degree constraint for each node (sum of solution edges incident to a node is 2) for (ListGraph::NodeIt v(g); v!=INVALID; ++v) { GRBLinExpr expr; for (ListGraph::IncEdgeIt e(g,v); e!=INVALID; ++e) expr += x[e]; //aqui model.addConstr(expr == 2 ); what? ignorou! model.addConstr(expr == 1); } try { model.update(); // Process any pending model modifications. if (time_limit >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,time_limit); model.update(); // Process any pending model modifications. model.write("model.lp"); system("cat model.lp"); model.optimize(); double soma=0.0; int i = 0; for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { lpvar[e] = x[e].get(GRB_DoubleAttr_X); if (lpvar[e] > 1-BC_EPS ) { soma += weight[e]; cout << "Achei, x("<< vname[g.u(e)] << " , " << vname[g.v(e)] << ") = " << lpvar[e] <<"\n"; tsp.BestCircuit[i] = g.u(e); tsp.BestCircuit[i+1] = g.v(e); i = i+2; } } cout << "Solution cost = "<< soma << endl; ViewTspCircuit(tsp); }catch (...) { if (tsp.BestCircuitValue < DBL_MAX) { cout << "Heuristic obtained optimum solution" << endl; ViewTspCircuit(tsp); return 0; }else { cout << "Graph is infeasible" << endl; return 1; } } }