Ignore:
Timestamp:
Sep 15, 2006 4:55:05 PM (13 years ago)
Author:
forrest
Message:

many changes

Location:
branches/devel/Cbc/examples
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/devel/Cbc/examples/CbcBranchLink.cpp

    r134 r424  
    2222    numberMembers_(0),
    2323    numberLinks_(0),
    24     first_(-1)
     24    which_(NULL)
    2525{
    2626}
     
    3232    numberMembers_(numberMembers),
    3333    numberLinks_(numberLinks),
    34     first_(first)
     34    which_(NULL)
    3535{
    3636  id_=identifier;
    3737  if (numberMembers_) {
    3838    weights_ = new double[numberMembers_];
     39    which_ = new int[numberMembers_*numberLinks_];
    3940    if (weights) {
    4041      memcpy(weights_,weights,numberMembers_*sizeof(double));
     
    5051      last=weights_[i];
    5152    }
     53    for (i=0;i<numberMembers_*numberLinks_;i++) {
     54      which_[i]=first+i;
     55    }
     56  } else {
     57    weights_ = NULL;
     58  }
     59}
     60
     61// Useful constructor (which are indices)
     62CbcLink::CbcLink (CbcModel * model,  int numberMembers,
     63           int numberLinks, const int * which , const double * weights, int identifier)
     64  : CbcObject(model),
     65    numberMembers_(numberMembers),
     66    numberLinks_(numberLinks),
     67    which_(NULL)
     68{
     69  id_=identifier;
     70  if (numberMembers_) {
     71    weights_ = new double[numberMembers_];
     72    which_ = new int[numberMembers_*numberLinks_];
     73    if (weights) {
     74      memcpy(weights_,weights,numberMembers_*sizeof(double));
     75    } else {
     76      for (int i=0;i<numberMembers_;i++)
     77        weights_[i]=i;
     78    }
     79    // weights must be increasing
     80    int i;
     81    double last=-COIN_DBL_MAX;
     82    for (i=0;i<numberMembers_;i++) {
     83      assert (weights_[i]>last+1.0e-12);
     84      last=weights_[i];
     85    }
     86    for (i=0;i<numberMembers_*numberLinks_;i++) {
     87      which_[i]= which[i];
     88    }
    5289  } else {
    5390    weights_ = NULL;
     
    6198  numberMembers_ = rhs.numberMembers_;
    6299  numberLinks_ = rhs.numberLinks_;
    63   first_ = rhs.first_;
    64100  if (numberMembers_) {
    65     weights_ = new double[numberMembers_];
    66     memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
     101    weights_ = CoinCopyOfArray(rhs.weights_,numberMembers_);
     102    which_ = CoinCopyOfArray(rhs.which_,numberMembers_*numberLinks_);
    67103  } else {
    68104    weights_ = NULL;
     105    which_ = NULL;
    69106  }
    70107}
     
    84121    CbcObject::operator=(rhs);
    85122    delete [] weights_;
     123    delete [] which_;
    86124    numberMembers_ = rhs.numberMembers_;
    87125    numberLinks_ = rhs.numberLinks_;
    88     first_ = rhs.first_;
    89126    if (numberMembers_) {
    90       weights_ = new double[numberMembers_];
    91       memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
     127      weights_ = CoinCopyOfArray(rhs.weights_,numberMembers_);
     128      which_ = CoinCopyOfArray(rhs.which_,numberMembers_*numberLinks_);
    92129    } else {
    93130      weights_ = NULL;
     131      which_ = NULL;
    94132    }
    95133  }
     
    101139{
    102140  delete [] weights_;
     141  delete [] which_;
    103142}
    104143
     
    112151  OsiSolverInterface * solver = model_->solver();
    113152  const double * solution = model_->testSolution();
    114   const double * lower = solver->getColLower();
     153  //const double * lower = solver->getColLower();
    115154  const double * upper = solver->getColUpper();
    116155  double integerTolerance =
     
    121160  // check bounds etc
    122161  double lastWeight=-1.0e100;
    123   int base=first_;
     162  int base=0;
    124163  for (j=0;j<numberMembers_;j++) {
    125164    for (int k=0;k<numberLinks_;k++) {
    126       int iColumn = base+k;
    127       if (lower[iColumn])
    128         throw CoinError("Non zero lower bound in CBCLink","infeasibility","CbcLink");
     165      int iColumn = which_[base+k];
     166      //if (lower[iColumn])
     167      //throw CoinError("Non zero lower bound in CBCLink","infeasibility","CbcLink");
    129168      if (lastWeight>=weights_[j]-1.0e-7)
    130169        throw CoinError("Weights too close together in CBCLink","infeasibility","CbcLink");
     
    177216  double sum =0.0;
    178217
    179   int base=first_;
     218  int base=0;
    180219  for (j=0;j<numberMembers_;j++) {
    181220    for (int k=0;k<numberLinks_;k++) {
    182       int iColumn = base+k;
     221      int iColumn = which_[base+k];
    183222      double value = CoinMax(0.0,solution[iColumn]);
    184223      sum += value;
     
    193232  }
    194233  assert (lastNonZero-firstNonZero==0) ;
    195   base=first_;
     234  base=0;
    196235  for (j=0;j<firstNonZero;j++) {
    197236    for (int k=0;k<numberLinks_;k++) {
    198       int iColumn = base+k;
     237      int iColumn = which_[base+k];
    199238      solver->setColUpper(iColumn,0.0);
    200239    }
     
    205244  for (j=lastNonZero+1;j<numberMembers_;j++) {
    206245    for (int k=0;k<numberLinks_;k++) {
    207       int iColumn = base+k;
     246      int iColumn = which_[base+k];
    208247      solver->setColUpper(iColumn,0.0);
    209248    }
     
    229268  double weight = 0.0;
    230269  double sum =0.0;
    231   int base=first_;
     270  int base=0;
    232271  for (j=0;j<numberMembers_;j++) {
    233272    for (int k=0;k<numberLinks_;k++) {
    234       int iColumn = base+k;
     273      int iColumn = which_[base+k];
    235274      if (upper[iColumn]) {
    236275        double value = CoinMax(0.0,solution[iColumn]);
     
    313352  int numberLinks = set_->numberLinks();
    314353  const double * weights = set_->weights();
     354  const int * which = set_->which();
    315355  OsiSolverInterface * solver = model_->solver();
    316356  //const double * lower = solver->getColLower();
     
    324364    }
    325365    assert (i<numberMembers);
    326     int base=set_->first()+i*numberLinks;;
     366    int base=i*numberLinks;;
    327367    for (;i<numberMembers;i++) {
    328368      for (int k=0;k<numberLinks;k++) {
    329         int iColumn = base+k;
     369        int iColumn = which[base+k];
    330370        solver->setColUpper(iColumn,0.0);
    331371      }
     
    335375  } else {
    336376    int i;
    337     int base=set_->first();
     377    int base=0;
    338378    for ( i=0;i<numberMembers;i++) {
    339379      if (weights[i] >= separator_) {
     
    341381      } else {
    342382        for (int k=0;k<numberLinks;k++) {
    343           int iColumn = base+k;
     383          int iColumn = which[base+k];
    344384          solver->setColUpper(iColumn,0.0);
    345385        }
     
    359399  int numberLinks = set_->numberLinks();
    360400  const double * weights = set_->weights();
     401  const int * which = set_->which();
    361402  OsiSolverInterface * solver = model_->solver();
    362403  const double * upper = solver->getColUpper();
     
    366407  int numberOther=0;
    367408  int i;
    368   int base=set_->first();
     409  int base=0;
    369410  for ( i=0;i<numberMembers;i++) {
    370411    for (int k=0;k<numberLinks;k++) {
    371       int iColumn = base+k;
     412      int iColumn = which[base+k];
    372413      double bound = upper[iColumn];
    373414      if (bound) {
     
    379420  }
    380421  // *** for way - up means fix all those in down section
    381   base=set_->first();
     422  base=0;
    382423  if (way_<0) {
    383424    printf("SOS Down");
    384425    for ( i=0;i<numberMembers;i++) {
     426      if (weights[i] > separator_)
     427        break;
    385428      for (int k=0;k<numberLinks;k++) {
    386         int iColumn = base+k;
     429        int iColumn = which[base+k];
    387430        double bound = upper[iColumn];
    388         if (weights[i] > separator_)
    389           break;
    390         else if (bound)
     431        if (bound)
    391432          numberOther++;
    392433      }
     
    396437    for (;i<numberMembers;i++) {
    397438      for (int k=0;k<numberLinks;k++) {
    398         int iColumn = base+k;
     439        int iColumn = which[base+k];
    399440        double bound = upper[iColumn];
    400441        if (bound)
     
    406447    printf("SOS Up");
    407448    for ( i=0;i<numberMembers;i++) {
     449      if (weights[i] >= separator_)
     450        break;
    408451      for (int k=0;k<numberLinks;k++) {
    409         int iColumn = base+k;
     452        int iColumn = which[base+k];
    410453        double bound = upper[iColumn];
    411         if (weights[i] >= separator_)
    412           break;
    413         else if (bound)
     454        if (bound)
    414455          numberFixed++;
    415456      }
     
    419460    for (;i<numberMembers;i++) {
    420461      for (int k=0;k<numberLinks;k++) {
    421         int iColumn = base+k;
     462        int iColumn = which[base+k];
    422463        double bound = upper[iColumn];
    423464        if (bound)
     
    428469  }
    429470  assert ((numberFixed%numberLinks)==0);
    430   assert ((numberFixed%numberOther)==0);
     471  assert ((numberOther%numberLinks)==0);
    431472  printf(" - at %g, free range %d (%g) => %d (%g), %d would be fixed, %d other way\n",
    432473         separator_,first,weights[first],last,weights[last],numberFixed/numberLinks,
  • branches/devel/Cbc/examples/CbcBranchLink.hpp

    r129 r424  
    2121      apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through
    2222      numberInSet-1.  The length of weights array is numberInSet.
    23       For this simple version the variables in matrix are the numberInSet*numberLink
     23      For this constructor the variables in matrix are the numberInSet*numberLink
    2424      starting at first. If weights null then 0,1,2..
    2525  */
    2626  CbcLink (CbcModel * model, int numberMembers,
    2727           int numberLinks, int first,
     28           const double * weights, int setNumber);
     29  /** Useful constructor - A valid solution is if all variables are zero
     30      apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through
     31      numberInSet-1.  The length of weights array is numberInSet.
     32      For this constructor the variables are given by list - grouped.
     33      If weights null then 0,1,2..
     34  */
     35  CbcLink (CbcModel * model, int numberMembers,
     36           int numberLinks, const int * which,
    2837           const double * weights, int setNumber);
    2938 
     
    5665  {return numberLinks_;};
    5766
    58   /// First variable in matrix
    59   inline int first() const
    60   {return first_;};
     67  /// Which variables
     68  inline const int * which() const
     69  {return which_;};
    6170
    6271  /** Array of weights */
     
    7483  /// Number of links
    7584   int numberLinks_;
    76   /// First member
    77   int first_;
     85  /// Members
     86  int * which_;
    7887};
    7988/** Branching object for Special ordered sets
  • branches/devel/Cbc/examples/CbcCompareUser.cpp

    r180 r424  
    8282{
    8383}
    84 
     84// For moment go to default
     85#if 0
    8586// Returns true if y better than x
    8687bool
     
    179180  }
    180181}
     182#else
     183
     184// Returns true if y better than x
     185bool
     186CbcCompareUser::test (CbcNode * x, CbcNode * y)
     187{
     188  if (weight_==-1.0&&(y->depth()>7||x->depth()>7)) {
     189    // before solution
     190    /* printf("x %d %d %g, y %d %d %g\n",
     191       x->numberUnsatisfied(),x->depth(),x->objectiveValue(),
     192       y->numberUnsatisfied(),y->depth(),y->objectiveValue()); */
     193    if (x->numberUnsatisfied() > y->numberUnsatisfied()) {
     194      return true;
     195    } else if (x->numberUnsatisfied() < y->numberUnsatisfied()) {
     196      return false;
     197    } else {
     198      int testX = x->depth();
     199      int testY = y->depth();
     200      if (testX!=testY)
     201        return testX < testY;
     202      else
     203        return equalityTest(x,y); // so ties will be broken in consistent manner
     204    }
     205  } else {
     206    // after solution
     207    double weight = CoinMax(weight_,0.0);
     208    double testX =  x->objectiveValue()+ weight*x->numberUnsatisfied();
     209    double testY = y->objectiveValue() + weight*y->numberUnsatisfied();
     210    if (testX!=testY)
     211      return testX > testY;
     212    else
     213      return equalityTest(x,y); // so ties will be broken in consistent manner
     214  }
     215}
     216// This allows method to change behavior as it is called
     217// after each solution
     218void
     219CbcCompareUser::newSolution(CbcModel * model,
     220                               double objectiveAtContinuous,
     221                               int numberInfeasibilitiesAtContinuous)
     222{
     223  if (model->getSolutionCount()==model->getNumberHeuristicSolutions()&&
     224      model->getSolutionCount()<5&&model->getNodeCount()<500)
     225    return; // solution was got by rounding
     226  // set to get close to this solution
     227  double costPerInteger =
     228    (model->getObjValue()-objectiveAtContinuous)/
     229    ((double) numberInfeasibilitiesAtContinuous);
     230  weight_ = 0.95*costPerInteger;
     231  saveWeight_ = 0.95*weight_;
     232  numberSolutions_++;
     233  if (numberSolutions_>5)
     234    weight_ =0.0; // this searches on objective
     235}
     236// This allows method to change behavior
     237bool
     238CbcCompareUser::every1000Nodes(CbcModel * model, int numberNodes)
     239{
     240  double saveWeight=weight_;
     241  int numberNodes1000 = numberNodes/1000;
     242  if (numberNodes>10000) {
     243    weight_ =0.0; // this searches on objective
     244    // but try a bit of other stuff
     245    if ((numberNodes1000%4)==1)
     246      weight_=saveWeight_;
     247  } else if (numberNodes==1000&&weight_==-2.0) {
     248    weight_=-1.0; // Go to depth first
     249  }
     250  // get size of tree
     251  treeSize_ = model->tree()->size();
     252  if (treeSize_>10000) {
     253    int n1 = model->solver()->getNumRows()+model->solver()->getNumCols();
     254    int n2 = model->numberObjects();
     255    double size = n1*0.1 + n2*2.0;
     256    // set weight to reduce size most of time
     257    if (treeSize_*size>5.0e7)
     258      weight_=-1.0;
     259    else if ((numberNodes1000%4)==0&&treeSize_*size>1.0e6)
     260      weight_=-1.0;
     261    else if ((numberNodes1000%4)==1)
     262      weight_=0.0;
     263    else
     264      weight_=saveWeight_;
     265  }
     266  return (weight_!=saveWeight);
     267}
     268// Returns true if wants code to do scan with alternate criterion
     269bool
     270CbcCompareUser::fullScan() const
     271{
     272  return false;
     273}
     274// This is alternate test function
     275bool
     276CbcCompareUser::alternateTest (CbcNode * x, CbcNode * y)
     277{
     278  // not used
     279  abort();
     280  return false;
     281}
     282#endif
Note: See TracChangeset for help on using the changeset viewer.