Exemple #1
0
/** separation method of constraint handler for LP solutions */
static
SCIP_DECL_CONSSEPALP(consSepalpStp)
{  /*lint --e{715}*/
   SCIP_CONSHDLRDATA* conshdlrdata;
   int maxcuts;
   int ncuts = 0;
   int i;

   *result = SCIP_DIDNOTRUN;

   conshdlrdata = SCIPconshdlrGetData(conshdlr);
   assert(conshdlrdata != NULL);

   maxcuts = SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 ?
      conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts;

   for( i = 0; i < nconss; ++i )
   {
      SCIP_CONSDATA* consdata;

      consdata = SCIPconsGetData(conss[i]);

      SCIP_CALL( sep_flow(scip, conshdlr, conshdlrdata, consdata, maxcuts, &ncuts) );

      SCIP_CALL( sep_2cut(scip, conshdlr, conshdlrdata, consdata, maxcuts, &ncuts) );
   }

   if( ncuts > 0 )
      *result = SCIP_SEPARATED;

   return SCIP_OKAY;
}
/** branching execution method for not completely fixed pseudo solutions */
static SCIP_DECL_BRANCHEXECPS(branchExecpsnodereopt)
{/*lint --e{715}*/
   assert(branchrule != NULL );
   assert(*result != SCIP_BRANCHED);

   *result = SCIP_DIDNOTRUN;

   if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) )
   {
      assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
           || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)));

      SCIP_CALL( Exec(scip, result) );
   }

   return SCIP_OKAY;
}
/** branching execution method for fractional LP solutions */
static
SCIP_DECL_BRANCHEXECLP(branchExeclpnodereopt)
{/*lint --e{715}*/
   assert(branchrule != NULL );
   assert(*result != SCIP_BRANCHED);

   *result = SCIP_DIDNOTRUN;

   if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) )
   {
      SCIP_VAR** branchcands;
      SCIP_Real* branchcandssol;
      SCIP_Real* branchcandsfrac;
      int nbranchcands;

      SCIP_Bool sbinit;
      SCIP_Real objsimrootlp;

      SCIP_CALL( SCIPgetBoolParam(scip, "reoptimization/strongbranchinginit", &sbinit) );
      SCIP_CALL( SCIPgetRealParam(scip, "reoptimization/objsimrootLP", &objsimrootlp) );

      if( sbinit && SCIPgetCurrentNode(scip) == SCIPgetRootNode(scip)
       && SCIPgetReoptSimilarity(scip, SCIPgetNReoptRuns(scip), SCIPgetNReoptRuns(scip)) <= objsimrootlp ) /* check objsimrootlp */
      {
         /* get branching candidates */
         SCIP_CALL( SCIPgetLPBranchCands(scip, &branchcands, &branchcandssol, &branchcandsfrac, NULL, &nbranchcands, NULL) );

         /* run strong branching initialization */
         if( nbranchcands > 0 )
         {
            SCIP_CALL( SCIPexecRelpscostBranching(scip, TRUE, branchcands, branchcandssol, branchcandsfrac, nbranchcands, FALSE, result) );
            assert(*result == SCIP_DIDNOTRUN || *result == SCIP_CUTOFF || *result == SCIP_REDUCEDDOM);
         }
      }

      if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM)
      {
         assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
              || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)));

         SCIP_CALL( Exec(scip, result) );
      }
   }

   return SCIP_OKAY;
}
Exemple #4
0
/** branching execution method for external candidates */
static
SCIP_DECL_BRANCHEXECEXT(branchExecextPscost)
{  /*lint --e{715}*/
   SCIP_BRANCHRULEDATA* branchruledata;
   SCIP_VAR** externcands;
   SCIP_Real* externcandssol;
   SCIP_Real* externcandsscore;
   int nprioexterncands;
   SCIP_VAR* brvar;
   SCIP_Real brpoint;
   int nchildren;

   assert(branchrule != NULL);
   assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
   assert(scip != NULL);
   assert(result != NULL);
   
   branchruledata = SCIPbranchruleGetData(branchrule);
   assert(branchruledata != NULL);

   SCIPdebugMessage("Execext method of pscost branching\n");
   
   /* get branching candidates */
   SCIP_CALL( SCIPgetExternBranchCands(scip, &externcands, &externcandssol, &externcandsscore, NULL, &nprioexterncands, NULL, NULL, NULL) );
   assert(nprioexterncands > 0);
   
   /* get current update strategy for pseudo costs, if our multiplier rule is 'u' */
   if( branchruledata->strategy == 'u' )
   {
      SCIP_CALL( SCIPgetCharParam(scip, "branching/lpgainnormalize", &branchruledata->updatestrategy) );
   }

   /* select branching variable */
   SCIP_CALL( selectBranchVar(scip, branchrule, externcands, externcandssol, externcandsscore, nprioexterncands, &brvar, &brpoint) );
   
   if( brvar == NULL )
   {
      SCIPerrorMessage("branchExecextPscost failed to select a branching variable from %d candidates\n", nprioexterncands);
      *result = SCIP_DIDNOTRUN;
      return SCIP_OKAY;
   }
  
   assert(SCIPvarIsActive(SCIPvarGetProbvar(brvar)));

   SCIPdebugMessage("branching on variable <%s>: new intervals: [%g, %g] and [%g, %g]\n",
      SCIPvarGetName(brvar), SCIPvarGetLbLocal(brvar), SCIPadjustedVarUb(scip, brvar, brpoint), SCIPadjustedVarLb(scip, brvar, brpoint), SCIPvarGetUbLocal(brvar));

   if( branchruledata->nchildren > 2 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) <= branchruledata->narymaxdepth )
   {
      /* do n-ary branching */
      SCIP_Real minwidth;

      minwidth = 0.0;
      if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(brvar)) && !SCIPisInfinity(scip, SCIPvarGetUbGlobal(brvar)) )
         minwidth = branchruledata->naryminwidth * (SCIPvarGetUbGlobal(brvar) - SCIPvarGetLbGlobal(brvar));

      SCIP_CALL( SCIPbranchVarValNary(scip, brvar, brpoint, branchruledata->nchildren, minwidth, branchruledata->narywidthfactor, &nchildren) );
   }
   else
   {
      /* do binary branching */
      SCIP_CALL( SCIPbranchVarValNary(scip, brvar, brpoint, 2, 0.0, 1.0, &nchildren) );
   }

   if( nchildren > 1 )
   {
      *result = SCIP_BRANCHED;
   }
   else
   {
      /* if there are no children, then variable should have been fixed by SCIPbranchVarVal */
      assert(SCIPisEQ(scip, SCIPvarGetLbLocal(brvar), SCIPvarGetUbLocal(brvar)));
      *result = SCIP_REDUCEDDOM;
   }

   return SCIP_OKAY;
}
/** reduced cost propagation method for an LP solution */
static
SCIP_DECL_PROPEXEC(propExecRedcost)
{  /*lint --e{715}*/
   SCIP_PROPDATA* propdata;
   SCIP_COL** cols;
   SCIP_Real requiredredcost;
   SCIP_Real cutoffbound;
   SCIP_Real lpobjval;
   SCIP_Bool propbinvars;
   SCIP_Bool cutoff;
   int nchgbds;
   int ncols;
   int c;

   *result = SCIP_DIDNOTRUN;

   /* in case we have a zero objective function, we skip the reduced cost propagator */
   if( SCIPgetNObjVars(scip) == 0 )
      return SCIP_OKAY;

   /* propagator can only be applied during solving stage */
   if( SCIPgetStage(scip) < SCIP_STAGE_SOLVING )
      return SCIP_OKAY;

   /* we cannot apply reduced cost fixing, if we want to solve exactly */
   /**@todo implement reduced cost fixing with interval arithmetics */
   if( SCIPisExactSolve(scip) )
      return SCIP_OKAY;

   /* only call propagator, if the current node has an LP */
   if( !SCIPhasCurrentNodeLP(scip) )
      return SCIP_OKAY;

   /* only call propagator, if an optimal LP solution is at hand */
   if( SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
      return SCIP_OKAY;

   /* only call propagator, if the current LP is a valid relaxation */
   if( !SCIPisLPRelax(scip) )
      return SCIP_OKAY;

   /* we cannot apply reduced cost strengthening, if no simplex basis is available */
   if( !SCIPisLPSolBasic(scip) )
      return SCIP_OKAY;

   /* get current cutoff bound */
   cutoffbound = SCIPgetCutoffbound(scip);

   /* reduced cost strengthening can only be applied, if we have a finite cutoff */
   if( SCIPisInfinity(scip, cutoffbound) )
      return SCIP_OKAY;

   /* get LP columns */
   cols = SCIPgetLPCols(scip);
   ncols = SCIPgetNLPCols(scip);

   /* do nothing if the LP has no columns (is empty) */
   if( ncols == 0 )
      return SCIP_OKAY;

   /* get propagator data */
   propdata = SCIPpropGetData(prop);
   assert(propdata != NULL);

   /* chack if all integral variables are fixed and the continuous variables should not be propagated */
   if( !propdata->continuous && SCIPgetNPseudoBranchCands(scip) == 0 )
      return SCIP_OKAY;

   /* get LP objective value */
   lpobjval = SCIPgetLPObjval(scip);

   /* check if binary variables should be propagated */
   propbinvars = (SCIPgetDepth(scip) == 0) || (cutoffbound - lpobjval < 5 * propdata->maxredcost);

   /* skip the propagator if the problem has only binary variables and those should not be propagated */
   if( !propbinvars && SCIPgetNVars(scip) == SCIPgetNBinVars(scip) )
      return SCIP_OKAY;

   *result = SCIP_DIDNOTFIND;
   cutoff = FALSE;
   nchgbds = 0;

   /* compute the required reduced cost which are needed for a binary variable to be fixed */
   requiredredcost = cutoffbound - lpobjval;

   SCIPdebugMessage("lpobjval <%g>, cutoffbound <%g>, max reduced <%g>, propgate binary %u, use implics %u\n",
      lpobjval, cutoffbound, propdata->maxredcost, propbinvars, propdata->usefullimplics);

   /* check reduced costs for non-basic columns */
   for( c = 0; c < ncols && !cutoff; ++c )
   {
      SCIP_VAR* var;

      var = SCIPcolGetVar(cols[c]);

      /* skip continuous variables in case the corresponding parameter is set */
      if( !propdata->continuous && !SCIPvarIsIntegral(var) )
         continue;

      if( SCIPvarIsBinary(var) )
      {
         if( propbinvars )
         {
            if( SCIPgetDepth(scip) == 0 )
            {
               SCIP_CALL( propagateRootRedcostBinvar(scip, propdata, var, cols[c], cutoffbound, &nchgbds) );
            }
            else
            {
               SCIP_CALL( propagateRedcostBinvar(scip, propdata, var, cols[c], requiredredcost, &nchgbds, &cutoff) );
            }
         }
      }
      else
      {
         SCIP_CALL( propagateRedcostVar(scip, var, cols[c], lpobjval, cutoffbound, &nchgbds) );
      }
   }

   if( cutoff )
   {
      *result = SCIP_CUTOFF;

      SCIPdebugMessage("node %"SCIP_LONGINT_FORMAT": detected cutoff\n",
         SCIPnodeGetNumber(SCIPgetCurrentNode(scip)));
   }
   else if( nchgbds > 0 )
   {
      *result = SCIP_REDUCEDDOM;

      SCIPdebugMessage("node %"SCIP_LONGINT_FORMAT": %d bound changes (max redcost <%g>)\n",
         SCIPnodeGetNumber(SCIPgetCurrentNode(scip)) , nchgbds, propdata->maxredcost);
   }

   return SCIP_OKAY;
}
Exemple #6
0
/** node selection method of node selector */
static
SCIP_DECL_NODESELSELECT(nodeselSelectMaster)
{
   SCIP_NODESELDATA* nodeseldata;
   SCIP_NODE** nodes;
   SCIP_CONS* origcons;
   SCIP_CONS* parentorigcons;
   SCIP_CONS* parentmastercons;
   SCIP* origscip;
   int nnodes;
   SCIP_Longint orignodenumber;

   assert(nodesel != NULL);
   assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0);
   assert(scip != NULL);
   assert(selnode != NULL);

   nodeseldata = SCIPnodeselGetData(nodesel);
   assert(nodeseldata != NULL);

   origscip = GCGpricerGetOrigprob(scip);

   *selnode = NULL;

   orignodenumber = SCIPnodeGetNumber(SCIPgetCurrentNode(origscip));

   if( orignodenumber != nodeseldata->lastorignodenumber )
   {
      nodeseldata->lastorignodenumber = orignodenumber;

      origcons = GCGconsOrigbranchGetActiveCons(origscip);
      parentorigcons = GCGconsOrigbranchGetParentcons(origcons);

      /* check whether the current node is the root node and has no parent */
      if( parentorigcons == NULL )
      {
         assert((GCGconsOrigbranchGetNode(origcons) == SCIPgetRootNode(origscip)) || ( GCGconsOrigbranchGetNode(origcons) == NULL) );
         assert(GCGconsOrigbranchGetMastercons(origcons) != NULL);
            assert((GCGconsMasterbranchGetNode(GCGconsOrigbranchGetMastercons(origcons)) == SCIPgetRootNode(scip)) || (GCGconsMasterbranchGetNode(GCGconsOrigbranchGetMastercons(origcons)) == NULL));

         *selnode = SCIPgetRootNode(scip);
         SCIPdebugMessage("selected root node in the master program\n");
      }
      else
      {
         parentmastercons = GCGconsOrigbranchGetMastercons(parentorigcons);
         assert(parentmastercons != NULL);

         assert( (GCGconsOrigbranchGetChild1cons(parentorigcons) == origcons)
            != (GCGconsOrigbranchGetChild2cons(parentorigcons) == origcons));

         /* the original cons is the left child of its parentcons,
            select the left child of the corresponding parentcons in the master*/
         if( GCGconsOrigbranchGetChild1cons(parentorigcons) == origcons )
         {
            assert(GCGconsMasterbranchGetChild1cons(parentmastercons) != NULL);
            assert(GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild1cons(parentmastercons)) != NULL);

            *selnode = GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild1cons(parentmastercons));
            SCIPdebugMessage("Master nodeselector selected node %"SCIP_LONGINT_FORMAT" corresponding to node %"SCIP_LONGINT_FORMAT" in the original program, since the parents (%"SCIP_LONGINT_FORMAT"/o, %"SCIP_LONGINT_FORMAT"/m) are linked\n",
               SCIPnodeGetNumber(*selnode), SCIPnodeGetNumber(GCGconsOrigbranchGetNode(origcons)),
               SCIPnodeGetNumber(GCGconsOrigbranchGetNode(parentorigcons)),
               SCIPnodeGetNumber(GCGconsMasterbranchGetNode(parentmastercons)));
         }

         /* the original cons is the right child of its parentcons,
            select the right child of the corresponding parentcons in the master */
         else
         {
            assert(GCGconsOrigbranchGetChild2cons(parentorigcons) == origcons);
            assert(GCGconsMasterbranchGetChild2cons(parentmastercons) != NULL);
            assert(GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild2cons(parentmastercons)) != NULL);

            *selnode = GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild2cons(parentmastercons));
            SCIPdebugMessage("Master nodeselector selected node %"SCIP_LONGINT_FORMAT" corresponding to node %"SCIP_LONGINT_FORMAT" in the original program, since the parents (%"SCIP_LONGINT_FORMAT"/o, %"SCIP_LONGINT_FORMAT"/m) are linked\n",
               SCIPnodeGetNumber(*selnode), SCIPnodeGetNumber(GCGconsOrigbranchGetNode(origcons)),
               SCIPnodeGetNumber(GCGconsOrigbranchGetNode(parentorigcons)),
               SCIPnodeGetNumber(GCGconsMasterbranchGetNode(parentmastercons)));
         }

      }

      if( *selnode == NULL )
      {
         SCIPerrorMessage("nodesel_master could not find a node corresponding to the current original node!\n");
      }
      assert(*selnode != NULL);

      /* set the dual bound to the lower bound of the corresponding original node */
      SCIP_CALL( SCIPupdateNodeDualbound(scip, *selnode, SCIPgetNodeLowerbound(origscip, SCIPgetCurrentNode(origscip))) );
   }
   else
   {
      SCIPdebugMessage("select random node\n");

      if( SCIPgetNChildren(scip) > 0 )
      {
         SCIP_CALL( SCIPgetChildren(scip, &nodes, &nnodes) );
         *selnode = nodes[0];
      }
      else if( SCIPgetNSiblings(scip) > 0 )
      {
         SCIP_CALL( SCIPgetSiblings(scip, &nodes, &nnodes) );
         *selnode = nodes[0];
      }
      else if( SCIPgetNLeaves(scip) > 0 )
      {
         SCIP_CALL( SCIPgetLeaves(scip, &nodes, &nnodes) );
         *selnode = nodes[0];
      }
   }

#ifndef NDEBUG
   GCGconsOrigbranchCheckConsistency(origscip);
   GCGconsMasterbranchCheckConsistency(scip);
#endif

   return SCIP_OKAY;
}
Exemple #7
0
/** call writing method */
static
SCIP_RETCODE writeBoundsFocusNode(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_EVENTHDLRDATA*   eventhdlrdata       /**< event handler data */
   )
{
   FILE* file;
   SCIP_Bool writesubmipdualbound;
   SCIP_NODE* node;

   assert(scip != NULL);
   assert(eventhdlrdata != NULL);

   file = eventhdlrdata->file;
   writesubmipdualbound = eventhdlrdata->writesubmipdualbound;
   node = SCIPgetCurrentNode(scip);

   /* do not process probing nodes */
   if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE )
      return SCIP_OKAY;

   /* do not process cutoff nodes */
   if( SCIPisInfinity(scip, SCIPgetNodeDualbound(scip, node)) )
      return SCIP_OKAY;

   if( !SCIPisEQ(scip, eventhdlrdata->lastpb, SCIPgetPrimalbound(scip)) )
   {
#ifdef LONGSTATS
      SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip));

      SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip));
      SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip));
#else
      SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip));
#endif
      eventhdlrdata->lastpb = SCIPgetPrimalbound(scip);
   }

   if( writesubmipdualbound )
   {
      SCIP* subscip;
      SCIP_Bool valid;
      SCIP_Real submipdb;
      SCIP_Bool cutoff;

      SCIP_CALL( SCIPcreate(&subscip) );

      submipdb = SCIP_INVALID;
      valid = FALSE;
      cutoff = FALSE;
      SCIP_CALL( SCIPcopy(scip, subscip, NULL, NULL, "__boundwriting", FALSE, FALSE, TRUE, &valid) );

      if( valid )
      {
	 /* do not abort subproblem on CTRL-C */
	 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
	 /* disable output to console */
	 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
	 /* solve only root node */
	 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );

#if 0
	 /* disable heuristics in subscip */
	 SCIP_CALL( SCIPsetHeuristics(subscip, SCIP_PARAMSETTING_OFF, TRUE) );
#endif

	 /* set cutoffbound as objective limit for subscip */
	 SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) );

	 SCIP_CALL( SCIPsolve(subscip) );

	 cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE);
	 submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip);
      }

#ifdef LONGSTATS
      SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : "");
#else
      SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : "");
#endif

      SCIP_CALL( SCIPfree(&subscip) );
   }
   else
   {
#ifdef LONGSTATS
      SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node));
#else
      SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node));
#endif
   }

#ifdef LONGSTATS
   SCIPinfoMessage(scip, file, "\n");
#endif

   return SCIP_OKAY;
}
/** Execute the branching of nodes with additional constraints. */
static
SCIP_RETCODE Exec(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_RESULT*          result              /**< pointer to store the result */
)
{
   SCIP_REOPTNODE* reoptnode;
   SCIP_NODE* curnode;
   SCIP_REOPTTYPE reopttype;
   SCIP_Bool localrestart;
   unsigned int* childids;
   unsigned int curid;
   int naddedconss;
   int nchilds;
   int childnodessize;
   int ncreatednodes;
   int c;


   assert(scip != NULL );
   assert(SCIPisReoptEnabled(scip));

   curnode = SCIPgetCurrentNode(scip);
   assert(curnode != NULL);

   curid = SCIPnodeGetReoptID(curnode);
   assert(curid >= 1 || SCIPgetRootNode(scip) == curnode);

   /* calculate local similarity and delete the induced subtree if the similarity is to low */
   localrestart = FALSE;
   SCIP_CALL( SCIPcheckReoptRestart(scip, curnode, &localrestart) );

   ncreatednodes = 0;

   if( localrestart )
   {
      *result = SCIP_DIDNOTRUN;
      goto TERMINATE;
   }

   SCIPdebugMessage("current node is %lld, ID %u:\n", SCIPnodeGetNumber(curnode), curid);

   /* get the corresponding node of the reoptimization tree */
   reoptnode = SCIPgetReoptnode(scip, curid);
   assert(reoptnode != NULL);
   reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);


   /* The current node is equal to the root and dual reductions were performed. Since the root has a special role
    * within the reoptimiziation we have to split the root node into several nodes and move all stored child nodes to
    * the one representing the root node including all dual reductions as before.
    *
    * @note If the type is infsubtree, there cannot exist a child node and the method SCIPapplyReopt adds a global valid
    * constraint only.
    */
   if( curid == 0 )
   {
      if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
      {
         int ncreatedchilds;

         /* apply the reoptimization at the root node */
         SCIP_CALL( SCIPsplitReoptRoot(scip, &ncreatedchilds, &naddedconss) );

         if( reopttype == SCIP_REOPTTYPE_INFSUBTREE )
         {
            assert(ncreatedchilds == 0);
            assert(naddedconss == 1);

            /* there is nothing to do */
            *result = SCIP_DIDNOTRUN;

            goto TERMINATE;
         }

         assert(reopttype == SCIP_REOPTTYPE_STRBRANCHED);
         assert(ncreatedchilds >= 2);

         ncreatednodes += ncreatedchilds;

         /* We decrease the counter by one because after splitting the root node and moving all children to the node
          * representing the original root with all fixings (caused by dual reductions), we continue reactivating the
          * original children nodes of the root. Thus, the node containing all the fixings can be replaced by the children
          * nodes
          */
         --ncreatednodes;
      }

      goto REVIVE;
   }

   /* if we reach this part of the code the current has to be different to the root node */
   assert(curid >= 1);

  REVIVE:

   /* get the IDs of all child nodes */
   childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
   SCIP_CALL( SCIPallocBufferArray(scip, &childids, childnodessize) );
   SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );

   if( childnodessize < nchilds )
   {
      childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
      SCIP_CALL( SCIPreallocBufferArray(scip, &childids, childnodessize) );
      SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );
   }
   assert(nchilds <= childnodessize);

   naddedconss = 0;

   for(c = 0; c < nchilds; c++)
   {
      SCIP_NODE** childnodes;
      SCIP_Bool success;
      unsigned int childid;
      int ncreatedchilds;

      childid = childids[c];
      assert(childid >= 1);

      SCIPdebugMessage("process child at ID %u\n", childid);

      reoptnode = SCIPgetReoptnode(scip, childid);
      assert(reoptnode != NULL);

      reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);
      ncreatedchilds = 0;

      /* check whether node need to be split */
      if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
      {
         /* by default we assume the node get split into two node (because using a constraint to split the node is
          * the default case
          */
         childnodessize = 2;
      }
      else
      {
         /* we only need to reconstruct the node */
         childnodessize = 1;
      }

      /* allocate buffer */
      SCIP_CALL( SCIPallocBufferArray(scip, &childnodes, childnodessize) );

      /* apply the reoptimization */
      SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
            &naddedconss, childnodessize, &success) );

      if( !success )
      {
         assert(ncreatedchilds > childnodessize);

         /* reallocate buffer memory */
         childnodessize = ncreatedchilds+1;
         SCIP_CALL( SCIPreallocBufferArray(scip, &childnodes, childnodessize) );

         /* apply the reoptimization */
         SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
               &naddedconss, childnodessize, &success) );
      }

      assert(success);

      /* free buffer memory */
      SCIPfreeBufferArray(scip, &childnodes);

      ncreatednodes += ncreatedchilds;
   }

   if( ncreatednodes == 0 )
      *result = SCIP_DIDNOTRUN;
   else
      *result = SCIP_BRANCHED;

   /* free the buffer memory */
   SCIPfreeBufferArray(scip, &childids);

  TERMINATE:

   SCIPdebugMessage("**** finish reoptimizing %d child nodes of node %lld ****\n", ncreatednodes, SCIPnodeGetNumber(curnode));

   return SCIP_OKAY;
}
/** LP solution separation method of separator */
static
SCIP_DECL_SEPAEXECLP(sepaExeclpClosecuts)
{  /*lint --e{715}*/
   SCIP_SEPADATA* sepadata;
   SCIP_Longint currentnodenumber;
   SCIP_Bool isroot;

   assert( sepa != NULL );
   assert( strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0 );
   assert( result != NULL );

   *result = SCIP_DIDNOTRUN;

   /* only call separator, if there are fractional variables */
   if ( SCIPgetNLPBranchCands(scip) == 0 )
      return SCIP_OKAY;

   sepadata = SCIPsepaGetData(sepa);
   assert( sepadata != NULL );

   currentnodenumber = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
   if ( sepadata->discardnode == currentnodenumber )
      return SCIP_OKAY;

   isroot = FALSE;
   if (SCIPgetNNodes(scip) == 0)
      isroot = TRUE;

   /* only separate close cuts in the root if required */
   if ( sepadata->separootonly || isroot )
   {
      SCIP_SOL* point = NULL;

      SCIPdebugMessage("Separation method of closecuts separator.\n");
      *result = SCIP_DIDNOTFIND;

      /* check whether we have to compute a relative interior point */
      if ( sepadata->separelint )
      {
         /* check if previous relative interior point should be forgotten,
          * otherwise it is computed only once and the same point is used for all nodes */
         if ( sepadata->recomputerelint && sepadata->sepasol != NULL )
         {
            SCIP_CALL( SCIPfreeSol(scip, &sepadata->sepasol) );
         }
         if ( sepadata->sepasol == NULL )
         {
            SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, 0, "Computing relative interior point (norm type: %c) ...\n", sepadata->relintnormtype);
            assert(sepadata->relintnormtype == 'o' || sepadata->relintnormtype == 's');
            SCIP_CALL( SCIPcomputeLPRelIntPoint(scip, TRUE, sepadata->inclobjcutoff, sepadata->relintnormtype, &sepadata->sepasol) );
         }
      }
      else
      {
         /* get best solution (NULL if not present) */
         sepadata->sepasol = SCIPgetBestSol(scip);
      }

      /* separate close cuts */
      if ( sepadata->sepasol != NULL )
      {
         SCIPdebugMessage("Generating close cuts ... (combination value: %f)\n", sepadata->sepacombvalue);

         /* generate point to be separated */
         SCIP_CALL( generateCloseCutPoint(scip, sepadata, &point) );

         /* apply a separation round to generated point */
         if ( point != NULL )
         {
            int noldcuts;
            SCIP_Bool delayed;
            SCIP_Bool cutoff;

            noldcuts = SCIPgetNCuts(scip);

            SCIP_CALL( SCIPseparateSol(scip, point, isroot, FALSE, &delayed, &cutoff) );

            SCIP_CALL( SCIPfreeSol(scip, &point) );
            assert( point == NULL );

            /* the cuts can be not violated by the current LP if the computed point is strange */
            SCIP_CALL( SCIPremoveInefficaciousCuts(scip) );

            if ( cutoff )
               *result = SCIP_CUTOFF;
            else
            {
               if ( SCIPgetNCuts(scip) - noldcuts > sepadata->sepathreshold )
               {
                  sepadata->nunsuccessful = 0;
                  *result = SCIP_NEWROUND;
               }
               else
               {
                  if ( SCIPgetNCuts(scip) > noldcuts )
                  {
                     sepadata->nunsuccessful = 0;
                     *result = SCIP_SEPARATED;
                  }
                  else
                     ++sepadata->nunsuccessful;
               }
            }

            SCIPdebugMessage("Separated close cuts: %d (enoughcuts: %d, unsuccessful: %d).\n", SCIPgetNCuts(scip) - noldcuts,
               SCIPgetNCuts(scip) - noldcuts > sepadata->sepathreshold, sepadata->nunsuccessful);

            if ( sepadata->maxunsuccessful >= 0 && sepadata->nunsuccessful > sepadata->maxunsuccessful )
            {
               SCIPdebugMessage("Turn off close cut separation, because of %d unsuccessful calls.\n", sepadata->nunsuccessful);
               sepadata->discardnode = currentnodenumber;
            }
         }
      }
   }

   return SCIP_OKAY;
}
Exemple #10
0
/** checks whether given row is valid for the debugging solution */
SCIP_RETCODE SCIPdebugCheckRow(
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_ROW*             row                 /**< row to check for validity */
   )
{
   SCIP_COL** cols;
   SCIP_Real* vals;
   SCIP_Real lhs;
   SCIP_Real rhs;
   int nnonz;
   int i;
   SCIP_Real minactivity;
   SCIP_Real maxactivity;
   SCIP_Real solval;

   assert(set != NULL);
   assert(row != NULL);

   /* check if we are in the original problem and not in a sub MIP */
   if( !isSolutionInMip(set) )
      return SCIP_OKAY;

   /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
   if( debugSolIsAchieved(set) )
      return SCIP_OKAY;

   /* if the row is only locally valid, check whether the debugging solution is contained in the local subproblem */
   if( SCIProwIsLocal(row) )
   {
      SCIP_Bool solcontained;

      SCIP_CALL( isSolutionInNode(SCIPblkmem(set->scip), set, SCIPgetCurrentNode(set->scip), &solcontained) );
      if( !solcontained )
         return SCIP_OKAY;
   }

   cols = SCIProwGetCols(row);
   vals = SCIProwGetVals(row);
   nnonz = SCIProwGetNNonz(row);
   lhs = SCIProwGetLhs(row);
   rhs = SCIProwGetRhs(row);

   /* calculate row's activity on debugging solution */
   minactivity = SCIProwGetConstant(row);
   maxactivity = minactivity;
   for( i = 0; i < nnonz; ++i )
   {
      SCIP_VAR* var;

      /* get solution value of variable in debugging solution */
      var = SCIPcolGetVar(cols[i]);
      SCIP_CALL( getSolutionValue(set, var, &solval) );

      if( solval != SCIP_UNKNOWN ) /*lint !e777*/
      {
         minactivity += vals[i] * solval;
         maxactivity += vals[i] * solval;
      }
      else if( vals[i] > 0.0 )
      {
         minactivity += vals[i] * SCIPvarGetLbGlobal(var);
         maxactivity += vals[i] * SCIPvarGetUbGlobal(var);
      }
      else if( vals[i] < 0.0 )
      {
         minactivity += vals[i] * SCIPvarGetUbGlobal(var);
         maxactivity += vals[i] * SCIPvarGetLbGlobal(var);
      }
   }
   SCIPdebugMessage("debugging solution on row <%s>: %g <= [%g,%g] <= %g\n",
      SCIProwGetName(row), lhs, minactivity, maxactivity, rhs);

   /* check row for violation */
   if( SCIPsetIsFeasLT(set, maxactivity, lhs) || SCIPsetIsFeasGT(set, minactivity, rhs) )
   {
      printf("***** debug: row <%s> violates debugging solution (lhs=%.15g, rhs=%.15g, activity=[%.15g,%.15g], local=%d)\n",
         SCIProwGetName(row), lhs, rhs, minactivity, maxactivity, SCIProwIsLocal(row));
      SCIProwPrint(row, NULL);

      /* output row with solution values */
      printf("\n\n");
      printf("***** debug: violated row <%s>:\n", SCIProwGetName(row));
      printf(" %.15g <= %.15g", lhs, SCIProwGetConstant(row));
      for( i = 0; i < nnonz; ++i )
      {
         /* get solution value of variable in debugging solution */
         SCIP_CALL( getSolutionValue(set, SCIPcolGetVar(cols[i]), &solval) );
         printf(" %+.15g<%s>[%.15g]", vals[i], SCIPvarGetName(SCIPcolGetVar(cols[i])), solval);
      }
      printf(" <= %.15g\n", rhs);

      SCIPABORT();
   }

   return SCIP_OKAY;
}