Ejemplo n.º 1
0
/** node comparison method of breadth first search: nodes with lower depth are preferred; in case of a tie, the node
 *  which was created earlier (and therefore has a smaller node number) is preferred */
static
SCIP_DECL_NODESELCOMP(nodeselCompBreadthfirst)
{  /*lint --e{715}*/
   int depth1;
   int depth2;

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

   depth1 = SCIPnodeGetDepth(node1);
   depth2 = SCIPnodeGetDepth(node2);

   /* if depths differ, prefer node with smaller depth */
   if( depth1 < depth2 )
      return -1;
   else if( depth1 > depth2 )
      return +1;
   else
   {
      /* depths are equal; prefer node with smaller number */
      SCIP_Longint number1;
      SCIP_Longint number2;

      number1 = SCIPnodeGetNumber(node1);
      number2 = SCIPnodeGetNumber(node2);
      assert(number1 != number2);

      if( number1 < number2 )
         return -1;
      else
         return +1;
   }
}
Ejemplo n.º 2
0
/** node comparison method of node selector */
static
SCIP_DECL_NODESELCOMP(nodeselCompMaster)
{
   assert(nodesel != NULL);
   assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0);
   assert(scip != NULL);

   if( SCIPnodeGetNumber(node1) < SCIPnodeGetNumber(node2) )
      return 1;
   else
      return -1;
}
Ejemplo n.º 3
0
/** constraint deactivation notification method of constraint handler */
static
SCIP_DECL_CONSDEACTIVE(consDeactiveSamediff)
{  /*lint --e{715}*/
   SCIP_CONSDATA* consdata;
   SCIP_PROBDATA* probdata;

   assert(scip != NULL);
   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
   assert(cons != NULL);

   consdata = SCIPconsGetData(cons);
   assert(consdata != NULL);
   assert(consdata->propagated || SCIPgetNChildren(scip) == 0);

   probdata = SCIPgetProbData(scip);
   assert(probdata != NULL);

   /* check if all variables which are not fixed locally to zero are valid for this constraint/node */
   assert( consdataCheck(scip, probdata, consdata) );

   SCIPdebugMessage("deactivate constraint <%s> at node <%"SCIP_LONGINT_FORMAT"> in depth <%d>: ",
      SCIPconsGetName(cons), SCIPnodeGetNumber(consdata->node), SCIPnodeGetDepth(consdata->node));
   SCIPdebug( consdataPrint(scip, consdata, NULL) );

   /* set the number of propagated variables to current number of variables is SCIP */
   consdata->npropagatedvars = SCIPprobdataGetNVars(probdata);

   /* check if all variables are valid for this constraint */
   assert( consdataCheck(scip, probdata, consdata) );

   return SCIP_OKAY;
}
Ejemplo n.º 4
0
/** constraint activation notification method of constraint handler */
static
SCIP_DECL_CONSACTIVE(consActiveSamediff)
{  /*lint --e{715}*/
   SCIP_CONSDATA* consdata;

   assert(scip != NULL);
   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
   assert(cons != NULL);

   consdata = SCIPconsGetData(cons);
   assert(consdata != NULL);
   assert(consdata->npropagatedvars <= SCIPprobdataGetNVars(SCIPgetProbData(scip)));

   SCIPdebugMessage("activate constraint <%s> at node <%"SCIP_LONGINT_FORMAT"> in depth <%d>: ",
      SCIPconsGetName(cons), SCIPnodeGetNumber(consdata->node), SCIPnodeGetDepth(consdata->node));
   SCIPdebug( consdataPrint(scip, consdata, NULL) );

   if( consdata->npropagatedvars != SCIPprobdataGetNVars(SCIPgetProbData(scip)) )
   {
      SCIPdebugMessage("-> mark constraint to be repropagated\n");
      consdata->propagated = FALSE;
      SCIP_CALL( SCIPrepropagateNode(scip, consdata->node) );
   }

   return SCIP_OKAY;
}
Ejemplo n.º 5
0
/** changes the color of the node to the color of nodes that were marked to be repropagated */
void SCIPvbcMarkedRepropagateNode(
   SCIP_VBC*             vbc,                /**< VBC information */
   SCIP_STAT*            stat,               /**< problem statistics */
   SCIP_NODE*            node                /**< node, that was marked to be repropagated */
   )
{
   assert(node != NULL);

   /* vbc is disabled on probing nodes */
   if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE )
      return;

   /* if the node number is zero, then SCIP is currently in probing and wants to mark a probing node; however this node
    * is not part of the search tree */
   if( SCIPnodeGetNumber(node) > 0 )
      vbcSetColor(vbc, stat, node, SCIP_VBCCOLOR_MARKREPROP);
}
Ejemplo n.º 6
0
/** display constraints */
static
void consdataPrint(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_CONSDATA*        consdata,           /**< constraint data */
   FILE*                 file                /**< file stream */
   )
{
   SCIP_PROBDATA* probdata;
   int* ids;

   probdata = SCIPgetProbData(scip);
   assert(probdata != NULL);

   ids = SCIPprobdataGetIds(probdata);
   assert(ids != NULL);

   SCIPinfoMessage(scip, file, "%s(%d,%d) at node %d\n",
      consdata->type == SAME ? "same" : "diff",
      ids[consdata->itemid1], ids[consdata->itemid2], SCIPnodeGetNumber(consdata->node) );
}
Ejemplo n.º 7
0
/** calculate score of a node given its feature and the policy weight vector */
void SCIPcalcNodeScore(
   SCIP_NODE*         node,
   SCIP_FEAT*         feat,
   SCIP_POLICY*       policy
   )
{
   int offset = SCIPfeatGetOffset(feat);
   int i;
   SCIP_Real score = 0;
   SCIP_Real* weights = policy->weights;
   SCIP_Real* featvals = SCIPfeatGetVals(feat);

   if( (offset + SCIPfeatGetSize(feat)) > policy->size )
      score = 0;
   else
   {
      for( i = 0; i < SCIPfeatGetSize(feat); i++ )
         score += featvals[i] * weights[i+offset];
   }

   SCIPnodeSetScore(node, score);
   SCIPdebugMessage("score of node  #%"SCIP_LONGINT_FORMAT": %f\n", SCIPnodeGetNumber(node), SCIPnodeGetScore(node));
}
Ejemplo n.º 8
0
/** 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;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
/** call writing method */
static
SCIP_RETCODE writeBounds(
   SCIP*                 scip,               /**< SCIP data structure */
   FILE*                 file,               /**< file to write to or NULL */
   SCIP_Bool             writesubmipdualbound/**< write dualbounds of submip roots for all open nodes */
   )
{
   SCIP_NODE** opennodes;
   int nopennodes;
   int n;
   int v;

   assert(scip != NULL);

   nopennodes = -1;

#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

   /* get all open nodes and therefor print all dualbounds */
   for( v = 2; v >= 0; --v )
   {
      SCIP_NODE* node;

      switch( v )
      {
      case 2:
         SCIP_CALL( SCIPgetChildren(scip, &opennodes, &nopennodes) );
         break;
      case 1:
         SCIP_CALL( SCIPgetSiblings(scip, &opennodes, &nopennodes) );
         break;
      case 0:
         SCIP_CALL( SCIPgetLeaves(scip, &opennodes, &nopennodes) );
         break;
      default:
	 assert(0);
	 break;
      }
      assert(nopennodes >= 0);

      /* print all node information */
      for( n = nopennodes - 1; n >= 0 && !SCIPisStopped(scip); --n )
      {
         node = opennodes[n];

         if( writesubmipdualbound )
         {
            SCIP* subscip;
            SCIP_Bool valid;
            SCIP_HASHMAP* varmap;                     /* mapping of SCIP variables to sub-SCIP variables */
            SCIP_VAR** vars;                          /* original problem's variables                    */
            int nvars;
            SCIP_Real submipdb;
	    SCIP_Bool cutoff;

            SCIP_CALL( SCIPcreate(&subscip) );

            SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );

            /* create the variable mapping hash map */
            SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), SCIPcalcHashtableSize(5 * nvars)) );

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

            if( valid )
            {
               SCIP_VAR** branchvars;
               SCIP_Real* branchbounds;
               SCIP_BOUNDTYPE* boundtypes;
               int nbranchvars;
               int size;

               size = SCIPnodeGetDepth(node);

               /* allocate memory for all branching decisions */
               SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) );
               SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) );
               SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) );

               /* we assume that we only have one branching decision at each node */
               SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size );

               /* check if did not have enough memory */
               if( nbranchvars > size )
               {
                  size = nbranchvars;
                  SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) );
                  SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) );
                  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) );

                  /* now getting all information */
                  SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size );
               }

               /* apply all changes to the submip */
               SCIP_CALL( applyDomainChanges(subscip, branchvars, branchbounds, boundtypes, nbranchvars, varmap) );

               /* free memory for all branching decisions */
               SCIPfreeBufferArray(scip, &boundtypes);
               SCIPfreeBufferArray(scip, &branchbounds);
               SCIPfreeBufferArray(scip, &branchvars);

	       /* 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) );

	       /* 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

            /* free hash map */
            SCIPhashmapFree(&varmap);

            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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
/** node selection method of node selector */
static
SCIP_DECL_NODESELSELECT(nodeselSelectBreadthfirst)
{  /*lint --e{715}*/
   assert(nodesel != NULL);
   assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0);
   assert(scip != NULL);
   assert(selnode != NULL);

   /* siblings come before leaves at the same level. Sometimes it can occur that no leaves are left except for children */
   *selnode = SCIPgetBestSibling(scip);
   if( *selnode == NULL )
   {
      *selnode = SCIPgetBestLeaf(scip);
      if( *selnode == NULL )
         *selnode=SCIPgetBestChild(scip);
   }
   if( *selnode != NULL )
   {
      SCIPdebugMessage("Selecting next node number %"SCIP_LONGINT_FORMAT" at depth %d\n", SCIPnodeGetNumber(*selnode), SCIPnodeGetDepth(*selnode));
   }

   return SCIP_OKAY;
}
Ejemplo n.º 13
0
/** 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;
}
Ejemplo n.º 14
0
/** 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;
}