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)); } }
int main(int argc, char *argv[]) { int time_limit; char name[1000]; double cutoff=0.0; ListGraph g; EdgeWeight lpvar(g); EdgeWeight weight(g); NodeName vname(g); ListGraph::NodeMap<double> posx(g),posy(g); string filename; int seed=1; // uncomment one of these lines to change default pdf reader, or insert new one //set_pdfreader("open"); // pdf reader for Mac OS X //set_pdfreader("xpdf"); // pdf reader for Linux //set_pdfreader("evince"); // pdf reader for Linux srand48(seed); time_limit = 3600; // solution must be obtained within time_limit seconds if (argc!=2) {cout<< endl << "Usage: "<< argv[0]<<" <graph_filename>"<<endl << endl << "Example: " << argv[0] << " gr_berlin52" << endl << " " << argv[0] << " gr_att48" << endl << endl; exit(0);} else if (!FileExists(argv[1])) {cout<<"File "<<argv[1]<<" does not exist."<<endl; exit(0);} filename = argv[1]; // Read the graph if (!ReadListGraph(filename,g,vname,weight,posx,posy)) {cout<<"Error reading graph file "<<argv[1]<<"."<<endl;exit(0);} TSP_Data tsp(g,vname,posx,posy,weight); ListGraph::EdgeMap<GRBVar> x(g); GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); #if GUROBI_NEWVERSION model.getEnv().set(GRB_IntParam_LazyConstraints, 1); model.getEnv().set(GRB_IntParam_Seed, seed); #else model.getEnv().set(GRB_IntParam_DualReductions, 0); // Dual reductions must be disabled when using lazy constraints #endif model.set(GRB_StringAttr_ModelName, "Undirected TSP with GUROBI"); // name to the problem model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // is a minimization problem // Add one binary variable for each edge and also sets its cost in the objective function for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { sprintf(name,"x_%s_%s",vname[g.u(e)].c_str(),vname[g.v(e)].c_str()); x[e] = model.addVar(0.0, 1.0, weight[e],GRB_BINARY,name); } model.update(); // run update to use model inserted variables // Add degree constraint for each node (sum of solution edges incident to a node is 2) for (ListGraph::NodeIt v(g); v!=INVALID; ++v) { GRBLinExpr expr; for (ListGraph::IncEdgeIt e(g,v); e!=INVALID; ++e) expr += x[e]; //aqui model.addConstr(expr == 2 ); what? ignorou! model.addConstr(expr == 2 ); } try { model.update(); // Process any pending model modifications. if (time_limit >= 0) model.getEnv().set(GRB_DoubleParam_TimeLimit,time_limit); subtourelim cb = subtourelim(tsp , x); model.setCallback(&cb); tsp.max_perturb2opt_it = 200; //1000; // number of iterations used in heuristic TSP_Perturb2OPT TSP_Perturb2OPT(tsp); if (tsp.BestCircuitValue < DBL_MAX) cutoff = tsp.BestCircuitValue-BC_EPS; // // optimum value for gr_a280=2579, gr_xqf131=566.422, gr_drilling198=15808.652 if (cutoff > 0) model.getEnv().set(GRB_DoubleParam_Cutoff, cutoff ); model.update(); // Process any pending model modifications. model.optimize(); double soma=0.0; for (ListGraph::EdgeIt e(g); e!=INVALID; ++e) { lpvar[e] = x[e].get(GRB_DoubleAttr_X); if (lpvar[e] > 1-BC_EPS ) { soma += weight[e]; if ( (vname[g.u(e)] == "243")||(vname[g.v(e)] == "243") || (vname[g.u(e)] == "242")||(vname[g.v(e)] == "242") ) { cout << "Achei, x("<< vname[g.u(e)] << " , " << vname[g.v(e)] << " = " << lpvar[e] <<"\n"; } } } cout << "Solution cost = "<< soma << endl; Update_Circuit(tsp,x); // Update the circuit in x to tsp circuit variable (if better) ViewTspCircuit(tsp); }catch (...) { if (tsp.BestCircuitValue < DBL_MAX) { cout << "Heuristic obtained optimum solution" << endl; ViewTspCircuit(tsp); return 0; }else { cout << "Graph is infeasible" << endl; return 1; } } }
int main(int argc, char *argv[]) { int 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; } } }