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; } }
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 ); } }