예제 #1
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;
}
예제 #2
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;
}