示例#1
0
/** delete problem data */
static
SCIP_DECL_PROBDELORIG(probdelorigLOP)
{  /*lint --e{831} */
   int i, j;

   assert( probdata != NULL );
   assert( *probdata != NULL );

   /* free matrix and release and free variables */
   assert( (*probdata)->W != NULL );
   assert( (*probdata)->vars != NULL );
   for (i = 0; i < (*probdata)->n; ++i)
   {
      for (j = 0; j < (*probdata)->n; ++j)
      {
	 if (j != i)
	    SCIP_CALL( SCIPreleaseVar(scip, &(*probdata)->vars[i][j]) );
      }
      SCIPfreeMemoryArray(scip, &(*probdata)->vars[i]);
      SCIPfreeMemoryArray(scip, &((*probdata)->W[i]));
   }
   SCIPfreeMemoryArray(scip, &(*probdata)->vars);
   SCIPfreeMemoryArray(scip, &((*probdata)->W));

   /* free probdata */
   SCIPfreeMemory(scip, probdata);

   return SCIP_OKAY;
}
示例#2
0
/** frees the memory of the given problem data */
static
SCIP_RETCODE probdataFree(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_PROBDATA**       probdata            /**< pointer to problem data */
   )
{
   int i;

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

   /* release all variables */
   for( i = 0; i < (*probdata)->nvars; ++i )
   {
      SCIP_CALL( SCIPreleaseVar(scip, &(*probdata)->vars[i]) );
   }

   /* release all constraints */
   for( i = 0; i < (*probdata)->nitems; ++i )
   {
      SCIP_CALL( SCIPreleaseCons(scip, &(*probdata)->conss[i]) );
   }

   /* free memory of arrays */
   SCIPfreeMemoryArray(scip, &(*probdata)->vars);
   SCIPfreeMemoryArray(scip, &(*probdata)->conss);
   SCIPfreeMemoryArray(scip, &(*probdata)->weights);
   SCIPfreeMemoryArray(scip, &(*probdata)->ids);

   /* free probdata */
   SCIPfreeMemory(scip, probdata);

   return SCIP_OKAY;
}
示例#3
0
/* reads problem from file */
SCIP_RETCODE SCIPreadDec(
    SCIP*                 scip,               /**< SCIP data structure */
    const char*           filename,           /**< full path and name of file to read, or NULL if stdin should be used */
    SCIP_RESULT*          result              /**< pointer to store the result of the file reading call */
)
{
    SCIP_READER* reader;
    DECINPUT decinput;
    int i;

    if( SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED )
        SCIP_CALL( SCIPtransformProb(scip) );

    reader = SCIPfindReader(scip, READER_NAME);
    assert(reader != NULL);

    /* initialize DEC input data */
    decinput.file = NULL;
    decinput.linebuf[0] = '\0';
    SCIP_CALL( SCIPallocMemoryArray(scip, &decinput.token, DEC_MAX_LINELEN) ); /*lint !e506*/
    decinput.token[0] = '\0';
    SCIP_CALL( SCIPallocMemoryArray(scip, &decinput.tokenbuf, DEC_MAX_LINELEN) ); /*lint !e506*/
    decinput.tokenbuf[0] = '\0';
    for( i = 0; i < DEC_MAX_PUSHEDTOKENS; ++ i )
    {
        SCIP_CALL( SCIPallocMemoryArray(scip, &decinput.pushedtokens[i], DEC_MAX_LINELEN) ); /*lint !e506 !e866*/
    }

    decinput.npushedtokens = 0;
    decinput.linenumber = 0;
    decinput.linepos = 0;
    decinput.section = DEC_START;
    decinput.presolved = FALSE;
    decinput.haspresolvesection = FALSE;
    decinput.nblocks = NOVALUE;
    decinput.blocknr = - 2;
    decinput.haserror = FALSE;

    /* read the file */
    SCIP_CALL( readDECFile(scip, reader, &decinput, filename) );

    /* free dynamically allocated memory */
    SCIPfreeMemoryArray(scip, &decinput.token);
    SCIPfreeMemoryArray(scip, &decinput.tokenbuf);
    for( i = 0; i < DEC_MAX_PUSHEDTOKENS; ++ i )
    {
        SCIPfreeMemoryArray(scip, &decinput.pushedtokens[i]);
    }

    /* evaluate the result */
    if( decinput.haserror )
        return SCIP_READERROR;
    else
    {
        *result = SCIP_SUCCESS;
    }

    return SCIP_OKAY;
}
示例#4
0
/* reads problem from file */
SCIP_RETCODE SCIPreadBlk(
    SCIP*                 scip,               /**< SCIP data structure */
    const char*           filename,           /**< full path and name of file to read, or NULL if stdin should be used */
    SCIP_RESULT*          result              /**< pointer to store the result of the file reading call */
)
{
    SCIP_READER* reader;
    BLKINPUT blkinput;
    int i;

    reader = SCIPfindReader(scip, READER_NAME);
    assert(reader != NULL);

    /* initialize BLK input data */
    blkinput.file = NULL;
    blkinput.linebuf[0] = '\0';
    SCIP_CALL( SCIPallocMemoryArray(scip, &blkinput.token, BLK_MAX_LINELEN) ); /*lint !e506*/
    blkinput.token[0] = '\0';
    SCIP_CALL( SCIPallocMemoryArray(scip, &blkinput.tokenbuf, BLK_MAX_LINELEN) ); /*lint !e506*/
    blkinput.tokenbuf[0] = '\0';
    for( i = 0; i < BLK_MAX_PUSHEDTOKENS; ++i )
    {
        SCIP_CALL( SCIPallocMemoryArray(scip, &blkinput.pushedtokens[i], BLK_MAX_LINELEN) ); /*lint !e506 !e866*/
    }

    blkinput.npushedtokens = 0;
    blkinput.linenumber = 0;
    blkinput.linepos = 0;
    blkinput.section = BLK_START;
    blkinput.presolved = FALSE;
    blkinput.haspresolvesection = FALSE;
    blkinput.nblocks = -1;
    blkinput.blocknr = -2;
    blkinput.haserror = FALSE;

    /* read the file */
    SCIP_CALL( readBLKFile(scip, reader, &blkinput, filename) );

    /* free dynamically allocated memory */
    SCIPfreeMemoryArray(scip, &blkinput.token);
    SCIPfreeMemoryArray(scip, &blkinput.tokenbuf);
    for( i = 0; i < BLK_MAX_PUSHEDTOKENS; ++i )
    {
        SCIPfreeMemoryArray(scip, &blkinput.pushedtokens[i]);
    }

    /* evaluate the result */
    if( blkinput.haserror )
        return SCIP_READERROR;
    else
    {
        *result = SCIP_SUCCESS;
    }

    return SCIP_OKAY;
}
示例#5
0
/** reads problem from file */
SCIP_RETCODE SCIPreadDiff(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_READER*          reader,             /**< the file reader itself */
   const char*           filename,           /**< full path and name of file to read, or NULL if stdin should be used */
   SCIP_RESULT*          result              /**< pointer to store the result of the file reading call */
   )
{  /*lint --e{715}*/
   LPINPUT lpinput;
   int i;

   /* initialize LP input data */
   lpinput.file = NULL;
   lpinput.linebuf[0] = '\0';
   lpinput.probname[0] = '\0';
   lpinput.objname[0] = '\0';
   SCIP_CALL( SCIPallocMemoryArray(scip, &lpinput.token, LP_MAX_LINELEN) ); /*lint !e506*/
   lpinput.token[0] = '\0';
   SCIP_CALL( SCIPallocMemoryArray(scip, &lpinput.tokenbuf, LP_MAX_LINELEN) ); /*lint !e506*/
   lpinput.tokenbuf[0] = '\0';
   for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
   {
      SCIP_CALL( SCIPallocMemoryArray(scip, &(lpinput.pushedtokens[i]), LP_MAX_LINELEN) );  /*lint !e866 !e506*/
   }

   lpinput.npushedtokens = 0;
   lpinput.linenumber = 0;
   lpinput.linepos = 0;
   lpinput.section = LP_START;
   lpinput.objsense = SCIP_OBJSENSE_MINIMIZE;
   lpinput.haserror = FALSE;
   lpinput.comment = FALSE;
   lpinput.endline = FALSE;

   /* read the file */
   SCIP_CALL( readDiffFile(scip, &lpinput, filename) );

   /* free dynamically allocated memory */
   SCIPfreeMemoryArray(scip, &lpinput.token);
   SCIPfreeMemoryArray(scip, &lpinput.tokenbuf);
   for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
   {
      SCIPfreeMemoryArray(scip, &lpinput.pushedtokens[i]);
   }

   /* evaluate the result */
   if( lpinput.haserror )
      return SCIP_READERROR;
   else
   {
      /* set objective sense */
      SCIP_CALL( SCIPsetObjsense(scip, lpinput.objsense) );
      *result = SCIP_SUCCESS;
   }

   return SCIP_OKAY;
}
示例#6
0
/** solving process deinitialization method of variable pricer (called before branch and bound process data is freed) */
static
SCIP_DECL_PRICEREXITSOL(pricerExitsolStp)
{
   SCIP_PRICERDATA* pricerdata;

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

   pricerdata = SCIPpricerGetData(pricer);
   assert(pricerdata != NULL);

   /* free memory */
   SCIPfreeMemoryArray(scip, &(pricerdata->mi));
   SCIPfreeMemoryArray(scip, &(pricerdata->pi));
   SCIPfreeMemoryArray(scip, &pricerdata->ncreatedvars);

   return SCIP_OKAY;
}
示例#7
0
/** deletes the transformed problem */
static
SCIP_DECL_PROBDELTRANS(probdeltransColoring)
{
   int i;

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

   /* relese constraints and free array for constraints */
   for ( i = 0; i < tcliqueGetNNodes((*probdata)->graph); i++)
   {
      SCIP_CALL( SCIPreleaseCons(scip, &((*probdata)->constraints[i])) );
   }
   SCIPfreeMemoryArray(scip, &((*probdata)->constraints));

   /* free the arrays for the stable sets and relese the related variables */
   for ( i = (*probdata)->nstablesets-1; i >= 0; i-- )
   {
      SCIPfreeBlockMemoryArray(scip, &((*probdata)->stablesets[i]), (*probdata)->stablesetlengths[i]); /*lint !e866*/
      SCIP_CALL( SCIPreleaseVar(scip, &((*probdata)->stablesetvars[i])) );
   }

   SCIPfreeMemoryArray(scip, &((*probdata)->new2oldnode));
   SCIPfreeMemoryArray(scip, &((*probdata)->deletednodes));
   SCIPfreeMemoryArray(scip, &((*probdata)->stablesetvars));
   SCIPfreeMemoryArray(scip, &((*probdata)->stablesetlengths));
   SCIPfreeMemoryArray(scip, &((*probdata)->stablesets));

   tcliqueFree(&(*probdata)->graph);
   SCIPfreeMemory(scip, probdata);
   return SCIP_OKAY;
}
示例#8
0
/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
static
SCIP_DECL_CONSEXITSOL(consExitsolOrigbranch)
{  /*lint --e{715}*/
   SCIP_CONSHDLRDATA* conshdlrData;

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

   conshdlrData = SCIPconshdlrGetData(conshdlr);
   assert(conshdlrData != NULL);
   assert(conshdlrData->nstack <= 1);
   SCIPdebugMessage("exiting solution process branch orig constraint handler\n");

   /* free stack */
   SCIPfreeMemoryArray(scip, &conshdlrData->stack);
   conshdlrData->stack = NULL;

   return SCIP_OKAY;
}
示例#9
0
static
SCIP_DECL_PROBDELORIG(probdelorigColoring)
{
   int i;

   assert(probdata != NULL);
   assert(*probdata != NULL);
  
   SCIPfreeMemoryArray(scip, &((*probdata)->new2oldnode));
   SCIPfreeMemoryArray(scip, &((*probdata)->deletednodes));  

   for ( i = (*probdata)->nstablesets-1; i >= 0; i-- )
   {
      SCIPfreeBlockMemoryArray(scip, &((*probdata)->stablesets[i]), (*probdata)->stablesetlengths[i]); /*lint !e866*/
      SCIP_CALL( SCIPreleaseVar(scip, &((*probdata)->stablesetvars[i])) );
   }
   SCIPfreeMemoryArray(scip, &((*probdata)->stablesetvars));
   SCIPfreeMemoryArray(scip, &((*probdata)->stablesetlengths));
   SCIPfreeMemoryArray(scip, &((*probdata)->stablesets));

   /* release Constraints */
   for ( i = 0; i < tcliqueGetNNodes((*probdata)->graph); i++ )
   {
      SCIP_CALL( SCIPreleaseCons(scip, &((*probdata)->constraints[i])) );
   }
   SCIPfreeMemoryArray(scip, &((*probdata)->constraints));   

   /* free memory used for graph */
   tcliqueFree(&((*probdata)->graph));
   tcliqueFree(&((*probdata)->oldgraph));

   /* free probdata */
   SCIPfreeMemory(scip, probdata);

   return SCIP_OKAY;
}
示例#10
0
文件: reader_cip.c 项目: gorhan/LFOS
/** read constraint */
static
SCIP_RETCODE getConstraint(
   SCIP*                 scip,               /**< SCIP data structure */
   CIPINPUT*             cipinput,           /**< CIP parsing data */
   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
   SCIP_Bool             dynamic,            /**< Is constraint subject to aging?
                                              *   Usually set to FALSE. Set to TRUE for own cuts which
                                              *   are separated as constraints. */
   SCIP_Bool             removable           /**< should the relaxation be removed from the LP due to aging or cleanup?
                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
   )
{
   SCIP_CONS* cons;
   char* buf;
   char* copybuf;
   SCIP_RETCODE retcode;
   SCIP_Bool separate;
   SCIP_Bool enforce;
   SCIP_Bool check;
   SCIP_Bool propagate;
   SCIP_Bool local;
   SCIP_Bool modifiable;
   SCIP_Bool success;
   int len;

   buf = cipinput->strbuf;

   if( strncmp(buf, "END", 3) == 0 )
   {
      cipinput->section = CIP_END;
      return SCIP_OKAY;
   }

   SCIPdebugMessage("parse constraints in line %d\n", cipinput->linenumber);

   separate = TRUE;
   enforce = TRUE;
   check = TRUE;
   propagate = TRUE;
   local = FALSE;
   modifiable = FALSE;

   /* get length of line and check for correct ending of constraint line */
   len = (int)strlen(buf);
   if( len < 1 )
   {
      SCIPerrorMessage("syntax error: expected constraint in line %d.\n", cipinput->linenumber);
      cipinput->haserror = TRUE;
      return SCIP_OKAY;
   }
   if ( buf[len - 1] != ';' )
   {
      SCIPerrorMessage("syntax error: line has to end with ';' (line: %d)\n", cipinput->linenumber);
      cipinput->haserror = TRUE;
      return SCIP_OKAY;
   }

   /* copy buffer for working purpose */
   SCIP_CALL( SCIPduplicateMemoryArray(scip, &copybuf, buf, len) );
   copybuf[len - 1] = '\0';

   /* parse the constraint */
   retcode = SCIPparseCons(scip, &cons, copybuf,
      initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE, &success);

   /* free temporary buffer */
   SCIPfreeMemoryArray(scip, &copybuf);

   SCIP_CALL( retcode );

   if( !success )
   {
      SCIPerrorMessage("syntax error when reading constraint (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf);
      cipinput->haserror = TRUE;
      return SCIP_OKAY;
   }

   SCIP_CALL( SCIPaddCons(scip, cons) );
   SCIPdebugPrintCons(scip, cons, NULL);
   SCIP_CALL( SCIPreleaseCons(scip, &cons) );

   return SCIP_OKAY;
}
示例#11
0
/** method for either Farkas or Redcost pricing */
static
SCIP_RETCODE pricing(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_PRICER*          pricer,             /**< pricer */
   SCIP_Real*            lowerbound,         /**< lowerbound pointer */
   SCIP_Bool             farkas              /**< TRUE: Farkas pricing; FALSE: Redcost pricing */
   )
{
   SCIP_PRICERDATA* pricerdata; /* the data of the pricer */
   SCIP_PROBDATA* probdata;
   GRAPH* graph;
   SCIP_VAR* var;
   PATH* path;
   SCIP_Real* edgecosts;  /* edgecosts of the current subproblem */
   char varname[SCIP_MAXSTRLEN];
   SCIP_Real newlowerbound = -SCIPinfinity(scip);
   SCIP_Real redcost;   /* reduced cost */
   int tail;
   int e;
   int t;
   int i;

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

   /* get pricer data */
   pricerdata = SCIPpricerGetData(pricer);
   assert(pricerdata != NULL);

   /* get problem data */
   probdata = SCIPgetProbData(scip);
   assert(probdata != NULL);

   SCIPdebugMessage("solstat=%d\n", SCIPgetLPSolstat(scip));

   if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
      newlowerbound = SCIPgetSolTransObj(scip, NULL);

   SCIPdebug( SCIP_CALL( SCIPprintSol(scip, NULL, NULL, FALSE) ) );

# if 0
   if ( pricerdata->lowerbound <= 4 )
   {
      char label[SCIP_MAXSTRLEN];
      (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "X%g.gml", pricerdata->lowerbound);
      SCIP_CALL( SCIPprobdataPrintGraph(scip, label , NULL, TRUE) );
      pricerdata->lowerbound++;
   }
#endif
   /* get the graph*/
   graph = SCIPprobdataGetGraph(probdata);

   /* get dual solutions and save them in mi and pi */
   for( t = 0; t < pricerdata->realnterms; ++t )
   {
      if( farkas )
      {
	 pricerdata->mi[t] = SCIPgetDualfarkasLinear(scip, pricerdata->pathcons[t]);
      }
      else
      {
         pricerdata->mi[t] = SCIPgetDualsolLinear(scip, pricerdata->pathcons[t]);
         assert(!SCIPisNegative(scip, pricerdata->mi[t]));
      }
   }

   for( e = 0; e < pricerdata->nedges; ++e )
   {
      if( !pricerdata->bigt )
      {
         for( t = 0; t < pricerdata->realnterms; ++t )
         {
            if( farkas )
	    {
               pricerdata->pi[t * pricerdata->nedges + e] = SCIPgetDualfarkasLinear(
                  scip, pricerdata->edgecons[t * pricerdata->nedges + e]);
	    }
            else
	    {
               pricerdata->pi[t * pricerdata->nedges + e] = SCIPgetDualsolLinear(
                  scip, pricerdata->edgecons[t * pricerdata->nedges + e]);
	    }
         }
      }
      else
      {
         if( farkas )
	 {
	    pricerdata->pi[e] = SCIPgetDualfarkasLinear(
               scip, pricerdata->edgecons[e]);
	 }
	 else
	 {
	    pricerdata->pi[e] = SCIPgetDualsolLinear(
               scip, pricerdata->edgecons[e]);
	 }
      }
   }

   SCIP_CALL( SCIPallocMemoryArray(scip, &path, graph->knots) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &edgecosts, pricerdata->nedges) );

   if( pricerdata->bigt )
   {
      for( e = 0; e < pricerdata->nedges; ++e )
      {
         edgecosts[e] = (-pricerdata->pi[e]);
      }
   }
   /* find shortest r-t (r root, t terminal) paths and create corresponding variables iff reduced cost < 0 */
   for( t = 0; t < pricerdata->realnterms; ++t )
   {
      for( e = 0; e < pricerdata->nedges; ++e )
      {
	 if( !pricerdata->bigt )
	 {
            edgecosts[e] = (-pricerdata->pi[t * pricerdata->nedges + e]);
	 }

         assert(!SCIPisNegative(scip, edgecosts[e]));
      }

      for( i = 0; i < graph->knots; i++ )
         graph->mark[i] = 1;

      graph_path_exec(scip, graph, FSP_MODE, pricerdata->root, edgecosts, path);

      /* compute reduced cost of shortest path to terminal t */
      redcost = 0.0;
      tail = pricerdata->realterms[t];
      while( tail != pricerdata->root )
      {
         redcost += edgecosts[path[tail].edge];
	 tail = graph->tail[path[tail].edge];
      }
      redcost -= pricerdata->mi[t];

      if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
      {
         newlowerbound += redcost;
      }
      /* check if reduced cost < 0 */
      if( SCIPisNegative(scip, redcost) )
      {
	 /* create variable to the shortest path (having reduced cost < 0) */
         var = NULL;
	 sprintf(varname, "PathVar%d_%d", t, pricerdata->ncreatedvars[t]);
         ++(pricerdata->ncreatedvars[t]);

         SCIP_CALL( SCIPcreateVarBasic(scip, &var, varname, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS) );
         SCIP_CALL( SCIPaddPricedVar(scip, var, -redcost) );
         tail = pricerdata->realterms[t];
         while( tail != pricerdata->root )
         {
            /* add variable to constraints */
	    if( !pricerdata->bigt )
	    {
	       SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->edgecons[t * pricerdata->nedges + path[tail].edge], var, 1.0) );
	    }
	    else
	    {
	       SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->edgecons[path[tail].edge], var, 1.0) );
	    }

	    tail = graph->tail[path[tail].edge];
         }
         SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->pathcons[t], var, 1.0) );
      }
   }

   if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
      *lowerbound = newlowerbound;

   SCIPfreeMemoryArray(scip, &edgecosts);
   SCIPfreeMemoryArray(scip, &path);

   return SCIP_OKAY;
}
示例#12
0
/* standard "main" method for mex interface */
void mexFunction(
   int                   nlhs,               /* number of expected outputs */
   mxArray*              plhs[],             /* array of pointers to output arguments */
   int                   nrhs,               /* number of inputs */
   const mxArray*        prhs[]              /* array of pointers to input arguments */
   )
{
   SCIP* scip;
   SCIP_VAR** vars;
   SCIP_Real* objs;
   SCIP_Real* lhss;
   SCIP_Real* rhss;
   SCIP_Real* lbs;
   SCIP_Real* ubs;
   SCIP_Real* matrix;
   SCIP_Real* bestsol;
   SCIP_Real* objval;
   char* vartypes;
   char objsense[SCIP_MAXSTRLEN];

   int nvars;
   int nconss;
   int stringsize;
   int i;

   if( SCIPmajorVersion() < 2 )
   {
      mexErrMsgTxt("SCIP versions less than 2.0 are not supported\n");
      return;
   }

   /* initialize SCIP */
   SCIP_CALL_ABORT( SCIPcreate(&scip) );

   /* output SCIP information */
   SCIPprintVersion(scip, NULL);

   /* include default SCIP plugins */
   SCIP_CALL_ABORT( SCIPincludeDefaultPlugins(scip) );

   if( nlhs != 2 || nrhs != 8 )
      mexErrMsgTxt("invalid number of parameters. Call as [bestsol, objval] = matscip(matrix, lhs, rhs, obj, lb, ub, vartype, objsense)\n");

   if( mxIsSparse(prhs[0]) )
      mexErrMsgTxt("sparse matrices are not supported yet"); /* ???????? of course this has to change */

   /* get linear constraint coefficient matrix */
   matrix = mxGetPr(prhs[0]);
   if( matrix == NULL )
      mexErrMsgTxt("matrix must not be NULL");
   if( mxGetNumberOfDimensions(prhs[0]) != 2 )
      mexErrMsgTxt("matrix must have exactly two dimensions");

   /* get dimensions of matrix */
   nconss = mxGetM(prhs[0]);
   nvars = mxGetN(prhs[0]);
   assert(nconss > 0);
   assert(nvars > 0);

   /* get left hand sides of linear constraints */
   lhss = mxGetPr(prhs[1]);
   if( mxGetM(prhs[1]) != nconss )
      mexErrMsgTxt("dimension of left hand side vector does not match matrix dimension");
   assert(lhss != NULL);

   /* get right hand sides of linear constraints */
   rhss = mxGetPr(prhs[2]);
   if( mxGetM(prhs[2]) != nconss )
      mexErrMsgTxt("dimension of right hand side vector does not match matrix dimension");
   assert(rhss != NULL);

   /* get objective coefficients */
   objs = mxGetPr(prhs[3]);
   if( mxGetM(prhs[3]) != nvars )
      mexErrMsgTxt("dimension of objective coefficient vector does not match matrix dimension");

   /* get lower bounds of variables */
   lbs = mxGetPr(prhs[4]);
   if( mxGetM(prhs[4]) != nvars )
      mexErrMsgTxt("dimension of lower bound vector does not match matrix dimension");

   /* get upper bounds of variables */
   ubs = mxGetPr(prhs[5]);
   if( mxGetM(prhs[5]) != nvars )
      mexErrMsgTxt("dimension of upper bound vector does not match matrix dimension");

   /* allocate memory for variable type characters */
   SCIP_CALL_ABORT( SCIPallocMemoryArray(scip, &vartypes, nvars+1) );

   /* get variable types */
   if( mxGetString(prhs[6], vartypes, nvars+1)  != 0 )
      mexErrMsgTxt("Error when parsing variable types, maybe a wrong vector dimension?");

   /* get objective sense */
   stringsize = mxGetNumberOfElements(prhs[7]);
   if( stringsize != 3 )
      mexErrMsgTxt("objective sense must be a three character word: \"max\" or \"min\"");
   if( mxGetString(prhs[7], objsense, stringsize+1) != 0)
      mexErrMsgTxt("Error when parsing objective sense string");
   if( strcmp(objsense,"max") != 0 && strcmp(objsense,"min") != 0 )
      mexErrMsgTxt("objective sense must be either \"max\" or \"min\"");

   /* get output parameters */
   plhs[0] = mxCreateDoubleMatrix(nvars, 1, mxREAL);
   bestsol = mxGetPr(plhs[0]);
   plhs[1] = mxCreateDoubleScalar(mxREAL);
   objval  = mxGetPr(plhs[1]);

   /* create SCIP problem */
   SCIP_CALL_ABORT( SCIPcreateProb(scip, "mex_prob", NULL, NULL, NULL, NULL, NULL, NULL, NULL) );

   /* allocate memory for variable array */
   SCIP_CALL_ABORT( SCIPallocMemoryArray(scip, &vars, nvars) );

   /* create variables */
   for( i = 0; i < nvars; ++i)
   {
      SCIP_VARTYPE vartype;
      char varname[SCIP_MAXSTRLEN];

      /* convert vartype character to SCIP vartype */
      if( vartypes[i] == 'i' )
         vartype = SCIP_VARTYPE_INTEGER;
      else if( vartypes[i] == 'b' )
         vartype = SCIP_VARTYPE_BINARY;
      else if( vartypes[i] == 'c' )
         vartype = SCIP_VARTYPE_CONTINUOUS;
      else
         mexErrMsgTxt("unkown variable type");

      /* variables get canonic names x_i */
      (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", i);

      /* create variable object and add it to SCIP */
      SCIP_CALL_ABORT( SCIPcreateVar(scip, &vars[i], varname, lbs[i], ubs[i], objs[i],
            vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
      assert(vars[i] != NULL);
      SCIP_CALL_ABORT( SCIPaddVar(scip, vars[i]) );
   }

   /* create linear constraints */
   for( i = 0; i < nconss; ++i )
   {
      SCIP_CONS* cons;
      char consname[SCIP_MAXSTRLEN];
      int j;

      /* constraints get canonic names cons_i */
      (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cons_%d", i);

      /* create empty linear constraint */
      SCIP_CALL_ABORT( SCIPcreateConsLinear(scip, &cons, consname, 0, NULL, NULL, lhss[i], rhss[i],
            TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );

      /* add non-zero coefficients to linear constraint */
      for( j = 0; j < nvars; ++j )
      {
         if( !SCIPisFeasZero(scip, matrix[i+j*nconss]) )
         {
            SCIP_CALL_ABORT( SCIPaddCoefLinear(scip, cons, vars[j], matrix[i+j*nconss]) );
         }
      }

      /* add constraint to SCIP and release it */
      SCIP_CALL_ABORT( SCIPaddCons(scip, cons) );
      SCIP_CALL_ABORT( SCIPreleaseCons(scip, &cons) );
   }

   /* set objective sense in SCIP */
   if( strcmp(objsense,"max") == 0)
   {
      SCIP_CALL_ABORT( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) );
   }
   else if( strcmp(objsense,"min") == 0)
   {
      SCIP_CALL_ABORT( SCIPsetObjsense(scip, SCIP_OBJSENSE_MINIMIZE) );
   }
   else
      /* this should have been caught earlier when parsing objsense */
      mexErrMsgTxt("unkown objective sense");

   /* solve SCIP problem */
   SCIP_CALL_ABORT( SCIPsolve(scip) );

   /* if SCIP found a solution, pass it back into MATLAB output parameters */
   if( SCIPgetNSols > 0 )
   {
      SCIP_SOL* scipbestsol;

      /* get incumbent solution vector */
      scipbestsol = SCIPgetBestSol(scip);
      assert(scipbestsol != NULL);

      /* get objective value of incumbent solution */
      *objval = SCIPgetSolOrigObj(scip, scipbestsol);
      assert(!SCIPisInfinity(scip, REALABS(*objval)));

      /* copy solution values into output vector */
      for( i = 0; i < nvars; ++i )
         bestsol[i] = SCIPgetSolVal(scip,scipbestsol,vars[i]);
   }

   /* release variables */
   for( i = 0; i < nvars; ++i )
   {
      SCIP_CALL_ABORT( SCIPreleaseVar(scip, &vars[i]) );
   }

   /* free memory for variable arrays */
   SCIPfreeMemoryArray(scip, &vartypes);
   SCIPfreeMemoryArray(scip, &vars);

   /* deinitialize SCIP */
   SCIP_CALL_ABORT( SCIPfree(&scip) );

   /* check for memory leaks */
   BMScheckEmptyMemory();

   return;
}
示例#13
0
/** read LP in "COL File Format" */  
static
SCIP_RETCODE readCol(
   SCIP*                 scip,               /**< SCIP data structure */   
   const char*           filename            /**< name of the input file */
   )
{
   SCIP_FILE* fp;               /* file-reader */
   char buf[COL_MAX_LINELEN];   /* maximal length of line */
   int nedges;
   int nnodes;
   int line_nr;
   char* char_p;
   char* probname;
   int** edges;
   int i;
   int j;
   int begin;
   int end;
   int nduplicateedges;
   SCIP_Bool duplicateedge;

   
   assert(scip != NULL);
   assert(filename != NULL);
   
   if (NULL == (fp = SCIPfopen(filename, "r")))
   {
      SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
      perror(filename);
      return SCIP_NOFILE;
   }
   
   /* Get problem name from filename and save it */
   SCIPfgets(buf, sizeof(buf), fp);
   i = 1;
   while ( (filename[i] != '/') && (filename[i] != '\0') )
   {
      i++;
   }
   if ( filename[i] != '/' )
   {
      j = i;
      i = -1;
   }
   else
   {
      j = i+1;
      while ( filename[i] == '/' && filename[j] != '\0' )
      {
         j = i+1;
         while ( filename[j] != '\0' )
         {
            j++;
            if ( filename[j] == '/' )
            {
               i = j;
               break;
            }
         }
      }
   }
   
   SCIPallocMemoryArray(scip, &probname, j-i-4);
   strncpy(probname, &filename[i+1], j-i-5);
   probname[j-i-5]= '\0';

   /* Read until information about graph starts */
   line_nr = 0;
   while( !SCIPfeof(fp) && (buf[0] != 'p') )
   {
      SCIPfgets(buf, sizeof(buf), fp);
      line_nr++;
   } 
   /* no graph information in file! */
   if ( SCIPfeof(fp) )
   {
      SCIPerrorMessage("Error! Could not find line starting with 'p'.\n");
      return SCIP_READERROR;
   }
   /* wrong format of the line containig number of nodes and edges */
   if ( buf[2] != 'e' || buf[3] != 'd' || buf[4] != 'g' || buf[5] != 'e' )
   {
      SCIPerrorMessage("Line starting with 'p' must continue with 'edge'!\n");
      return SCIP_READERROR;
   }
   char_p = &buf[6];
   /* if line reads 'edges' (non-standard!), instead of 'edge'. */
   if ( *char_p == 's' )
      ++(char_p);

   /* read out number of nodes and edges, the pointer char_p will be changed */
   nduplicateedges = 0;
   nnodes = getNextNumber(&char_p);
   nedges = getNextNumber(&char_p);
   if ( nnodes <= 0 )
   {
      SCIPerrorMessage("Number of vertices must be positive!\n");
      return SCIP_READERROR;
   }
   if ( nedges < 0 )
   {	  
      SCIPerrorMessage("Number of edges must be nonnegative!\n");
      return SCIP_READERROR;
   }
   /* create array for edges */
   SCIP_CALL( SCIPallocMemoryArray(scip, &edges, nedges) );
   for( i = 0; i < nedges; i++)
   {
      SCIP_CALL( SCIPallocMemoryArray(scip, &(edges[i]), 2) );
   }
   /* fill array for edges */
   i = 0;
   while ( !SCIPfeof(fp) )
   {
      SCIPfgets(buf, sizeof(buf), fp);
      line_nr++;
      if ( buf[0] == 'e')
      {
         duplicateedge = FALSE;
         char_p = &buf[2];
         
         begin = getNextNumber(&char_p);
         end = getNextNumber(&char_p);
         for ( j = 0; j < i; j++)
         {
            if ( ((edges[j][0] == begin) && (edges[j][1] == end))
               || ((edges[j][1] == begin) && (edges[j][0] == end)) )
            {
               duplicateedge = TRUE;
               nduplicateedges++;
               break;
            }
         }
         if ( !duplicateedge )
         {
            if( i >= nedges )
            {
               SCIPerrorMessage("more edges than expected: expected %d many, but got already %d'th (non-duplicate) edge", nedges, i+1);
               return SCIP_READERROR;
            }
            edges[i][0] = begin;
            edges[i][1] = end;
            assert((edges[i][0] > 0) && (edges[i][0] <= nnodes));
            assert((edges[i][1] > 0) && (edges[i][1] <= nnodes));
            i++;
         }
      }
   }
   if( i + nduplicateedges != nedges )
   {
      SCIPerrorMessage("incorrect number of edges: expected %d many, but got %d many\n", nedges, i + nduplicateedges);
      return SCIP_ERROR;
   }

   printf("Read graph: %d nodes, %d edges (%d duplicates)\n", nnodes, nedges, nduplicateedges);

   /* create problem data */
   SCIP_CALL( SCIPcreateProbColoring(scip, probname, nnodes, nedges-nduplicateedges, edges) );

   /* create LP */
   SCIPdebugMessage("Erstelle LP...\n");
   COLORprobSetUpArrayOfCons(scip);

   
   /* activate the pricer */
   SCIP_CALL( SCIPactivatePricer(scip, SCIPfindPricer(scip, "coloring")) );
   SCIP_CALL( SCIPsetObjIntegral(scip) );
   for ( i = nedges-1; i >= 0; i--)
   {
      SCIPfreeMemoryArray(scip, &(edges[i]));
   }
   SCIPfreeMemoryArray(scip, &edges);
   SCIPfreeMemoryArray(scip, &probname);
   SCIPfclose(fp);

   return SCIP_OKAY;
}
示例#14
0
/** reads an BLK file */
static
SCIP_RETCODE readBLKFile(
    SCIP*                 scip,               /**< SCIP data structure */
    SCIP_READER*          reader,             /**< reader data structure */
    BLKINPUT*             blkinput,           /**< BLK reading data */
    const char*           filename            /**< name of the input file */
)
{
    DEC_DECOMP *decdecomp;
    int i;
    int nconss;
    int nblocksread;
    int nvars;
    SCIP_READERDATA* readerdata;
    SCIP_CONS** conss;
    nblocksread = FALSE;

    assert(scip != NULL);
    assert(reader != NULL);
    assert(blkinput != NULL);

    if( SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED )
        SCIP_CALL( SCIPtransformProb(scip) );

    readerdata = SCIPreaderGetData(reader);
    assert(readerdata != NULL);

    readerdata->nlinkingcons = SCIPgetNConss(scip);
    readerdata->nlinkingvars = 0;
    nvars = SCIPgetNVars(scip);
    conss = SCIPgetConss(scip);
    nconss = SCIPgetNConss(scip);

    /* alloc: var -> block mapping */
    SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->varstoblock, nvars) );
    for( i = 0; i < nvars; i ++ )
    {
        readerdata->varstoblock[i] = NOVALUE;
    }

    /* alloc: linkingvar -> blocks mapping */
    SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->linkingvarsblocks, nvars) );
    SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->nlinkingvarsblocks, nvars) );
    BMSclearMemoryArray(readerdata->linkingvarsblocks, nvars);
    BMSclearMemoryArray(readerdata->nlinkingvarsblocks, nvars);

    /* cons -> block mapping */
    SCIP_CALL( SCIPhashmapCreate(&readerdata->constoblock, SCIPblkmem(scip), nconss) );
    for( i = 0; i < SCIPgetNConss(scip); i ++ )
    {
        SCIP_CALL( SCIPhashmapInsert(readerdata->constoblock, conss[i], (void*)(size_t) NOVALUE) );
    }


    /* open file */
    blkinput->file = SCIPfopen(filename, "r");
    if( blkinput->file == NULL )
    {
        SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
        SCIPprintSysError(filename);
        return SCIP_NOFILE;
    }

    /* parse the file */
    blkinput->section = BLK_START;
    while( blkinput->section != BLK_END && !hasError(blkinput) )
    {
        switch( blkinput->section )
        {
        case BLK_START:
            SCIP_CALL( readStart(scip, blkinput) );
            break;

        case BLK_PRESOLVED:
            SCIP_CALL( readPresolved(scip, blkinput) );
            if( blkinput->presolved && SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED )
            {
                assert(blkinput->haspresolvesection);
                /** @bug GCG should be able to presolve the problem first */
                SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "decomposition belongs to the presolved problem, please presolve the problem first.\n");
                goto TERMINATE;
            }
            break;

        case BLK_NBLOCKS:
            SCIP_CALL( readNBlocks(scip, blkinput) );
            if( blkinput->haspresolvesection && !blkinput->presolved && SCIPgetStage(scip) >= SCIP_STAGE_PRESOLVED )
            {
                SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "decomposition belongs to the unpresolved problem, please re-read the problem and read the decomposition without presolving.\n");
                goto TERMINATE;
            }
            if( !blkinput->haspresolvesection )
            {
                SCIPwarningMessage(scip, "decomposition has no presolve section at beginning. The behaviour is undefined. See the FAQ for further information.\n");
            }
            break;

        case BLK_BLOCK:
            if( nblocksread == FALSE )
            {
                /* alloc n vars per block */
                SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->nblockvars, blkinput->nblocks) );
                SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->nblockcons, blkinput->nblocks) );
                SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->blockcons, blkinput->nblocks) );
                for( i = 0; i < blkinput->nblocks; ++i )
                {
                    readerdata->nblockvars[i] = 0;
                    readerdata->nblockcons[i] = 0;
                    SCIP_CALL( SCIPallocMemoryArray(scip, &(readerdata->blockcons[i]), nconss) ); /*lint !e866*/
                }
                nblocksread = TRUE;
            }
            SCIP_CALL( readBlock(scip, blkinput, readerdata) );
            break;

        case BLK_MASTERCONSS:
            SCIP_CALL( readMasterconss(scip, blkinput, readerdata) );
            break;

        case BLK_END: /* this is already handled in the while() loop */
        default:
            SCIPerrorMessage("invalid BLK file section <%d>\n", blkinput->section);
            return SCIP_INVALIDDATA;
        }
    }


    SCIP_CALL( DECdecompCreate(scip, &decdecomp) );

    /* fill decomp */
    SCIP_CALL( fillDecompStruct(scip, blkinput, decdecomp, readerdata) );

    /* add decomp to cons_decomp */
    SCIP_CALL( SCIPconshdlrDecompAddDecdecomp(scip, decdecomp) );

    for( i = 0; i < nvars; ++i )
    {
        assert(readerdata->linkingvarsblocks[i] != NULL || readerdata->nlinkingvarsblocks[i] == 0);
        if( readerdata->nlinkingvarsblocks[i] > 0 )
        {
            SCIPfreeMemoryArray(scip, &readerdata->linkingvarsblocks[i]);
        }
    }

TERMINATE:
    if( nblocksread )
    {
        for( i = blkinput->nblocks - 1; i >= 0; --i )
        {
            SCIPfreeMemoryArray(scip, &(readerdata->blockcons[i]));
        }
        SCIPfreeMemoryArray(scip, &readerdata->blockcons);
        SCIPfreeMemoryArray(scip, &readerdata->nblockcons);
        SCIPfreeMemoryArray(scip, &readerdata->nblockvars);
    }

    SCIPhashmapFree(&readerdata->constoblock);

    SCIPfreeMemoryArray(scip, &readerdata->nlinkingvarsblocks);
    SCIPfreeMemoryArray(scip, &readerdata->linkingvarsblocks);
    SCIPfreeMemoryArray(scip, &readerdata->varstoblock);

    /* close file */
    SCIPfclose(blkinput->file);

    return SCIP_OKAY;
}
示例#15
0
/** fills the whole Decomp struct after the blk file has been read */
static
SCIP_RETCODE fillDecompStruct(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput,           /**< blk reading data */
    DEC_DECOMP*           decomp,             /**< DEC_DECOMP structure to fill */
    SCIP_READERDATA*      readerdata          /**< reader data*/
)
{

    SCIP_HASHMAP* constoblock;
    SCIP_CONS** allcons;

    SCIP_VAR** consvars;
    int i;
    int j;
    int nvars;
    int blocknr;
    int nconss;
    int nblocks;
    SCIP_Bool valid;

    assert(scip != NULL);
    assert(blkinput != NULL);
    assert(readerdata != NULL);

    allcons = SCIPgetConss(scip);
    nvars = SCIPgetNVars(scip);
    nconss = SCIPgetNConss(scip);
    nblocks = blkinput->nblocks;

    DECdecompSetPresolved(decomp, blkinput->presolved);
    DECdecompSetNBlocks(decomp, nblocks);
    DECdecompSetDetector(decomp, NULL);

    DECdecompSetType(decomp, DEC_DECTYPE_ARROWHEAD, &valid);
    assert(valid);

    /* hashmaps */
    SCIP_CALL( SCIPhashmapCreate(&constoblock, SCIPblkmem(scip), nconss) );
    SCIP_CALL( SCIPallocMemoryArray(scip, &consvars, nvars) );

    /* assign constraints to blocks or declare them linking */
    for( i = 0; i < nconss; i ++ )
    {
        SCIP_CONS* cons;

        cons = allcons[i];

        if( SCIPhashmapGetImage(readerdata->constoblock, cons) == (void*) (size_t) LINKINGVALUE )
        {
            SCIP_CALL( SCIPhashmapInsert(constoblock, cons, (void*) (size_t) (nblocks+1)) );

            SCIPdebugMessage("cons %s is linking\n", SCIPconsGetName(cons));
        }
        /* check whether all variables in the constraint belong to one block */
        else
        {
            int nconsvars;

            nconsvars = SCIPgetNVarsXXX(scip, cons);
            assert(nconsvars < nvars);

            SCIP_CALL( SCIPgetVarsXXX(scip, cons, consvars, nvars) );

            blocknr = -1;

            /* find the first unique assignment of a contained variable to a block */
            for( j = 0; j < nconsvars; ++j )
            {
                /* if a contained variables is directly transferred to the master, the constraint is a linking constraint */
                if( readerdata->varstoblock[SCIPvarGetProbindex(consvars[j])] == NOVALUE )
                {
                    blocknr = -1;
                    break;
                }
                /* assign the constraint temporarily to the block of the variable, if it is unique */
                if( blocknr == -1 && readerdata->varstoblock[SCIPvarGetProbindex(consvars[j])] != LINKINGVALUE )
                {
                    blocknr = readerdata->varstoblock[SCIPvarGetProbindex(consvars[j])];
                }
            }
            if( blocknr != -1 )
            {
                int varidx;
                int varblock;

                /* check whether all contained variables are copied into the assigned block;
                 * if not, the constraint is treated as a linking constraint
                 */
                for( j = 0; j < nconsvars; ++j )
                {
                    varidx = SCIPvarGetProbindex(consvars[j]);
                    varblock = readerdata->varstoblock[varidx];
                    assert(varblock != NOVALUE);

                    if( varblock != LINKINGVALUE && varblock != blocknr )
                    {
                        blocknr = -1;
                        break;
                    }
                    else if( varblock == LINKINGVALUE )
                    {
                        int k;

                        for( k = 0; k < readerdata->nlinkingvarsblocks[varidx]; ++k )
                        {
                            if( readerdata->linkingvarsblocks[varidx][k] == blocknr )
                                break;
                        }
                        /* we did not break, so the variable is not assigned to the block */
                        if( k == readerdata->nlinkingvarsblocks[varidx] )
                        {
                            blocknr = -1;
                            break;
                        }
                    }
                }
            }

            if( blocknr == -1 )
            {
                SCIP_CALL( SCIPhashmapInsert(constoblock, cons, (void*) (size_t) (nblocks+1)) );

                SCIPdebugMessage("constraint <%s> is a linking constraint\n",
                                 SCIPconsGetName(cons));
            }
            else
            {
                SCIP_CALL( SCIPhashmapInsert(constoblock, cons, (void*) (size_t) (blocknr+1)) );
                SCIPdebugMessage("constraint <%s> is assigned to block %d\n", SCIPconsGetName(cons), blocknr);
            }
        }
    }
    SCIP_CALL( DECfilloutDecdecompFromConstoblock(scip, decomp, constoblock, nblocks, SCIPgetVars(scip), SCIPgetNVars(scip), SCIPgetConss(scip), SCIPgetNConss(scip), FALSE) );

    SCIPfreeMemoryArray(scip, &consvars);

    return SCIP_OKAY;
}
示例#16
0
/** reduced cost pricing method of variable pricer for feasible LPs */
static
SCIP_DECL_PRICERREDCOST(pricerRedcostBinpacking)
{  /*lint --e{715}*/
   SCIP* subscip;
   SCIP_PRICERDATA* pricerdata;
   SCIP_CONS** conss;
   SCIP_VAR** vars;
   int* ids;
   SCIP_Bool addvar;

   SCIP_SOL** sols;
   int nsols;
   int s;

   int nitems;
   SCIP_Longint capacity;

   SCIP_Real timelimit;
   SCIP_Real memorylimit;

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

   (*result) = SCIP_DIDNOTRUN;

   /* get the pricer data */
   pricerdata = SCIPpricerGetData(pricer);
   assert(pricerdata != NULL);

   capacity = pricerdata->capacity;
   conss = pricerdata->conss;
   ids = pricerdata->ids;
   nitems = pricerdata->nitems;

   /* get the remaining time and memory limit */
   SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
   if( !SCIPisInfinity(scip, timelimit) )
      timelimit -= SCIPgetSolvingTime(scip);
   SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
   if( !SCIPisInfinity(scip, memorylimit) )
      memorylimit -= SCIPgetMemUsed(scip)/1048576.0;

   /* initialize SCIP */
   SCIP_CALL( SCIPcreate(&subscip) );
   SCIP_CALL( SCIPincludeDefaultPlugins(subscip) );

   /* create problem in sub SCIP */
   SCIP_CALL( SCIPcreateProbBasic(subscip, "pricing") );
   SCIP_CALL( SCIPsetObjsense(subscip, SCIP_OBJSENSE_MAXIMIZE) );

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

   /* set time and memory limit */
   SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) );
   SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) );

   SCIP_CALL( SCIPallocMemoryArray(subscip, &vars, nitems) );

   /* initialization local pricing problem */
   SCIP_CALL( initPricing(scip, pricerdata, subscip, vars) );

   SCIPdebugMessage("solve pricer problem\n");

   /* solve sub SCIP */
   SCIP_CALL( SCIPsolve(subscip) );

   sols = SCIPgetSols(subscip);
   nsols = SCIPgetNSols(subscip);
   addvar = FALSE;

   /* loop over all solutions and create the corresponding column to master if the reduced cost are negative for master,
    * that is the objective value i greater than 1.0
    */
   for( s = 0; s < nsols; ++s )
   {
      SCIP_Bool feasible;
      SCIP_SOL* sol;

      /* the soultion should be sorted w.r.t. the objective function value */
      assert(s == 0 || SCIPisFeasGE(subscip, SCIPgetSolOrigObj(subscip, sols[s-1]), SCIPgetSolOrigObj(subscip, sols[s])));

      sol = sols[s];
      assert(sol != NULL);

      /* check if solution is feasible in original sub SCIP */
      SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, FALSE, FALSE ) );

      if( !feasible )
      {
         SCIPwarningMessage(scip, "solution in pricing problem (capacity <%d>) is infeasible\n", capacity);
         continue;
      }

      /* check if the solution has a value greater than 1.0 */
      if( SCIPisFeasGT(subscip, SCIPgetSolOrigObj(subscip, sol), 1.0) )
      {
         SCIP_VAR* var;
         SCIP_VARDATA* vardata;
         int* consids;
         char strtmp[SCIP_MAXSTRLEN];
         char name[SCIP_MAXSTRLEN];
         int nconss;
         int o;
         int v;

         SCIPdebug( SCIP_CALL( SCIPprintSol(subscip, sol, NULL, FALSE) ) );

         nconss = 0;
         (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "items");

         SCIP_CALL( SCIPallocBufferArray(scip, &consids, nitems) );

         /* check which variables are fixed -> which item belongs to this packing */
         for( o = 0, v = 0; o < nitems; ++o )
         {
            if( !SCIPconsIsEnabled(conss[o]) )
               continue;

            assert(SCIPgetNFixedonesSetppc(scip, conss[o]) == 0);

            if( SCIPgetSolVal(subscip, sol, vars[v]) > 0.5 )
            {
               (void) SCIPsnprintf(strtmp, SCIP_MAXSTRLEN, "_%d", ids[o]);
               strcat(name, strtmp);

               consids[nconss] = o;
               nconss++;
            }
            else
               assert( SCIPisFeasEQ(subscip, SCIPgetSolVal(subscip, sol, vars[v]), 0.0) );

            v++;
         }

         SCIP_CALL( SCIPvardataCreateBinpacking(scip, &vardata, consids, nconss) );

         /* create variable for a new column with objective function coefficient 0.0 */
         SCIP_CALL( SCIPcreateVarBinpacking(scip, &var, name, 1.0, FALSE, TRUE, vardata) );

         /* add the new variable to the pricer store */
         SCIP_CALL( SCIPaddPricedVar(scip, var, 1.0) );
         addvar = TRUE;

         /* change the upper bound of the binary variable to lazy since the upper bound is already enforced due to
          * the objective function the set covering constraint; The reason for doing is that, is to avoid the bound
          * of x <= 1 in the LP relaxation since this bound constraint would produce a dual variable which might have
          * a positive reduced cost
          */
         SCIP_CALL( SCIPchgVarUbLazy(scip, var, 1.0) );

         /* check which variable are fixed -> which orders belong to this packing */
         for( v = 0; v < nconss; ++v )
         {
            assert(SCIPconsIsEnabled(conss[consids[v]]));
            SCIP_CALL( SCIPaddCoefSetppc(scip, conss[consids[v]], var) );
         }

         SCIPdebug(SCIPprintVar(scip, var, NULL) );
         SCIP_CALL( SCIPreleaseVar(scip, &var) );

         SCIPfreeBufferArray(scip, &consids);
      }
      else
         break;
   }

   /* free pricer MIP */
   SCIPfreeMemoryArray(subscip, &vars);

   if( addvar || SCIPgetStatus(subscip) == SCIP_STATUS_OPTIMAL )
      (*result) = SCIP_SUCCESS;

   /* free sub SCIP */
   SCIP_CALL( SCIPfree(&subscip) );

   return SCIP_OKAY;
}
示例#17
0
/** frees specific constraint data */
static
SCIP_DECL_CONSDELETE(consDeleteOrigbranch)
{  /*lint --e{715}*/
   SCIP_CONSDATA* parentdata;

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

   SCIPdebugMessage("Deleting branch orig constraint: <%s>.\n", SCIPconsGetName(cons));

   /* set the origcons pointer of the corresponding mastercons to NULL */
   if( (*consdata)->mastercons != NULL )
      GCGconsMasterbranchSetOrigcons((*consdata)->mastercons, NULL);

   /* set the pointer in the parent constraint to NULL */
   if( (*consdata)->parentcons != NULL )
   {
      parentdata = SCIPconsGetData((*consdata)->parentcons);
      if( parentdata->child1cons == cons )
         parentdata->child1cons = NULL;
      else if( parentdata->probingtmpcons == cons )
      {
         assert(SCIPinProbing(scip));
         parentdata->probingtmpcons = NULL;
      }
      else
      {
         assert(parentdata->child2cons == cons);
         parentdata->child2cons = NULL;
         if( SCIPinProbing(scip) )
         {
            parentdata->child2cons = parentdata->probingtmpcons;
            parentdata->probingtmpcons = NULL;
         }
      }
   }
   /* no child nodes may exist */
   assert((*consdata)->child1cons == NULL);
   assert((*consdata)->child2cons == NULL);

   /* delete branchdata, if no mastercons is linked, which would still need the branchdata
    * otherwise, the mastercons deletes the branchdata when it is deleted itself */
   if( (*consdata)->mastercons == NULL && (*consdata)->branchdata != NULL )
   {
      SCIP_CALL( GCGrelaxBranchDataDelete(scip, (*consdata)->branchrule, &(*consdata)->branchdata) );
   }

   /* free propagation domain changes arrays */
   if( (*consdata)->maxpropbounds > 0 )
   {
      SCIPfreeMemoryArray(scip, &((*consdata)->propvars));
      SCIPfreeMemoryArray(scip, &((*consdata)->propboundtypes));
      SCIPfreeMemoryArray(scip, &((*consdata)->propbounds));
   }

   /* free constraint data */
   SCIPfreeBlockMemory(scip, consdata);

   return SCIP_OKAY;
}
示例#18
0
SCIP_RETCODE SCIPconshdlrBenders::sepaBenders(
		SCIP * scip,
		SCIP_CONSHDLR * conshdlr,
		SCIP_SOL * sol,
		whereFrom where,
		SCIP_RESULT * result)
{
	OsiCuts cs; /**< Benders cut placeholder */
	SCIP_Real * vals = NULL; /**< current solution */

#if 1
	if (scip_checkpriority_ < 0)
	{
		/** consider incumbent solutions only */
		double primObj = SCIPgetPrimalbound(scip);
		double currObj = SCIPgetSolOrigObj(scip, sol);
		if (SCIPisLT(scip, primObj, currObj))
		{
			DSPdebugMessage(" -> primObj %e currObj %e\n", primObj, currObj);
			return SCIP_OKAY;
		}
	}
#endif

	/** allocate memory */
	SCIP_CALL(SCIPallocMemoryArray(scip, &vals, nvars_));

	/** get current solution */
	SCIP_CALL(SCIPgetSolVals(scip, sol, nvars_, vars_, vals));

	/** TODO The following filter does not work, meaning that it provides suboptimal solution.
	 * I do not know the reason. */
#if 0
	double maxviol = 1.e-10;
	for (int j = 0; j < nvars_ - naux_; ++j)
	{
		SCIP_VARTYPE vartype = SCIPvarGetType(vars_[j]);
		if (vartype == SCIP_VARTYPE_CONTINUOUS) continue;

		double viol = 0.5 - fabs(vals[j] - floor(vals[j]) - 0.5);
		if (viol > maxviol)
			maxviol = viol;
	}
	DSPdebugMessage("maximum violation %e\n", maxviol);

	if (where != from_scip_check &&
		where != from_scip_enfolp &&
		where != from_scip_enfops &&
		maxviol > 1.e-7)
	{
		printf("where %d maxviol %e\n", where, maxviol);
		/** free memory */
		SCIPfreeMemoryArray(scip, &vals);
		return SCIP_OKAY;
	}
#endif

#ifdef DSP_DEBUG2
	double minvals = COIN_DBL_MAX;
	double maxvals = -COIN_DBL_MAX;
	double sumvals = 0.;
	double ssvals  = 0.;
	//printf("nvars_ %d naux_ %d nAuxvars_ %d\n", nvars_, naux_, tss_->nAuxvars_);
	for (int j = 0; j < nvars_ - naux_; ++j)
	{
//		if (vals[j] < 0 || vals[j] > 1)
//			printf("solution %d has value %e.\n", j, vals[j]);
		sumvals += vals[j];
		ssvals  += vals[j] * vals[j];
		minvals = minvals > vals[j] ? vals[j] : minvals;
		maxvals = maxvals < vals[j] ? vals[j] : maxvals;
	}
	DSPdebugMessage("solution: min %e max %e avg %e sum %e two-norm %e\n",
			minvals, maxvals, sumvals / nvars_, sumvals, sqrt(ssvals));
#endif

#define SCAN_GLOBAL_CUT_POOL
#ifdef SCAN_GLOBAL_CUT_POOL
	if (SCIPgetStage(scip) == SCIP_STAGE_SOLVING ||
		SCIPgetStage(scip) == SCIP_STAGE_SOLVED ||
		SCIPgetStage(scip) == SCIP_STAGE_EXITSOLVE)
	{
		bool addedPoolCut = false;
		int numPoolCuts = SCIPgetNPoolCuts(scip);
		int numCutsToScan = 100;
		SCIP_CUT ** poolcuts = SCIPgetPoolCuts(scip);
		for (int i = numPoolCuts - 1; i >= 0; --i)
		{
			if (i < 0) break;
			if (numCutsToScan == 0) break;

			/** retrieve row */
			SCIP_ROW * poolcutrow = SCIPcutGetRow(poolcuts[i]);

			/** benders? */
			if (strcmp(SCIProwGetName(poolcutrow), "benders") != 0)
				continue;

			/** counter */
			numCutsToScan--;

			if (SCIPgetCutEfficacy(scip, sol, poolcutrow) > 1.e-6)
			{
				if (where == from_scip_sepalp ||
					where == from_scip_sepasol ||
					where == from_scip_enfolp)
				{
					/** add cut */
					SCIP_Bool infeasible;
					SCIP_CALL(SCIPaddCut(scip, sol, poolcutrow,
							FALSE, /**< force cut */
							&infeasible));

					if (infeasible)
						*result = SCIP_CUTOFF;
					else //if (*result != SCIP_CUTOFF)
						*result = SCIP_SEPARATED;
				}
				else
					*result = SCIP_INFEASIBLE;
				addedPoolCut = true;
				break;
			}
		}
		if (addedPoolCut)
		{
			DSPdebugMessage("Added pool cut\n");
			/** free memory */
			SCIPfreeMemoryArray(scip, &vals);
			return SCIP_OKAY;
		}
	}
#endif

	/** generate Benders cuts */
	assert(tss_);
	tss_->generateCuts(nvars_, vals, &cs);

	/** If found Benders cuts */
	for (int i = 0; i < cs.sizeCuts(); ++i)
	{
		/** get cut pointer */
		OsiRowCut * rc = cs.rowCutPtr(i);
		if (!rc) continue;

		const CoinPackedVector cutrow = rc->row();
		if (cutrow.getNumElements() == 0) continue;

		/** is optimality cut? */
		bool isOptimalityCut = false;
		for (int j = nvars_ - naux_; j < nvars_; ++j)
		{
			if (cutrow.getMaxIndex() == j)
			{
				isOptimalityCut = true;
				break;
			}
		}

		double efficacy = rc->violated(vals) / cutrow.twoNorm();
		SCIP_Bool isEfficacious = efficacy > 1.e-6;

#define KK_TEST
#ifdef KK_TEST
		if (SCIPgetStage(scip) == SCIP_STAGE_INITSOLVE ||
			SCIPgetStage(scip) == SCIP_STAGE_SOLVING)
		{
			/** create empty row */
			SCIP_ROW * row = NULL;
			SCIP_CALL(SCIPcreateEmptyRowCons(scip, &row, conshdlr, "benders", rc->lb(), SCIPinfinity(scip),
					FALSE, /**< is row local? */
					FALSE, /**< is row modifiable? */
					FALSE  /**< is row removable? can this be TRUE? */));

			/** cache the row extension and only flush them if the cut gets added */
			SCIP_CALL(SCIPcacheRowExtensions(scip, row));

			/** collect all non-zero coefficients */
			for (int j = 0; j < cutrow.getNumElements(); ++j)
				SCIP_CALL(SCIPaddVarToRow(scip, row, vars_[cutrow.getIndices()[j]], cutrow.getElements()[j]));

			DSPdebugMessage("found Benders (%s) cut: act=%f, lhs=%f, norm=%f, eff=%f, min=%f, max=%f (range=%f)\n",
				isOptimalityCut ? "opti" : "feas",
				SCIPgetRowLPActivity(scip, row), SCIProwGetLhs(row), SCIProwGetNorm(row),
				SCIPgetCutEfficacy(scip, sol, row),
				SCIPgetRowMinCoef(scip, row), SCIPgetRowMaxCoef(scip, row),
				SCIPgetRowMaxCoef(scip, row)/SCIPgetRowMinCoef(scip, row));

			/** flush all changes before adding cut */
			SCIP_CALL(SCIPflushRowExtensions(scip, row));

			DSPdebugMessage("efficacy %e isEfficatious %d\n", efficacy, isEfficacious);

			if (isEfficacious)
			{
				if (where == from_scip_sepalp ||
					where == from_scip_sepasol ||
					where == from_scip_enfolp)
				{
					/** add cut */
					SCIP_Bool infeasible;
					SCIP_CALL(SCIPaddCut(scip, sol, row,
							FALSE, /**< force cut */
							&infeasible));

					if (infeasible)
						*result = SCIP_CUTOFF;
					else //if (*result != SCIP_CUTOFF)
						*result = SCIP_SEPARATED;
				}
				else
					*result = SCIP_INFEASIBLE;
			}

			/** add cut to global pool */
			SCIP_CALL(SCIPaddPoolCut(scip, row));
			DSPdebugMessage("number of cuts in global cut pool: %d\n", SCIPgetNPoolCuts(scip));

			/** release the row */
			SCIP_CALL(SCIPreleaseRow(scip, &row));
		}
		else if (isEfficacious &&
					where != from_scip_sepalp &&
					where != from_scip_sepasol &&
					where != from_scip_enfolp)
			*result = SCIP_INFEASIBLE;
#else
		if (where == from_scip_sepalp ||
			where == from_scip_sepasol ||
			where == from_scip_enfolp)
		{
			/** create empty row */
			SCIP_ROW * row = NULL;
			SCIP_CALL(SCIPcreateEmptyRowCons(scip, &row, conshdlr, "benders", rc->lb(), SCIPinfinity(scip),
					FALSE, /**< is row local? */
					FALSE, /**< is row modifiable? */
					FALSE  /**< is row removable? can this be TRUE? */));

			/** cache the row extension and only flush them if the cut gets added */
			SCIP_CALL(SCIPcacheRowExtensions(scip, row));

			/** collect all non-zero coefficients */
			for (int j = 0; j < cutrow.getNumElements(); ++j)
				SCIP_CALL(SCIPaddVarToRow(scip, row, vars_[cutrow.getIndices()[j]], cutrow.getElements()[j]));

			DSPdebugMessage("found Benders (%s) cut: act=%f, lhs=%f, norm=%f, eff=%f, min=%f, max=%f (range=%f)\n",
				isOptimalityCut ? "opti" : "feas",
				SCIPgetRowLPActivity(scip, row), SCIProwGetLhs(row), SCIProwGetNorm(row),
				SCIPgetCutEfficacy(scip, NULL, row),
				SCIPgetRowMinCoef(scip, row), SCIPgetRowMaxCoef(scip, row),
				SCIPgetRowMaxCoef(scip, row)/SCIPgetRowMinCoef(scip, row));

			/** flush all changes before adding cut */
			SCIP_CALL(SCIPflushRowExtensions(scip, row));

			/** is cut efficacious? */
			if (isOptimalityCut)
			{
				efficacy = SCIPgetCutEfficacy(scip, sol, row);
				isEfficacious = SCIPisCutEfficacious(scip, sol, row);
			}
			else
			{
				efficacy = rc->violated(vals);
				isEfficacious = efficacy > 1.e-6;
			}

			if (isEfficacious)
			{
				/** add cut */
				SCIP_Bool infeasible;
				SCIP_CALL(SCIPaddCut(scip, sol, row,
						FALSE, /**< force cut */
						&infeasible));

				if (infeasible)
					*result = SCIP_CUTOFF;
				else if (*result != SCIP_CUTOFF)
					*result = SCIP_SEPARATED;
			}

			/** add cut to global pool */
			SCIP_CALL(SCIPaddPoolCut(scip, row));

			/** release the row */
			SCIP_CALL(SCIPreleaseRow(scip, &row));
		}
		else
		{
			if (isOptimalityCut)
			{
				efficacy = rc->violated(vals) / cutrow.twoNorm();
				isEfficacious = efficacy > 0.05;
			}
			else
			{
				efficacy = rc->violated(vals);
				isEfficacious = efficacy > 1.e-6;
			}
			DSPdebugMessage("%s efficacy %e\n", isOptimalityCut ? "Opti" : "Feas", efficacy);

			if (isEfficacious == TRUE)
				*result = SCIP_INFEASIBLE;
		}
#endif
	}

	/** free memory */
	SCIPfreeMemoryArray(scip, &vals);

	return SCIP_OKAY;
}