void PerspCutGenerator::generateCut()
{
  const double * x = s_->getPrimal();
 
  UInt binindex;
  binindex = bp_->getIndex();
 
 FunctionPtr f = cp_->getFunction();
 UInt indexvar = 0;
 ConstVariablePtr cvp;
 double sb = x[binindex];
 double vsol = 0.0;

 // Generate solution y=(x/z,1), x are continuous and z is binary variable
 double * y = new double[rnv_];
 std::fill(y, y + rnv_, 0);
 for (VarSetConstIterator it=f->varsBegin(); it!=f->varsEnd(); ++it) {
   cvp = *it;
   indexvar = cvp->getIndex();
   //std::cout << cvp->getName() << " " << x[indexvar] << std::endl;
   if (indexvar != binindex) {
     vsol = x[indexvar];
     y[indexvar] = vsol/sb;  
     //std::cout << "corresponding y " << y[indexvar] << std::endl;
   } 
 } 

 y[binindex] = 1;
 gPCut(f,y);
 delete [] y;
 return;
}
bool
MultilinearTermsHandler::isFeasible(ConstSolutionPtr sol, RelaxationPtr ,
                                    bool &, double &)
{
  const double *x = sol->getPrimal();
  bool is_feas = true;

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  std::cout << "Checking feasibility: " << std::endl;
#endif

  for (ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) {
    ConstVariablePtr zt = it->first;
    SetOfVars const &jt = it->second;

    if (allVarsBinary_(jt)) continue;

    double zval = x[zt->getIndex()];
    double xval = 1.0;
    for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) {
      xval *= x[(*jt_it)->getIndex()];
    }
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
    std::cout << "Term for variable: " << std::endl;
    zt->write(std::cout);
    std::cout << " has error: " << fabs(zval - xval) << std::endl;
#endif
    if (fabs(zval - xval) > eTol_) {
      is_feas = false;
      break;
    }
  }
  
  return(is_feas);
}
// This chunk of code adds
// z_t = \sum_{k=1}^{2 |V_g|} \lambda_k^g, \Prod_{j \in J_t} \chi_j^{g,k}
//   \forall J_t \subseteq V_g
void
MultilinearTermsHandler::handleZDefConstraints_(RelaxationPtr relaxation, HandleCallingFunction wherefrom, ModVector &mods)
{
  for(ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) {
    ConstVariablePtr zt = it->first;
    SetOfVars const &jt = it->second;

    for (UInt gix = 0; gix < groups_.size(); ++gix) {
      SetOfVars &vg = groups_[gix];
       
      if (std::includes(vg.begin(), vg.end(), jt.begin(), jt.end())) { 
        // jt is a subset of vg, add constraint
        LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
        lf->addTerm(zt, -1.0);
        int pix = 0;

        for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); 
             it2 != points_[gix].end(); ++it2) {
          double prodval = 1.0;
          VariablePtr lam = lambdavars_[gix][pix];

          for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) {
            ConstVariablePtr xvar = *jt_it;
            double tmp = varIsAtLowerBoundAtPoint_(xvar, *it2) ? xvar->getLb() : xvar->getUb();
            prodval *= tmp;
          }

          lf->addTerm(lam, prodval);
          ++pix;
        }        
        FunctionPtr f = (FunctionPtr) new Function(lf);

        if (wherefrom == relaxInit_Call) {
          ConstraintPtr c = relaxation->newConstraint(f, 0.0, 0.0);
          zConMap_.insert(std::make_pair(IntVarPtrPair(gix, zt), c));
        }
        else { 
          IntVarPtrPairConstraintMap::iterator pos;
          pos = zConMap_.find(IntVarPtrPair(gix, zt));
          if (pos == zConMap_.end()) {
            assert(0);
          }
          ConstraintPtr c = pos->second;
          //XXX Here you should just check if the constraint really was going to
          //change and do nothing if it doesn't...  (will be faster).
          if (wherefrom == relaxNodeInc_Call) {
            relaxation->changeConstraint(c, lf, 0.0, 0.0);
          }
          LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0); 
          mods.push_back(lcmod);
        }
      }
      
    }
  } 


}
void 
Hypergraph::create(std::map<ConstVariablePtr, SetOfVars > const &terms)
{

  // Add the vertices
  std::map<ConstVariablePtr, SetOfVars >::const_iterator terms_it;
  for(terms_it = terms.begin(); terms_it != terms.end(); ++terms_it) {
    SetOfVars const &jt = terms_it->second;
    for(SetOfVars::iterator it = jt.begin(); it != jt.end(); ++it) {
      V_.insert(*it);
    }
  }

  // Add empty lists for the hyperedges
  for(SetOfVars::iterator v_it = V_.begin(); v_it != V_.end(); ++v_it) {
    std::list<SetOfVars> e_list;
    adjList_.insert(make_pair(*v_it, e_list));
  }

  // Now add the edges
  for(terms_it = terms.begin(); terms_it != terms.end(); ++terms_it) {
    SetOfVars const &jt = terms_it->second;
    E_.insert(jt);
    // Put it in the adjacency lists
    for (SetOfVars::const_iterator it = jt.begin(); it != jt.end(); ++it) {
      AdjListType::iterator pos = adjList_.find(*it);
      assert(pos != adjList_.end());
      std::list<SetOfVars> &e_list = pos->second;
      e_list.push_back(jt);
    }
    
    // Determine weight
    ConstVariablePtr zvar = terms_it->first;
    double zweight = 0.0;
    for (ConstrSet::iterator it2 = zvar->consBegin(); it2 != zvar->consEnd(); ++it2) {
      const LinearFunctionPtr lf = (*it2)->getLinearFunction();
      double w = lf->getWeight(zvar);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      zvar->write(std::cout);
      std::cout << "  has weight: " << w << " in constraint: ";
      (*it2)->write(std::cout);
#endif
      zweight += fabs(w);
    }

    // Add objective weight
    const LinearFunctionPtr obj = problem_->getObjective()->getLinearFunction();
    if (obj != 0) {
      double w = obj->getWeight(zvar);
      zweight += fabs(w);
    }

    weights_.insert(make_pair(jt, zweight));
    originalWeights_.insert(make_pair(jt, zweight));
  }
}
void
MultilinearTermsHandler::handleXDefConstraints_(RelaxationPtr relaxation, HandleCallingFunction wherefrom, ModVector &mods)
{
  for (UInt gix = 0; gix < groups_.size(); ++gix) {
    for(SetOfVars::const_iterator it = groups_[gix].begin(); it != groups_[gix].end(); ++it) {
      ConstVariablePtr xvar = *it;
      LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
      lf->addTerm(xvar, -1.0);
      
      int pix = 0;
      for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); it2 != points_[gix].end(); ++it2) {
        VariablePtr lam = lambdavars_[gix][pix];
        double val = varIsAtLowerBoundAtPoint_(xvar, *it2) ? xvar->getLb() : xvar->getUb();
        lf->addTerm(lam, val);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
        std::cout << xvar->getName() << ", lam: " << gix << "," << pix << " value is: " 
                  << val << std::endl;
#endif        
        ++pix;
      }      
      FunctionPtr f = (FunctionPtr) new Function(lf);

      if (wherefrom == relaxInit_Call) {
        ConstraintPtr c = relaxation->newConstraint(f, 0.0, 0.0);
        xConMap_.insert(std::make_pair(IntVarPtrPair(gix, xvar), c));
      }
      else { 
        IntVarPtrPairConstraintMap::iterator pos;
        pos = xConMap_.find(IntVarPtrPair(gix, xvar));
        if (pos == xConMap_.end()) {
          assert(0);
        }
        ConstraintPtr c = pos->second;
        //XXX Here you should just check if the constraint really was going to
        //change and do nothing if it doesn't...  (will be faster).
        if (wherefrom == relaxNodeInc_Call) {
          relaxation->changeConstraint(c, lf, 0.0, 0.0);
        }
        else {
          assert(0);
        }
        LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0); 
        mods.push_back(lcmod);
      }      
    }
  }  
  
}
void
Hypergraph::write(std::ostream &out) const
{
  for(AdjListType::const_iterator it = adjList_.begin(); it != adjList_.end(); ++it) {
    ConstVariablePtr v = it->first;
    std::cout << "Vertex: ";
    v->write(out);
    std::list<SetOfVars> e_list = it->second;    
    for(std::list<SetOfVars>::const_iterator e_it = e_list.begin(); e_it != e_list.end(); ++e_it) {
      std::cout << " has edge: " << std::endl;    
      for(SetOfVars::const_iterator v_it = e_it->begin(); v_it != e_it->end(); ++v_it) {
        (*v_it)->write(out);
      }
    }
  }    
}
void
MultilinearTermsHandler::setupWeights_()
{
  for(ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) {
    ConstVariablePtr zvar = it->first;
    double zweight = 0.0;
    for (ConstrSet::iterator it2 = zvar->consBegin(); it2 != zvar->consEnd(); ++it2) {
      const LinearFunctionPtr lf = (*it2)->getLinearFunction();
      double w = lf->getWeight(zvar);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      zvar->write(std::cout);
      std::cout << "  has weight: " << w << " in constraint: ";
      (*it2)->write(std::cout);
#endif
      zweight += fabs(w);
    }
    weights_.insert(std::make_pair(zvar, zweight));
  }
  
}
Exemplo n.º 8
0
void
MultilinearFormulation::boundsOnProduct(ConstVariablePtr x1, ConstVariablePtr x2,
                                        double &lb, double &ub)
{
  double l1 = x1->getLb();
  double u1 = x1->getUb();
  double l2 = x2->getLb();
  double u2 = x2->getUb();

  lb = l1 * l2;
  ub = l1 * l2;

  lb = std::min(lb, u1*l2);
  ub = std::max(ub, u1*l2);

  lb = std::min(lb, u1*u2);
  ub = std::max(ub, u1*u2);

  lb = std::min(lb, l1*u2);
  ub = std::max(ub, l1*u2);

}
BranchPtr
MultilinearTermsHandler::doBranch_(BranchDirection UpOrDown, ConstVariablePtr v, 
                                   double bvalue)
{
  BranchPtr branch;
  BoundType lu;
  VariableType vtype = v->getType();

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  std::cout << "Branching: " << (UpOrDown == DownBranch ? "Down" : "Up")
            << " at value: " << bvalue << " on: " << std::endl;
  v->write(std::cout);
#endif

  branch = (BranchPtr) new Branch();

  double branching_value = bvalue;

  // Change bounds on the x var (called v here)
  if (UpOrDown == DownBranch) { 
    lu = Upper;    
    if (vtype != Continuous)  branching_value = floor(bvalue);
  }
  else {
    lu = Lower;
    if (vtype != Continuous)  branching_value = ceil(bvalue);
  }
 
  VarBoundModPtr vmod = (VarBoundModPtr) new VarBoundMod(v, lu, branching_value);
  assert(!"check whether this needs to be addRMod instead");
  branch->addPMod(vmod);

  branch->setActivity(0.5);// TODO: set this correctly
  return branch;

}
Exemplo n.º 10
0
void KnapCovHandler::separate(ConstSolutionPtr sol, NodePtr,
                              RelaxationPtr rel, CutManager * cmanager,
                              SolutionPoolPtr , bool * ,
                              SeparationStatus * status)
{
  // Check integer feasibility of sol, must add cuts if it is not integral.
  numvars_ = minlp_->getNumVars();
  VariableType type;
  const double * x = sol->getPrimal();
  // Is the relaxation solution is integer feasible.
  bool isintfeas = true;
  // Iterators for variables.
  VariableConstIterator it;
  VariableConstIterator begin = rel->varsBegin();
  VariableConstIterator end   = rel->varsEnd();
  // Temporary variable holder.
  ConstVariablePtr var; 
  // Value of variable.
  double value;
  bool separated = false;
  UInt n_added = 0;

  // Check if integrality is satisfied for each integer variable. 
  for (it=begin; it!=end; ++it) {
    var = *it;
    type = var->getType();
    if (type==Binary || type==Integer) {
      value = x[var->getIndex()];
      if (fabs(value - floor(value + 0.5)) > intTol_) {
        isintfeas = false;
        break;
      }
    }
  }

  if (isintfeas ==  false) {
    // We do another check in CoverCutGneerator for integrality, may be we
    // should eliminate it and use the one above.
    // Generate cover cuts from current relaxation.
    CoverCutGeneratorPtr cover = (CoverCutGeneratorPtr) new CoverCutGenerator(rel,sol, env_);
    // Add cuts to the relaxation by using cut manager.
    CutVector violatedcuts = cover->getViolatedCutList();
    CutIterator itc;
    CutIterator beginc = violatedcuts.begin();
    CutIterator endc   = violatedcuts.end();
    
    // Serdar I am not sure if we should add the constraints generated by
    // addCuts to the constraint vector of knapsack cover handler.
    // Currently CutMan2::addCuts does not add the cuts to the relaxation formulation.
    cmanager->addCuts(beginc, endc);
    cmanager->separate(rel, sol, &separated, &n_added);
    if (n_added>0) {
      *status = SepaResolve;
    }
    
    // Update statistics by using return from cover cut generator.
    ConstCovCutGenStatsPtr covstats = cover->getStats();
    // Later put the code below to updateStats function.
    stats_->knaps += covstats->knaps;
    stats_->cuts += covstats->cuts;
    stats_->extended += covstats->extended;
    stats_->simple += covstats->simple;
    stats_->gns += covstats->gns;
    stats_->singlectwo += covstats->singlectwo;    
  }

  
}
Exemplo n.º 11
0
void PerspCutGenerator::gPCut(FunctionPtr f, double * y)
{
  int  error = 0, errorgr = 0;
  //NonlinearFunctionPtr nlf = cp_->getNonlinearFunction();
  LinearFunctionPtr lf = cp_->getLinearFunction();
  double conseval = f->eval(y, &error);
  double * cgrad = new double[rnv_];
  std::fill(cgrad, cgrad + rnv_, 0);
  f->evalGradient(y, cgrad, &errorgr);
  lf_ = (LinearFunctionPtr) new LinearFunction();

  if (errorgr == 0 && error ==0) {
    double gradu =0.0 ;
    // Gradient of continuous variables in the constraint.
    double gradfi = 0.0;
    // Index of current variable considered.
     UInt varindex = 0;
    // Soluion of variable at vector y.
    double ysolvar = 0.0;
    ConstVariablePtr var ;
    ConstraintPtr newc;
    for (VarSetConstIterator it = f->varsBegin(); it!= f->varsEnd(); ++it) {
      var = *it; 
      varindex = var->getIndex();
      //std::cout << var->getName() << " " << y[varindex] << std::endl;
      if(varindex!=bp_->getIndex()){
        gradfi =cgrad[varindex];
        //std::cout << var->getName() << " Gradient:  " << gradfi << std::endl;

        // Add terms for each variable.
        lf_->addTerm(var, gradfi);
        // Solution value of variable.
        ysolvar = y[varindex];
        // gradient for variable u is calculated.
        gradu -= (gradfi * ysolvar); 
      } 
      //else {
        //gradu +=lf->getWeight(bp_);
      //}
    }
    // In perspective reformulated constraint coefficient of binary variable is
    // included in conseval
    // its coefficient in original constraint minus the upper bound of the constraint
    if(cp_->getUb() != +INFINITY){
      gradu-=(cp_->getUb());
    } else {
      gradu+=(cp_->getLb());
    }
    gradu+=conseval;
    // We can add binary variable to linearization, when we considered all
    // variables except the binary variable so that the linearization
    // coefficient of binary variable is calculated.
    lf_->addTerm(bp_, gradu);
    return;
  } else {
    logger_->msgStream(LogError) << me_ <<" Gradient"
     <<  " or nonlinear part of the function is not defined at the current point" 
     <<std::endl;
  }
  return;
}
Exemplo n.º 12
0
BranchPtr CxUnivarHandler::doBranch_(BranchDirection UpOrDown,
                                     ConstVariablePtr v, double bvalue)
{
  BranchPtr branch;
  LinModsPtr linmods;

#if defined(DEBUG_CXUNIVARHANDLER)
  std::cout << "CxUnivarHandler, Branching: " << (UpOrDown == DownBranch ? "Down" : "Up")
            << " at value: " << bvalue << " on: " << std::endl;
  v->write(std::cout);
#endif

  // Zero out tmpX and grad each time, or else bad things happen
  for (UInt j = 0; j < tmpX_.size(); ++j) {
    tmpX_[j] = 0.0;
    grad_[j] = 0.0;
  }
    
  branch = (BranchPtr) new Branch();
  linmods = (LinModsPtr) new LinMods();

  // Change bounds on the x var (called v here)
  if (UpOrDown == DownBranch) {

    VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Upper, bvalue);
    linmods->insert(mod);

    // Find *all* cons_data that has v as an input variable.
    CxUnivarConstraintIterator dit; 
  
    for (dit = cons_data_.begin(); dit != cons_data_.end(); ++dit) {
      if ((*dit)->getRInputVar() == v) {

	ConstVariablePtr rov = (*dit)->getROutVar();
	FunctionPtr fn = (*dit)->getOriginalCon()->getFunction();
	int error;

	// Change the secant constraint
	ConstraintPtr secCon = (*dit)->getSecantCon();

	LinearFunctionPtr lf; 
	FunctionPtr f;

	double xlb = v->getLb();
	double xub = bvalue;

	// TODO: Check the error value!
	tmpX_[v->getIndex()] = xlb;
	double fxlb =  fn->eval(tmpX_, &error);
	tmpX_[v->getIndex()] = xub;
	double fxub =  fn->eval(tmpX_, &error);
	tmpX_[v->getIndex()] = 0.0;

	// TODO: check/remedy numerical issues in this division
	double m = 0.0;
	if (xub - xlb > 10e-7) {
	  m = (fxub - fxlb)/(xub - xlb);
	}
	double intercept = fxlb - m*xlb;
	lf = (LinearFunctionPtr) new LinearFunction();
	lf->addTerm(rov, 1.0);
	lf->addTerm(v, -m);

        LinConModPtr lcmod = (LinConModPtr) new LinConMod(secCon, lf,
                                                          -INFINITY,
                                                          intercept);
	linmods->insert(lcmod);

	// Change all linearization constraints
	ConstraintVector::iterator lin_it;
        for(lin_it = (*dit)->linConsBegin(); lin_it != (*dit)->linConsEnd();
            ++lin_it) {
	  ConstraintPtr c = *lin_it;
	}
      }
    }
  } else {
    VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Lower, bvalue);
    linmods->insert(mod);
  }

  assert(!"add Mod correctly here.");
  branch->addPMod(linmods);
  return branch;

}
Exemplo n.º 13
0
void CxUnivarConstraintData::addSecant(RelaxationPtr rel,
                                       ConstVariablePtr riv,
                                       ConstVariablePtr rov,
                                       FunctionPtr fn, DoubleVector& tmpX,
                                       bool init, ModVector &mods) 
{

  int error;
  double xlb, xub, fxlb, fxub, m, intercept;
  LinearFunctionPtr lf; 
  FunctionPtr f;

  // First add the secant inequalities based on variable bounds
  xlb = riv->getLb();
  xub = riv->getUb();
	
#if defined(DEBUG_CXUNIVARHANDLER)
  std::cout << "Adding secant on variable rix index: " << riv->getIndex() 
	    << " rov index: " << rov->getIndex()
	    << " xlb: " << xlb << " xub: " << xub << std::endl;
#endif 
  // no secant if unbounded either way
  if (xlb <= -0.9*INFINITY || xub >= 0.9*INFINITY) {
    std::cout << "Cannot add secant -- bound is infinite" << std::endl;
    return;
  }

  // TODO: Check the error value!
  tmpX[riv->getIndex()] = xlb;
  fxlb =  fn->eval(tmpX, &error);
  tmpX[riv->getIndex()] = xub;
  fxub =  fn->eval(tmpX, &error);
  tmpX[riv->getIndex()] = 0.0;

  // TODO: check/remedy numerical issues in this division
  if (xub - xlb > 10e-7) {
    m = (fxub - fxlb)/(xub - xlb);
  }
  else {
    m = 0.0;
  }

  intercept = fxlb - m*xlb;
  lf = (LinearFunctionPtr) new LinearFunction();
  lf->addTerm(rov, 1.0);
  lf->addTerm(riv, -m);

  // rovar <= m*rivar + intercept 
  if (init) {
     f = (FunctionPtr) new Function(lf);
     secCon_ = rel->newConstraint(f, -INFINITY, intercept);
  }
  else {
    rel->changeConstraint(secCon_, lf, -INFINITY, intercept);
    LinConModPtr lcmod = (LinConModPtr) new LinConMod(secCon_, lf, -INFINITY,
                                                      intercept);
    mods.push_back(lcmod);
  }

  
}
Exemplo n.º 14
0
void CxUnivarConstraintData::addLin(RelaxationPtr rel, ConstVariablePtr riv,
				    ConstVariablePtr rov, FunctionPtr fn,
                                    DoubleVector& tmpX, DoubleVector& grad,
                                    bool init, ModVector &mods)
{
 
  int error;
  ConstraintPtr cons; 
  double xlb = riv->getLb();
  double xub = riv->getUb();
  double fxlbval=0, fxubval=0, dfxlbval=0, dfxubval=0;
  double tmpxval, fxval, dfxval; 
  LinearFunctionPtr lf; 
  FunctionPtr f;

  // More sophisticated strategies hopefully could be obtained by simply
  // changing this array 
  int npts = 3;
  double xvals[] = {xlb, xub, (xub-xlb)/2.0};

#if defined(DEBUG_CXUNIVARHANDLER)
  std::cout << "Adding linearizations.  rix id: " << riv->getId() 
	    << " rix index: " << riv->getIndex() << " rov id: " << rov->getId() 
	    << " rov index: " << rov->getIndex()
	    << " xlb: " << xlb << " xub: " << xub << std::endl;
#endif
  
  for (int i = 0; i < npts; i++) {

    // Zero out tmpX and grad each time, or else bad things happen
    for (UInt j = 0; j < tmpX.size(); ++j) {
      tmpX[j] = 0.0;
      grad[j] = 0.0;
    }
    
    if (i == 2) {
      // Third linearization point taken to be where first two intersect:
      // x3 = (f'(xub)*xub - f'(xlb)*xlb + f(xlb) - f(xub))/(f'(xub) - f'(xlb))
      // Unless this would put it too close to one of the end points
      if (dfxubval - dfxlbval > 0.0001 || dfxubval - dfxlbval < -0.0001) {
        tmpxval = (dfxubval*xub - dfxlbval*xlb + fxlbval - fxubval)/
                  (dfxubval - dfxlbval);
        if (tmpxval < xlb + (xub-xlb)*0.05) {
          xvals[2] = xlb + (xub-xlb)*0.05;
        }
        else if (tmpxval > xub - (xub-xlb)*0.05) {
          xvals[2] = xub - (xub-xlb)*0.05;
        }
        else {
          xvals[2] = tmpxval;
        }
      }
    }
    tmpX[riv->getIndex()] = xvals[i];
    error = 0;
    fxval =  fn->eval(tmpX, &error);
    fn->evalGradient(&tmpX[0], &grad[0], &error);
#if defined(DEBUG_CXUNIVARHANDLER2)
    for (UInt j = 0; j < tmpX.size(); ++j) {
      std::cout << "x[" << j << "] = " << tmpX[j] << " dfdx[" << j << "] = "
                << grad[j] << std::endl;
    }
#endif
    dfxval = grad[riv->getIndex()];
    if (i == 0) {
       fxlbval = fxval;
       dfxlbval = dfxval; 
    }
    else if (i == 1) {
       fxubval = fxval;
       dfxubval = dfxval; 
    }
    // linearization:  rov >= f(xval) + f'(xval)(riv - xval) 
    //                 rov - f'(xval)*riv >= f(xval) - f'(xval)*xval
    lf = (LinearFunctionPtr) new LinearFunction();
    lf->addTerm(rov, 1.0);
    lf->addTerm(riv, -dfxval);
    if (init) {
        f = (FunctionPtr) new Function(lf);
    	cons = rel->newConstraint(f, fxval - dfxval*xvals[i], INFINITY);
	linCons_.push_back(cons);
    }
    else {
#if defined(DEBUG_CXUNIVARHANDLER)
       std::cout << "Will change 'linearization  ' constraint to have "
                 << "linear function: ";
       lf->write(std::cout);  
       std::cout << std::endl;
#endif

       rel->changeConstraint(linCons_[i], lf, fxval - dfxval*xvals[i], INFINITY); 
       LinConModPtr lcmod = (LinConModPtr) new LinConMod(linCons_[i], lf, 
                                                         fxval -
                                                         dfxval*xvals[i],
                                                         INFINITY); 
       mods.push_back(lcmod);
    }
  }
  tmpX[riv->getIndex()] = 0.0;
  grad[riv->getIndex()] = 0.0;

}
void MultilinearTermsHandler::getBranchingCandidates(RelaxationPtr, 
                                                const DoubleVector &x,
                                                ModVector &,
                                                BrVarCandSet &cands,
                                                BrCandVector &, bool &is_inf)
{
  // Implementation notes:
  //  (1) You must insert into the set cands
  //  (2) Super naive implmentation:  Just pick the variable from infeasible
  //      terms whose total 'bound product' is largest

  std::set<ConstVariablePtr> candidates;

  for (ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) {
    ConstVariablePtr zt = it->first;
    SetOfVars const &jt = it->second;

    if (allVarsBinary_(jt)) continue;

    double zval = x[zt->getIndex()];

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      std::cout << "Relaxation term variable: ";
      zt->write(std::cout);
      std::cout << " Has LP value: " << zval << std::endl;
#endif

    double termval = 1.0;
    double largest_score = eTol_;
    ConstVariablePtr largest_score_var;
    for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) {
      ConstVariablePtr termvar = *jt_it;
      termval *= x[termvar->getIndex()];
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      std::cout << "Term variable: ";
      termvar->write(std::cout);
      std::cout <<  "  has value: " << x[termvar->getIndex()] << std::endl;
#endif

      double score = (termvar->getUb() - x[termvar->getIndex()])*
        (x[termvar->getIndex()] - termvar->getLb());

      if (score > largest_score) {
        largest_score = score;
        largest_score_var = termvar;
      }
    }
    if (fabs(zval - termval) > eTol_) {
      candidates.insert(largest_score_var);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      largest_score_var->write(std::cout);
      std::cout << " will be a candidate" << std::endl;      
#endif
    }
    
  }

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  std::cout << "Branching candidates are: " << std::endl;
  for(SetOfVars::const_iterator it = candidates.begin(); it != candidates.end(); ++it) {
    (*it)->write(std::cout);
  }
#endif  

  for(SetOfVars::const_iterator it = candidates.begin(); it != candidates.end(); ++it) {
    ConstVariablePtr v = *it;
    BrVarCandPtr br_can = (BrVarCandPtr) new BrVarCand(v, v->getIndex(), 0.5, 0.5);
    cands.insert(br_can);
  }
  is_inf = false;
}
ModificationPtr MultilinearTermsHandler::getBrMod(BrCandPtr cand, DoubleVector &xval, 
                                                  RelaxationPtr , BranchDirection dir)
{
  LinModsPtr linmods;

  //XXX Put (bool init) back in handle{x,z}def...

  BrVarCandPtr  vcand = boost::dynamic_pointer_cast <BrVarCand> (cand);
  VariablePtr v = vcand->getVar();
  
  double branching_value = xval[v->getIndex()];
  BoundType lu;
  VariableType vtype = v->getType();

  // Change bounds on the x var (called v here)
  if (dir == DownBranch) { 
    lu = Upper;    
    if (vtype != Continuous)  branching_value = floor(branching_value);
  }
  else {
    lu = Lower;
    if (vtype != Continuous)  branching_value = ceil(branching_value);
  }

  linmods = (LinModsPtr) new LinMods();

  VarBoundModPtr vmod = (VarBoundModPtr) new VarBoundMod(v, lu, branching_value);
  linmods->insert(vmod);
  
  
  // This chunk of code changes the
  // x_{V_g} = \sum_{k=1}^{2 |V_g|} \lambda_k^g \chi^{k,g} \forall g \in G


  for (UInt gix = 0; gix < groups_.size(); ++gix) {
    for(SetOfVars::const_iterator it = groups_[gix].begin(); it != groups_[gix].end(); ++it) {
      ConstVariablePtr xvar = *it;
      if (v != xvar) continue;

      LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
      lf->addTerm(xvar, -1.0);

      UInt pix = 0;
      for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); it2 != points_[gix].end(); ++it2) {
        VariablePtr lam = lambdavars_[gix][pix];
        double val = -INFINITY;

        bool atLower = varIsAtLowerBoundAtPoint_(v, *it2);
        bool atUpper = !atLower;
        
        if (lu == Upper && atUpper) val = branching_value;
        else if (lu == Lower && atLower) val = branching_value;
        else val = (atLower ? v->getLb() : v->getUb());

        lf->addTerm(lam, val);
        ++pix;
      }       
      FunctionPtr f = (FunctionPtr) new Function(lf);

      IntVarPtrPairConstraintMap::iterator pos;
      pos = xConMap_.find(IntVarPtrPair(gix, xvar));
      if (pos == xConMap_.end()) {
        assert(0);
      }
      ConstraintPtr c = pos->second;

      LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      std::cout << "getBrMod().  Will change 'x =' constraint to have linear function ";
      lf->write(std::cout);        
      std::cout << std::endl;
#endif
      linmods->insert(lcmod);
    
    }
  }

  // This will change the z_t = sum \sum_{k=1}^{2|V_g} \lambda_k^g \chi^{k,g}.
  //  Probably not very efficient way to do this...
  for(ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) {
    SetOfVars const &jt = it->second;

    for (UInt gix = 0; gix < groups_.size(); ++gix) {
      SetOfVars &vg = groups_[gix];

      std::set<ConstVariablePtr>::iterator pos1;
      pos1 = jt.find(v);
      if (pos1 == jt.end()) continue; // J_t does not contain v, go to next group
      // J_t is not in V_g, go to next group
      if (! std::includes(vg.begin(), vg.end(), jt.begin(), jt.end())) continue;

      ConstVariablePtr zvar = it->first;
      LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
      lf->addTerm(zvar, -1.0);

      // Get ConstraintToChange
      IntVarPtrPairConstraintMap::iterator pos2;
      pos2 = zConMap_.find(IntVarPtrPair(gix, zvar));
      if (pos2 == zConMap_.end()) {
        assert(0);
      }
      ConstraintPtr c = pos2->second;

      UInt pix = 0;
      for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); 
           it2 != points_[gix].end(); ++it2) {

        double prodval = 1.0;
        VariablePtr lam = lambdavars_[gix][pix];

        // Compute new extreme point value for this lambda
        for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) {
          ConstVariablePtr xvar = *jt_it;
          double val = 0.0;
          bool atLower = varIsAtLowerBoundAtPoint_(xvar, *it2);
          bool atUpper = !atLower;
            
          if (xvar == v) {
            if (lu == Upper && atUpper) val = branching_value;
            else if (lu == Lower && atLower) val = branching_value;
            else val = (atLower ? xvar->getLb() : xvar->getUb());
          }
          else {
            val = atLower ? xvar->getLb() : xvar->getUb();
          }            
          prodval *= val;
        }
        lf->addTerm(lam, prodval);
        ++pix;
      }

      // Add new mod
      LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0);

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
      std::cout << "getBrMod(): Will change 'zt = ' constraint to have linear function: ";
      lf->write(std::cout);  
      std::cout << std::endl;
#endif
      linmods->insert(lcmod);
    }
          
  }

  return linmods;

  return ModificationPtr();
}