예제 #1
0
/**
 * incremental version of satisfy that allows refinement after blocks are
 * moved.
 *
 *  - move blocks to new positions
 *  - repeatedly merge across most violated constraint until no more
 *    violated constraints exist
 *
 * Note: there is a special case to handle when the most violated constraint
 * is between two variables in the same block.  Then, we must split the block
 * over an active constraint between the two variables.  We choose the
 * constraint with the most negative lagrangian multiplier.
 */
void IncSolver::satisfy() {
#ifdef RECTANGLE_OVERLAP_LOGGING
  ofstream f(LOGFILE,ios::app);
  f<<"satisfy_inc()..."<<endl;
#endif
  splitBlocks();
  long splitCtr = 0;
  Constraint* v = NULL;

  while((v=mostViolated(inactive))&&(v->equality || v->slack() < ZERO_UPPERBOUND)) {
    assert(!v->active);
    Block *lb = v->left->block, *rb = v->right->block;

    if(lb != rb) {
      lb->merge(rb,v);
    }
    else {
      if(lb->isActiveDirectedPathBetween(v->right,v->left)) {
        // cycle found, relax the violated, cyclic constraint
        v->gap = v->slack();
        continue;
      }

      if(splitCtr++>10000) {
        throw "Cycle Error!";
      }

      // constraint is within block, need to split first
      inactive.push_back(lb->splitBetween(v->left,v->right,lb,rb));
      lb->merge(rb,v);
      bs->insert(lb);
    }
  }

#ifdef RECTANGLE_OVERLAP_LOGGING
  f<<"  finished merges."<<endl;
#endif
  bs->cleanup();

  for(unsigned i=0; i<m; i++) {
    v=cs[i];

    if(v->slack() < ZERO_UPPERBOUND) {
      ostringstream s;
      s<<"Unsatisfied constraint: "<<*v;
#ifdef RECTANGLE_OVERLAP_LOGGING
      ofstream f(LOGFILE,ios::app);
      f<<s.str()<<endl;
#endif
      throw s.str().c_str();
    }
  }

#ifdef RECTANGLE_OVERLAP_LOGGING
  f<<"  finished cleanup."<<endl;
  printBlocks();
#endif
}
예제 #2
0
void IncSolver::solve() {
#ifdef RECTANGLE_OVERLAP_LOGGING
	ofstream f(LOGFILE,ios::app);
	f<<"solve_inc()..."<<endl;
#endif
	double lastcost,cost = bs->cost();
	do {
		lastcost=cost;
		satisfy();
		splitBlocks();
		cost = bs->cost();
#ifdef RECTANGLE_OVERLAP_LOGGING
	f<<"  cost="<<cost<<endl;
#endif
	} while(fabs(lastcost-cost)>0.0001);
}