Пример #1
0
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;
  }
}
Пример #2
0
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 );
    }

}