コード例 #1
0
ファイル: LorentzCone.cpp プロジェクト: caomw/COLA
// copy constructor
LorentzCone::LorentzCone(LorentzCone const & other): Cone(other) {
  size_ = other.size();
  // copy members
  members_ = new int[size_];
  int const * other_members = other.members();
  std::copy(other_members, other_members+size_, members_);
}
コード例 #2
0
ファイル: ColaModel.cpp プロジェクト: aykutbulut/COLA
ProblemStatus ColaModel::solve_numeric() {
  solve(false);
  // 1. determine original binding constraints
  std::vector<int> binding;
  int num_rows = getNumRows();
  int orig_num_rows = num_rows - total_num_cuts_;
  int num_cols = getNumCols();
  int * cstat = new int[num_cols];
  int * rstat = new int[num_rows];
  getBasisStatus(cstat, rstat);
  for (int i=0; i<orig_num_rows; ++i) {
    if (rstat[i]==2 or rstat[i]==3) {
      binding.push_back(i);
    }
  }
  int num_binding = binding.size();
  delete[] cstat;
  delete[] rstat;
  // 2. compute AA^T
  // A is sparse and instance of CoinPackedMatrix
  // 2.1 get A
  CoinPackedMatrix const * mat = getMatrixByRow();
  CoinPackedMatrix * A = new CoinPackedMatrix(false, 500, 500);
  std::vector<int>::const_iterator it;
  for (it=binding.begin(); it!=binding.end(); ++it) {
    int first = mat->getVectorFirst(*it);
    int last = mat->getVectorLast(*it);
    int num_elem  = last-first;
    int const * mat_cols = mat->getIndices() + first;
    double const * mat_value = mat->getElements() + first;
    A->appendRow(CoinPackedVector(num_elem, mat_cols, mat_value));
  }
  // 2.2 Compute AAt
  CoinPackedMatrix * AAt = new CoinPackedMatrix();
  double * Aa_i = new double[num_binding];
  int * Aa_i_cols = new int[num_binding];
  double * Aa_i_vals = new double[num_binding];
  for (it=binding.begin(); it!=binding.end(); ++it) {
    // A times row i of A
    int first = mat->getVectorFirst(*it);
    int last = mat->getVectorLast(*it);
    int num_elem  = last-first;
    int const * mat_cols = mat->getIndices() + first;
    double const * mat_value = mat->getElements() + first;
    A->times(CoinPackedVector(num_elem, mat_cols, mat_value), Aa_i);
    // sparsify and insert Aa_i
    int Aa_i_size = 0;
    for (int i=0; i<num_binding; ++i) {
      if (Aa_i[i]!=0.0) {
        Aa_i_cols[Aa_i_size] = i;
        Aa_i_vals[Aa_i_size] = Aa_i[i];
        Aa_i_size++;
      }
    }
    AAt->appendCol(CoinPackedVector(Aa_i_size, Aa_i_cols, Aa_i_vals));
  }
  delete[] Aa_i;
  delete[] Aa_i_cols;
  delete[] Aa_i_vals;
  //AAt->dumpMatrix();
  // 3. compute Ac
  double * Ac = new double[num_binding];
  double const * obj = getObjCoefficients();
  int obj_size;
  int * obj_cols = new int[num_cols];
  double * obj_vals = new double[num_cols];
  for (int i=0; i<num_cols; ++i) {
    if (obj[i]!=0) {
      obj_cols[obj_size] = i;
      obj_vals[obj_size] = obj[i];
      obj_size++;
    }
  }
  A->times(CoinPackedVector(obj_size, obj_cols, obj_vals), Ac);
  delete[] obj_cols;
  delete[] obj_vals;
  // 4. compute (b-Ac)
  double * b = new double[num_binding];
  int k=0;
  for (it=binding.begin(); it!=binding.end(); ++it) {
    b[k] = getRightHandSide()[*it];
    k++;
  }
  double * b_Ac = new double[num_binding];
  for (int i=0; i<num_binding; ++i) {
    b_Ac[i] = b[i] - Ac[i];
  }
  // 5. solve AA^Ty=(b-Ac)
  // 5.1 get AAt in lower triangular format
  double ** AAt_dense = new double*[num_binding];
  for (int i=0; i<num_binding; ++i) {
    AAt_dense[i] = new double[num_binding]();
  }
  int const * AAt_cols = AAt->getIndices();
  double const * AAt_value = AAt->getElements();
  for (int i=0; i<num_binding; ++i) {
    // get row i
    int first = AAt->getVectorFirst(i);
    int last = AAt->getVectorLast(i);
    //int num_elem  = last-first;
    for (int j=first; j<last; ++j) {
      AAt_dense[i][AAt_cols[j]] = AAt_value[j];
    }
  }
  // 5.2 call lapack routine to solve the system
  double * y = new double[num_binding];
  lapack_solve(AAt_dense, b_Ac, y, num_binding);
  // 6. compute d <- c+A^Ty
  // in other words x <- c + A'(AA')^{-1}b - A'(AA')^{-1}Ac when
  // we insert for y.
  // 6.1 compute Aty
  double * Aty = new double[num_cols];
  A->transposeTimes(y, Aty);
  // 6.2 compute d <- c+A^Ty
  double * dir = new double[num_cols];
  double const * cur_sol = getColSolution();
  for (int i=0; i<num_cols; ++i) {
    dir[i] = -obj[i] - Aty[i];
  }
  // 7. go along direction until we hit boundry, ie. compute step_size
  double step_size = 0.0;
  int num_cones = getNumCones();
  imp_solution_ = new double[num_cols];
  std::copy(cur_sol, cur_sol+num_cols, imp_solution_);
  double * par_sol;
  double * par_dir;
  for (int i=0; i<num_cones; ++i) {
    int cone_size = cones_[i]->size();
    LorentzCone * con = dynamic_cast<LorentzCone*>(cones_[i]);
    int const * members = con->members();
    par_sol = new double[cone_size];
    par_dir = new double[cone_size];
    // 7.1 compute step size
    // 7.2 compute a in ax^2+bx+c=0
    // 7.3 compute b in ax^2+bx+c=0
    // 7.4 compute c in ax^2+bx+c=0
    for (int j=0; j<con->size(); j++) {
      par_sol[j] = cur_sol[members[j]];
      par_dir[j] = dir[members[j]];
    }
    double feas_i = par_sol[0]*par_sol[0]-std::inner_product(par_sol+1, par_sol+cone_size, par_sol+1, 0.0);
    if (feas_i > options_->get_dbl_option(TOL)) {
      delete[] par_sol;
      delete[] par_dir;
      continue;
    }
    double a = par_dir[0]*par_dir[0];
    double b = par_sol[0]*par_dir[0];
    double c = par_sol[0]*par_sol[0];
    a = a - std::inner_product(par_dir+1, par_dir+con->size(), par_dir+1, 0.0);
    b = b - std::inner_product(par_sol+1, par_sol+con->size(), par_dir+1, 0.0);
    b = 2.0*b;
    c = c - std::inner_product(par_sol+1, par_sol+con->size(), par_sol+1, 0.0);
    // 7.5 compute step size
    double alpha1 = (-b+sqrt(b*b-4.0*a*c))/(2.0*a);
    double alpha2 = (-b-sqrt(b*b-4.0*a*c))/(2.0*a);
    double alpha=alpha1;
    std::cout << "alpha1 " << alpha1 << std::endl;
    std::cout << "alpha2 " << alpha2 << std::endl;
    // if (alpha2<alpha1)
    //   alpha=alpha2;
    for (int j=0; j<con->size(); j++) {
      imp_solution_[members[j]] = cur_sol[members[j]] + alpha*par_dir[j];
    }
    delete[] par_sol;
    delete[] par_dir;
    // get related portion of direction
    // get related portion of solution
  }
  delete A;
  delete AAt;
  delete[] Ac;
  delete[] b;
  delete[] b_Ac;
  for (int i=0; i<num_binding; ++i) {
    delete[] AAt_dense[i];
  }
  delete[] AAt_dense;
  delete[] y;
  delete[] Aty;
  delete[] dir;
  // remove all the cuts and add a cut using the improved solution
  int * indices = new int[total_num_cuts_];
  for (int i=0; i<total_num_cuts_; ++i) {
    indices[i] = orig_num_rows+i;
  }
  deleteRows(total_num_cuts_, indices);
  delete[] indices;
  total_num_cuts_ = 0;
  num_lp_solved_ = 0;
  std::fill(num_cuts_, num_cuts_+num_cones, 0);
  // separate from imp_solution
  Separate * sep = new Separate(cones_, imp_solution_, getNumCols(), options_);
  // returns true if given point is feasible for all cones.
  int feasible = sep->is_feasible();
  while(!feasible) {
    // number of cuts generated
    // std::cout << "ColaModel: " << sep->cuts()->size() << " cuts generated." << std::endl;
    // add all the cuts generated
        // Add all the cuts generated
    std::vector<CoinPackedVector*> cut = sep->cuts();
    std::vector<double> rhs = sep->rhs();
    std::vector<int> gen_cone = sep->generating_cone();
    int num_cuts = cut.size();
    for (int i=0; i<num_cuts; ++i) {
      addRow(*cut[i], -getInfinity(), rhs[i]);
      // print cut
      // end of cut print
      total_num_cuts_++;
      num_cuts_[gen_cone[i]]++;
    }
    // if (num_lp_solved_%2==0) {
    //   clean_redundant_constraints();
    // }
    // resolve the problem
    num_lp_solved_++;
    OsiClpSolverInterface::resolve();
    // update problem status
    update_problem_status();
    // check problem status
    if (soco_status_!=OPTIMAL)
      break;
    delete sep;
    // chec if the new solution is feasible for cones
    sep = new Separate(cones_, getColSolution(), getNumCols(), options_);
    feasible = sep->is_feasible();
  }
  delete sep;
  // update problem status
  update_problem_status();
  // report feasibility of imp_solution_
  double lhs = 0.0;
  double lhs_real = 0.0;
  std::cout << "Conic Constraints feasibility report" << std::endl;
  std::cout << std::setw(5) << std::left << "Cone";
  // todo(aykut) this is not true all the time, what if cone is rotated.
  std::cout << std::setw(20) << std::left << "x1^2-sum x_i^2"
            << std::setw(20) << std::left << "x1-||x_{2:n}||"
            << std::endl;
  const double * full_sol = imp_solution_;
  //double * par_sol;
  for (int i=0; i<num_cones; ++i) {
    int cone_size = cones_[i]->size();
    LorentzCone * con = dynamic_cast<LorentzCone*>(cones_[i]);
    const int * members = con->members();
    par_sol = new double[cone_size];
    for (int j=0; j<cone_size; ++j) {
      par_sol[j] = full_sol[members[j]];
    }
    if (con->type()==LORENTZ) {
      lhs = par_sol[0]*par_sol[0]
        - std::inner_product(par_sol+1, par_sol+cone_size, par_sol+1, 0.0);
      lhs_real = par_sol[0]
        -sqrt(std::inner_product(par_sol+1, par_sol+cone_size, par_sol+1, 0.0));
    }
    else if (con->type()==RLORENTZ) {
      lhs = 2.0*par_sol[0]*par_sol[1]
        - std::inner_product(par_sol+2, par_sol+cone_size, par_sol+2, 0.0);
      lhs_real = lhs;
    }
    std::cout << std::setw(5) << std::left << i
              << std::setw(20) << std::left << lhs
              << std::setw(20) << std::left << lhs_real
              << std::endl;
    delete[] par_sol;
  }
  return soco_status_;
}
コード例 #3
0
ファイル: ColaModel.cpp プロジェクト: aykutbulut/COLA
// solves problem using ben-tal nemirovski approximation
// v is approximation parameter
// resolve is false, then solve from scratch
// resolve is true, use Clp's resolve.
ProblemStatus ColaModel::solve_with_bn(bool resolve, int v) {
  // if we have rotated cones bail out,


  // create approximation
  // = first reduce all cones to 3 dimensional cones.
  // conic constraints obtained by reducing cone i
  std::vector<Cone*> reduced_cones_i;
  // set of conic constraints we get by reducing all cones of original problem
  std::vector<Cone*> reduced_cones;
  int num_cones = cones_.size();
  int num_var = getNumCols();
  for (int i=0; i<num_cones; ++i) {
    if (cones_[i]->size()<=3) {
      continue;
    }
    // reduce conic constraint i to smaller cones, save them in reduced_cc_i
    LorentzCone * c = dynamic_cast<LorentzCone*>(cones_[i]);
    reduce_cone (c->size(), c->members(), reduced_cones_i, num_var);
    // add new cones to problem
    int num_cones_i = reduced_cones_i.size();
    for (int i=0; i<num_cones_i; ++i) {
      reduced_cones.push_back(reduced_cones_i[i]);
    }
    //    std::copy(reduced_cones_i, reduced_cones_i+reduced_cones_i.size(),
    //        reduced_cones+reduced_cones.size());
    // reset reduced_cc_i
    reduced_cones_i.clear();
  }
  // print new cones of the problem
  //reduced_cc->dump_cones();
  // = add new variables to the model
  int diff = num_var - getNumCols();
  double infinity = getInfinity();
  for(int i=0; i<diff; ++i) {
    addCol(0, NULL, NULL, 0.0, infinity, 0.0);
  }
  // int num_rows = getNumRows();
  // int diff = num_var - getNumCols();
  // double * collb = new double[diff]();
  // double * colub = new double[diff]();
  // double * obj = new double[diff]();
  // double infinity = getInfinity();
  // std::fill(colub, colub+diff, infinity);
  // CoinPackedVectorBase ** cols = 0;
  // cols = new CoinPackedVectorBase*[diff];
  // int * inds = 0;
  // for (int i=0; i<diff; ++i) {
  //   cols[i] = new CoinPackedVector(num_rows, inds, 0.0);
  // }
  // addCols(diff, cols, collb, colub, obj);
  // std::cout << "Num Cols: " << getNumCols();
  // delete[] collb;
  // delete[] colub;
  // delete[] obj;
  //writeMps("reduced", "mps");
  // if reduced cone is not empty
  if (!reduced_cones.empty()) {
    setConicConstraints(reduced_cones);
  }
  int nOfCones = getNumCones();
  if (num_cuts_!=0) {
    delete[] num_cuts_;
  }
  if (num_supports_!=0) {
    delete num_supports_;
  }
  num_cuts_ = new int[nOfCones]();
  num_supports_ = new int[nOfCones]();
  solve(resolve);
  // set columns for new variables to 0
}
コード例 #4
0
ファイル: ColaModel.cpp プロジェクト: aykutbulut/COLA
// first reduces all conic constraints to 3 dimentional second order conic
// constraints as described in ben-tal nemirovski, then solves the conic
// problem using liner approximations
ProblemStatus ColaModel::solve_reducing_cones(bool resolve) {
  int num_cones = cones_.size();
  // if we have Scaled cones bail out,
  std::vector<Cone*>::const_iterator it;
  for (it=cones_.begin(); it!=cones_.end(); it++) {
    if ((*it)->type()==SCALED) {
      std::cerr << "Cola: This method is only for Lorentz cones."
                << std::endl;
      std::cerr << "Cola: Terminating..." << std::endl;
      soco_status_ = ABANDONED;
      return ABANDONED;
    }
  }
  // if we have rotated cones bail out,
  for (int i=0; i<num_cones; ++i) {
    if (cones_[i]->type()==SCALED or cones_[i]->type()==RLORENTZ) {
      std::cerr << "Cola: This method is only for canonical cones."
                << std::endl;
      std::cerr << "Cola: Terminating..." << std::endl;
      soco_status_ = ABANDONED;
      return ABANDONED;
    }
  }
  // create approximation
  // = first reduce all cones to 3 dimensional cones.
  // conic constraints obtained by reducing cone i
  std::vector<Cone*> reduced_cones_i;
  // set of conic constraints we get by reducing all cones of original problem
  std::vector<Cone*>  reduced_cones;
  int num_var = getNumCols();
  for (int i=0; i<num_cones; ++i) {
    LorentzCone * c = dynamic_cast<LorentzCone*>(cones_[i]);
    if (c->size()<=3) {
      continue;
    }
    // reduce conic constraint i to smaller cones, save them in reduced_cc_i
    reduce_cone (c->size(), c->members(), reduced_cones_i, num_var);
    // add new cones to problem
    int num_cones_i = reduced_cones_i.size();
    for (int i=0; i<num_cones_i; ++i) {
      reduced_cones.push_back(reduced_cones_i[i]);
    }
    // copy all from reduced_cones_i vector to reduced_cones
    //    std::copy(reduced_cones_i, reduced_cones_i+reduced_cones_i.size(),
    //        reduced_cones+reduced_cones.size());
    // reset reduced_cc_i
    reduced_cones_i.clear();;
  }
  // print new cones of the problem
  //reduced_cc->dump_cones();
  // = add new variables to the model
  int diff = num_var - getNumCols();
  double infinity = getInfinity();
  for(int i=0; i<diff; ++i) {
    addCol(0, NULL, NULL, 0.0, infinity, 0.0);
  }
  // int num_rows = getNumRows();
  // int diff = num_var - getNumCols();
  // double * collb = new double[diff]();
  // double * colub = new double[diff]();
  // double * obj = new double[diff]();
  // double infinity = getInfinity();
  // std::fill(colub, colub+diff, infinity);
  // CoinPackedVectorBase ** cols = 0;
  // cols = new CoinPackedVectorBase*[diff];
  // int * inds = 0;
  // for (int i=0; i<diff; ++i) {
  //   cols[i] = new CoinPackedVector(num_rows, inds, 0.0);
  // }
  // addCols(diff, cols, collb, colub, obj);
  // std::cout << "Num Cols: " << getNumCols();
  // delete[] collb;
  // delete[] colub;
  // delete[] obj;
  //writeMps("reduced", "mps");
  // if reduced cone is not empty
  if (!reduced_cones.empty()) {
    setConicConstraints(reduced_cones);
  }
  int nOfCones = getNumCones();
  if (num_cuts_!=0) {
    delete[] num_cuts_;
  }
  if (num_supports_!=0) {
    delete num_supports_;
  }
  num_cuts_ = new int[nOfCones]();
  num_supports_ = new int[nOfCones]();
  solve(resolve);
  // set columns for new variables to 0
}