예제 #1
0
// Infeasibility - large is 0.5
double
CbcGeneralDepth::infeasibility(const OsiBranchingInformation * /*info*/,
                               int &/*preferredWay*/) const
{
    whichSolution_ = -1;
    // should use genuine OsiBranchingInformation usefulInfo = model_->usefulInformation();
    // for now assume only called when correct
    //if (usefulInfo.depth_>=4&&!model_->parentModel()
    //     &&(usefulInfo.depth_%2)==0) {
    if (true) {
        OsiSolverInterface * solver = model_->solver();
        OsiClpSolverInterface * clpSolver
        = dynamic_cast<OsiClpSolverInterface *> (solver);
        if (clpSolver) {
	  if ((model_->moreSpecialOptions()&33554432)==0) {
            ClpNodeStuff * info = nodeInfo_;
            info->integerTolerance_ = model_->getIntegerTolerance();
            info->integerIncrement_ = model_->getCutoffIncrement();
            info->numberBeforeTrust_ = model_->numberBeforeTrust();
            info->stateOfSearch_ = model_->stateOfSearch();
            // Compute "small" change in branch
            int nBranches = model_->getIntParam(CbcModel::CbcNumberBranches);
            if (nBranches) {
                double average = model_->getDblParam(CbcModel::CbcSumChange) / static_cast<double>(nBranches);
                info->smallChange_ =
                    CoinMax(average * 1.0e-5, model_->getDblParam(CbcModel::CbcSmallestChange));
                info->smallChange_ = CoinMax(info->smallChange_, 1.0e-8);
            } else {
                info->smallChange_ = 1.0e-8;
            }
            int numberIntegers = model_->numberIntegers();
            double * down = new double[numberIntegers];
            double * up = new double[numberIntegers];
            int * priority = new int[numberIntegers];
            int * numberDown = new int[numberIntegers];
            int * numberUp = new int[numberIntegers];
            int * numberDownInfeasible = new int[numberIntegers];
            int * numberUpInfeasible = new int[numberIntegers];
            model_->fillPseudoCosts(down, up, priority, numberDown, numberUp,
                                    numberDownInfeasible, numberUpInfeasible);
            info->fillPseudoCosts(down, up, priority, numberDown, numberUp,
                                  numberDownInfeasible,
                                  numberUpInfeasible, numberIntegers);
            info->presolveType_ = 1;
            delete [] down;
            delete [] up;
            delete [] numberDown;
            delete [] numberUp;
            delete [] numberDownInfeasible;
            delete [] numberUpInfeasible;
            bool takeHint;
            OsiHintStrength strength;
            solver->getHintParam(OsiDoReducePrint, takeHint, strength);
            ClpSimplex * simplex = clpSolver->getModelPtr();
            int saveLevel = simplex->logLevel();
            if (strength != OsiHintIgnore && takeHint && saveLevel == 1)
                simplex->setLogLevel(0);
            clpSolver->setBasis();
            whichSolution_ = simplex->fathomMany(info);
            //printf("FAT %d nodes, %d iterations\n",
            //info->numberNodesExplored_,info->numberIterations_);
            //printf("CbcBranch %d rows, %d columns\n",clpSolver->getNumRows(),
            //     clpSolver->getNumCols());
            model_->incrementExtra(info->numberNodesExplored_,
                                   info->numberIterations_);
            // update pseudo costs
            double smallest = 1.0e50;
            double largest = -1.0;
            OsiObject ** objects = model_->objects();
#ifndef NDEBUG
            const int * integerVariable = model_->integerVariable();
#endif
            for (int i = 0; i < numberIntegers; i++) {
#ifndef NDEBUG
                CbcSimpleIntegerDynamicPseudoCost * obj =
                    dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
                assert (obj && obj->columnNumber() == integerVariable[i]);
#else
                CbcSimpleIntegerDynamicPseudoCost * obj =
                    static_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
#endif
                if (info->numberUp_[i] > 0) {
                    if (info->downPseudo_[i] > largest)
                        largest = info->downPseudo_[i];
                    if (info->downPseudo_[i] < smallest)
                        smallest = info->downPseudo_[i];
                    if (info->upPseudo_[i] > largest)
                        largest = info->upPseudo_[i];
                    if (info->upPseudo_[i] < smallest)
                        smallest = info->upPseudo_[i];
                    obj->updateAfterMini(info->numberDown_[i],
                                         info->numberDownInfeasible_[i],
                                         info->downPseudo_[i],
                                         info->numberUp_[i],
                                         info->numberUpInfeasible_[i],
                                         info->upPseudo_[i]);
                }
            }
            //printf("range of costs %g to %g\n",smallest,largest);
            simplex->setLogLevel(saveLevel);
            numberNodes_ = info->nNodes_;
	  } else {
	    // Try diving
	    // See if any diving heuristics set to do dive+save
	    CbcHeuristicDive * dive=NULL;
	    for (int i = 0; i < model_->numberHeuristics(); i++) {
	      CbcHeuristicDive * possible = dynamic_cast<CbcHeuristicDive *>(model_->heuristic(i));
	      if (possible&&possible->maxSimplexIterations()==COIN_INT_MAX) {
		// if more than one then rotate later?
		//if (possible->canHeuristicRun()) {
		dive=possible;
		break;
	      }
	    }
	    assert (dive); // otherwise moreSpecial should have been turned off
	    CbcSubProblem ** nodes=NULL;
	    int branchState=dive->fathom(model_,numberNodes_,nodes);
	    if (branchState) {
	      printf("new solution\n");
	      whichSolution_=numberNodes_-1;
	    } else {
	      whichSolution_=-1;
	    }
#if 0
	    if (0) {
	      for (int iNode=0;iNode<numberNodes;iNode++) {
		//tree_->push(nodes[iNode]) ;
	      }
	      assert (node->nodeInfo());
	      if (node->nodeInfo()->numberBranchesLeft()) {
		tree_->push(node) ;
	      } else {
		node->setActive(false);
	      }
	    }
#endif
	    //delete [] nodes;
	    model_->setTemporaryPointer(reinterpret_cast<void *>(nodes));
	    // end try diving
	  }
	  int numberDo = numberNodes_;
	  if (numberDo > 0 || whichSolution_ >= 0) {
	    return 0.5;
	  } else {
	    // no solution
	    return COIN_DBL_MAX; // say infeasible
	  }
        } else {
            return -1.0;
        }
    } else {
        return -1.0;
    }
}
예제 #2
0
// Apply subproblem
void
CbcSubProblem::apply(OsiSolverInterface * solver, int what) const
{
    int i;
    if ((what&1) != 0) {
#ifndef NDEBUG
        int nSame = 0;
#endif
        for (i = 0; i < numberChangedBounds_; i++) {
            int variable = variables_[i];
            int k = variable & 0x3fffffff;
            if ((variable&0x80000000) == 0) {
                // lower bound changing
                //#define CBC_PRINT2
#ifdef CBC_PRINT2
                if (solver->getColLower()[k] != newBounds_[i])
                    printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
#endif
#ifndef NDEBUG
                if ((variable&0x40000000) == 0 && true) {
                    double oldValue = solver->getColLower()[k];
                    assert (newBounds_[i] > oldValue - 1.0e-8);
                    if (newBounds_[i] < oldValue + 1.0e-8) {
#ifdef CBC_PRINT2
                        printf("bad null lower change for column %d - bound %g\n", k, oldValue);
#endif
                        if (newBounds_[i] == oldValue)
                            nSame++;
                    }
                }
#endif
                solver->setColLower(k, newBounds_[i]);
            } else {
                // upper bound changing
#ifdef CBC_PRINT2
                if (solver->getColUpper()[k] != newBounds_[i])
                    printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
#endif
#ifndef NDEBUG
                if ((variable&0x40000000) == 0 && true) {
                    double oldValue = solver->getColUpper()[k];
                    assert (newBounds_[i] < oldValue + 1.0e-8);
                    if (newBounds_[i] > oldValue - 1.0e-8) {
#ifdef CBC_PRINT2
                        printf("bad null upper change for column %d - bound %g\n", k, oldValue);
#endif
                        if (newBounds_[i] == oldValue)
                            nSame++;
                    }
                }
#endif
                solver->setColUpper(k, newBounds_[i]);
            }
        }
#ifndef NDEBUG
#ifdef CBC_PRINT2
        if (nSame && (nSame < numberChangedBounds_ || (what&3) != 3))
            printf("%d changes out of %d redundant %d\n",
                   nSame, numberChangedBounds_, what);
        else if (numberChangedBounds_ && what == 7 && !nSame)
            printf("%d good changes %d\n",
                   numberChangedBounds_, what);
#endif
#endif
    }
#ifdef JJF_ZERO
    if ((what&2) != 0) {
        OsiClpSolverInterface * clpSolver
        = dynamic_cast<OsiClpSolverInterface *> (solver);
        assert (clpSolver);
        //assert (clpSolver->getNumRows()==numberRows_);
        //clpSolver->setBasis(*status_);
        // Current basis
        CoinWarmStartBasis * basis = clpSolver->getPointerToWarmStart();
        printf("BBBB\n");
        basis->print();
        assert (basis->fullBasis());
        basis->applyDiff(status_);
        printf("diff applied %x\n", status_);
        printf("CCCC\n");
        basis->print();
        assert (basis->fullBasis());
#ifndef NDEBUG
        if (!basis->fullBasis())
            printf("Debug this basis!!\n");
#endif
        clpSolver->setBasis(*basis);
    }
#endif
    if ((what&8) != 0) {
        OsiClpSolverInterface * clpSolver
        = dynamic_cast<OsiClpSolverInterface *> (solver);
        assert (clpSolver);
        clpSolver->setBasis(*status_);
        delete status_;
        status_ = NULL;
    }
}