Esempio n. 1
0
/** solving process initialization method of variable pricer (called when branch and bound process is about to begin) */
static
SCIP_DECL_PRICERINITSOL(pricerInitsolStp)
{
   SCIP_PRICERDATA* pricerdata;
   SCIPdebugPrintf("pricerinitsol \n");
   assert(scip != NULL);
   assert(pricer != NULL);

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

   /* allocate memory */
   if( !pricerdata->bigt )
   {
      SCIP_CALL( SCIPallocMemoryArray(scip, &(pricerdata->pi), SCIPprobdataGetNEdges(scip) * SCIPprobdataGetRNTerms(scip)) );
   }
   else
   {
      SCIP_CALL( SCIPallocMemoryArray(scip, &(pricerdata->pi), SCIPprobdataGetNEdges(scip)) );
   }

   SCIP_CALL( SCIPallocMemoryArray(scip, &(pricerdata->mi), SCIPprobdataGetRNTerms(scip)) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &pricerdata->ncreatedvars, SCIPprobdataGetRNTerms(scip)) );
   BMSclearMemoryArray(pricerdata->ncreatedvars, SCIPprobdataGetRNTerms(scip));

   return SCIP_OKAY;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
/** copies user data of source SCIP for the target SCIP */
static
SCIP_DECL_PROBCOPY(probcopyLOP)
{
   int n;
   int i;
   int j;

   assert( scip != NULL );
   assert( sourcescip != NULL );
   assert( sourcedata != NULL );
   assert( targetdata != NULL );

   /* set up data */
   SCIP_CALL( SCIPallocMemory(scip, targetdata) );

   n = sourcedata->n;
   (*targetdata)->n = n;

   /* set matrices */
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->W), n) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->vars), n) );

   for( i = 0; i < n; ++i )
   {
      SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->W[i]), n) ); /*lint !e866*/
      SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->vars[i]), n) ); /*lint !e866*/

      for( j = 0; j < n; ++j )
      {
         if( i != j )
         {
            SCIP_VAR* var;
            SCIP_Bool success;
            
	    SCIP_CALL( SCIPgetTransformedVar(sourcescip, sourcedata->vars[i][j], &var) );
            SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &((*targetdata)->vars[i][j]), varmap, consmap, global, &success) );
            assert(success);
            assert((*targetdata)->vars[i][j] != NULL);

            SCIP_CALL( SCIPcaptureVar(scip, (*targetdata)->vars[i][j]) );
         }
         else
            (*targetdata)->vars[i][j] = NULL;
      }
   }

   *result = SCIP_SUCCESS;
   
   return SCIP_OKAY;
}
Esempio n. 6
0
/** solving process initialization method of constraint handler (called when branch and bound process is about to begin) */
static
SCIP_DECL_CONSINITSOL(consInitsolOrigbranch)
{  /*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);

   /* prepare stack */
   SCIP_CALL( SCIPallocMemoryArray(scip, &conshdlrData->stack, conshdlrData->maxstacksize) );
   assert( conshdlrData->nstack >= 0 );

   /* check consistency */
   if( conshdlrData->rootcons != NULL )
   {
      SCIP_CALL( SCIPreleaseCons(scip, &conshdlrData->rootcons) );
      conshdlrData->rootcons = NULL;
      --(conshdlrData->nstack);
   }
   GCGconsOrigbranchCheckConsistency(scip);

   return SCIP_OKAY;
}
Esempio n. 7
0
/** set original variable pointers */
SCIP_RETCODE SCIPconshdlrBenders::setOriginalVariables(int nvars, SCIP_Var ** vars)
{
	nvars_ = nvars;
	SCIP_CALL(SCIPallocMemoryArray(scip_, &vars_, nvars_));
	for (int j = 0; j < nvars_; ++j)
		vars_[j] = vars[j];
	return SCIP_OKAY;
}
Esempio n. 8
0
/** create linear ordering problem model */
SCIP_RETCODE LOPgenerateModel(
   SCIP*                 scip                /**< SCIP data structure */
   )
{
   SCIP_PROBDATA* probdata;
   SCIP_CONS* cons;
   int i, j;

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

   /* generate variables */
   SCIP_CALL( SCIPallocMemoryArray(scip, &probdata->vars, probdata->n) );
   for (i = 0; i < probdata->n; ++i)
   {
      SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->vars[i]), probdata->n) ); /*lint !e866*/
      for (j = 0; j < probdata->n; ++j)
      {
	 if (j != i)
	 {
	    char s[SCIP_MAXSTRLEN];
	    (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "x#%d#%d", i, j);
	    SCIP_CALL( SCIPcreateVar(scip, &(probdata->vars[i][j]), s, 0.0, 1.0, probdata->W[i][j], SCIP_VARTYPE_BINARY,
		  TRUE, FALSE, NULL, NULL, NULL, NULL, NULL));
	    SCIP_CALL( SCIPaddVar(scip, probdata->vars[i][j]) );
	 }
	 else
	    probdata->vars[i][j] = NULL;
      }
   }

   /* generate linear ordering constraint */
   SCIP_CALL( SCIPcreateConsLinearOrdering(scip, &cons, "LOP", probdata->n, probdata->vars, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
	 FALSE, FALSE, FALSE, FALSE));
   SCIP_CALL( SCIPaddCons(scip, cons) );
   SCIP_CALL( SCIPreleaseCons(scip, &cons) );

   /* set maximization */
   SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) );

   return SCIP_OKAY;
}
Esempio n. 9
0
SCIP_RETCODE SCIPreadLIBSVMPolicy(
   SCIP*              scip,
   char*              fname,
   SCIP_POLICY**      policy       
   )
{
   int nlines = 0;
   int i;
   char buffer[SCIP_MAXSTRLEN];

   FILE* file = fopen(fname, "r");
   if( file == NULL )
   {
      SCIPerrorMessage("cannot open file <%s> for reading\n", fname);
      SCIPprintSysError(fname);
      return SCIP_NOFILE;
   }

   /* find out weight vector size */
   while( fgets(buffer, (int)sizeof(buffer), file) != NULL )
      nlines++;
   /* don't count libsvm model header */
   assert(nlines >= HEADERSIZE_LIBSVM);
   (*policy)->size = nlines - HEADERSIZE_LIBSVM;
   fclose(file);
   if( (*policy)->size == 0 )
   {
      SCIPerrorMessage("empty policy model\n");
      return SCIP_NOFILE;
   }

   SCIP_CALL( SCIPallocMemoryArray(scip, &(*policy)->weights, (*policy)->size) );

   /* have to reopen to read weights */
   file = fopen(fname, "r");
   /* skip header */
   for( i = 0; i < HEADERSIZE_LIBSVM; i++ )
      fgets(buffer, (int)sizeof(buffer), file);
   for( i = 0; i < (*policy)->size; i++ )
      fscanf(file, "%"SCIP_REAL_FORMAT, &((*policy)->weights[i]));

   fclose(file);

   SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "policy of size %d from file <%s> was %s\n",
      (*policy)->size, fname, "read, will be used in the dagger node selector");

   return SCIP_OKAY;
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
/** reads a block section */
static
SCIP_RETCODE readBlock(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput,           /**< BLK reading data */
    SCIP_READERDATA*      readerdata          /**< reader data */
)
{
    int blockid;

    assert(blkinput != NULL);

    blockid = blkinput->blocknr;

    while( getNextToken(blkinput) )
    {
        SCIP_VAR* var;
        int varidx;
        int oldblock;

        /* check if we reached a new section */
        if( isNewSection(scip, blkinput) )
            return SCIP_OKAY;

        /* the token must be the name of an existing variable */
        var = SCIPfindVar(scip, blkinput->token);
        if( var == NULL )
        {
            syntaxError(scip, blkinput, "unknown variable in block section");
            return SCIP_OKAY;
        }

        varidx = SCIPvarGetProbindex(var);
        oldblock = readerdata->varstoblock[varidx];

        /* set the block number of the variable to the number of the current block */
        if( oldblock == NOVALUE )
        {
            SCIPdebugMessage("\tVar %s temporary in block %d.\n", SCIPvarGetName(var), blockid);
            readerdata->varstoblock[varidx] = blockid;
            ++(readerdata->nblockvars[blockid]);
        }
        /* variable was assigned to another (non-linking) block before, so it becomes a linking variable, now */
        else if( (oldblock != LINKINGVALUE) )
        {
            assert(oldblock != blockid);
            SCIPdebugMessage("\tVar %s is linking (old %d != %d new).\n", SCIPvarGetName(var), oldblock, blockid);

            readerdata->varstoblock[varidx] = LINKINGVALUE;

            /* decrease the number of variables in the old block and increase the number of linking variables */
            --(readerdata->nblockvars[oldblock]);
            ++(readerdata->nlinkingvars);

            assert(readerdata->nlinkingvarsblocks[varidx] == 0);
            assert(readerdata->linkingvarsblocks[varidx] == NULL);
            SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->linkingvarsblocks[varidx], 2) ); /*lint !e506 !e866*/
            readerdata->linkingvarsblocks[varidx][0] = oldblock;
            readerdata->linkingvarsblocks[varidx][1] = blockid;
            readerdata->nlinkingvarsblocks[varidx] = 2;
        }
        /* variable is a linking variable already, store the new block to which it belongs */
        else
        {
            assert(oldblock == LINKINGVALUE);
            assert(readerdata->nlinkingvarsblocks[varidx] >= 2);
            assert(readerdata->linkingvarsblocks[varidx] != NULL);
            SCIP_CALL( SCIPreallocMemoryArray(scip, &readerdata->linkingvarsblocks[varidx], readerdata->nlinkingvarsblocks[varidx] + 1) ); /*lint !e866*/
            readerdata->linkingvarsblocks[varidx][readerdata->nlinkingvarsblocks[varidx]] = blockid;
            ++(readerdata->nlinkingvarsblocks[varidx]);
        }
    }

    return SCIP_OKAY;
}
Esempio n. 15
0
/** transforms the problem */
static
SCIP_DECL_PROBTRANS(probtransColoring)
{
   int i;
   int j;
   int* firstedge;
   int* lastedge;

   assert(scip != NULL);
   assert(sourcedata != NULL);
   assert(targetdata != NULL);

   /* allocate memory */
   SCIP_CALL( SCIPallocMemory(scip, targetdata) );

   if( !tcliqueCreate(&((*targetdata)->graph)) ) /* create the transformed graph */
   {
      SCIPerrorMessage("could not create the clique graph\n");
      return SCIP_ERROR;
   }

   (*targetdata)->maxstablesets = sourcedata->maxstablesets;        /* copy length of array sets */
   (*targetdata)->nstablesets = sourcedata->nstablesets;            /* copy number of sets saved in array sets */
   (*targetdata)->oldgraph = sourcedata->oldgraph;      /* copy link to original graph */

   /* allocate memory for sets and lenghts of the sets */
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->stablesets), sourcedata->maxstablesets) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->stablesetlengths), sourcedata->maxstablesets) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->stablesetvars), sourcedata->maxstablesets) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->deletednodes), tcliqueGetNNodes(sourcedata->oldgraph)) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->new2oldnode), tcliqueGetNNodes(sourcedata->oldgraph)) );  

   for ( i = 0; i < tcliqueGetNNodes(sourcedata->oldgraph); i++ )
   {
      (*targetdata)->deletednodes[i] = sourcedata->deletednodes[i];
      (*targetdata)->new2oldnode[i] = sourcedata->new2oldnode[i];
   }

   /* copy stablesetlengths and stablesets */
   for ( i = 0; i < sourcedata->nstablesets; i++ )
   {
      assert(sourcedata->stablesetvars[i] != NULL);
      (*targetdata)->stablesetlengths[i] = sourcedata->stablesetlengths[i];
      SCIP_CALL( SCIPtransformVar(scip, sourcedata->stablesetvars[i], &((*targetdata)->stablesetvars[i])) );
      SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*targetdata)->stablesets[i]),  sourcedata->stablesetlengths[i]) ); /*lint !e866*/
      for ( j = 0; j <sourcedata->stablesetlengths[i]; j++ )
      {
         (*targetdata)->stablesets[i][j] =  sourcedata->stablesets[i][j];
      }
   }

   /* create array for constraints */
   SCIP_CALL( SCIPallocMemoryArray(scip, &(*targetdata)->constraints, tcliqueGetNNodes(sourcedata->graph)) );
   /* tranform constraints */
   SCIP_CALL( SCIPtransformConss(scip, tcliqueGetNNodes(sourcedata->graph), sourcedata->constraints,
         (*targetdata)->constraints) );
   /* copy the graph */
   if( !tcliqueAddNode((*targetdata)->graph, tcliqueGetNNodes(sourcedata->graph)-1, 0) )
   {
      SCIPerrorMessage("could not add a node to the clique graph\n");
      return SCIP_ERROR;
   }

   for ( i = 0; i < tcliqueGetNNodes(sourcedata->graph); i++ )
   {
      /* get adjacent nodes for node i */
      firstedge = tcliqueGetFirstAdjedge(sourcedata->graph, i);
      lastedge = tcliqueGetLastAdjedge(sourcedata->graph, i);
      while ( firstedge <= lastedge )
      {
         if ( *firstedge > i )
         {
            if( !tcliqueAddEdge((*targetdata)->graph, i, *firstedge) )
            {
               SCIPerrorMessage("could not add an edge to the clique graph\n");
               return SCIP_ERROR;
            }
         }
         firstedge++;
      }
   }

   if( !tcliqueFlush((*targetdata)->graph) )
   {
      SCIPerrorMessage("could not flush the clique graph\n");
      return SCIP_ERROR;
   }

   return SCIP_OKAY;
}
Esempio n. 16
0
/** sets up the problem data */
SCIP_RETCODE SCIPcreateProbColoring(
   SCIP*                 scip,               /**< SCIP data structure */
   const char*           name,               /**< problem name */           
   int                   nnodes,             /**< number of nodes */
   int                   nedges,             /**< number of edges */
   int**                 edges               /**< array with start- and endpoints of the edges */
   )
{
   int i;
   SCIP_PROBDATA* probdata = NULL;

   assert(nnodes > 0);  /* at least one node */
   assert(nedges >= 0); /* no negative number of edges */

   printf("Creating problem: %s \n", name);
   
   /* allocate memory */
   SCIP_CALL( SCIPallocMemory(scip, &probdata) );

   /* create graph */
   if( !tcliqueCreate(&((probdata)->oldgraph)) )
   {
      SCIPerrorMessage("could not create the clique graph\n");
      return SCIP_ERROR;
   }

   /* add all nodes from 0 to nnodes-1 */
   if( !tcliqueAddNode((probdata)->oldgraph, nnodes-1, 0) )
   {
      SCIPerrorMessage("could not add a node to the clique graph\n");
      return SCIP_ERROR;
   }


   /* add all edges, first into cache, then flush to add all of them to the graph */
   for ( i = 0; i < nedges; i++ )
   {
      assert((edges[i][0] > 0) && (edges[i][0] <= nnodes));
      assert((edges[i][1] > 0) && (edges[i][1] <= nnodes));

      if( !tcliqueAddEdge((probdata)->oldgraph, edges[i][0]-1, edges[i][1]-1) )
      {
         SCIPerrorMessage("could not add an edge to the clique graph\n");
         return SCIP_ERROR;
      }
   }

   if( !tcliqueFlush((probdata)->oldgraph) )
   {
      SCIPerrorMessage("could not flush the clique graph\n");
      return SCIP_ERROR;
   }

   /* create constraints */
   SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->constraints), nnodes) );

   /* at the beginning memory for 2 sets */
   SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->stablesets), 2) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->stablesetlengths), 2) );
   SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->stablesetvars), 2) );

   probdata->maxstablesets = 2;
   probdata->nstablesets = 0;

   /* include variable deleted event handler into SCIP */
   SCIP_CALL( SCIPincludeEventhdlrBasic(scip, NULL, EVENTHDLR_NAME, EVENTHDLR_DESC,
         eventExecProbdatavardeleted, NULL) );

   /* create problem in SCIP */
   SCIP_CALL( SCIPcreateProb(scip, name, probdelorigColoring, probtransColoring, probdeltransColoring, 
         NULL, NULL, NULL, probdata) );

   SCIP_CALL( preprocessGraph(scip) );

   return SCIP_OKAY;
}
Esempio n. 17
0
/** read weight matrix from file (in LOLIB format)
 *
 *  Format:
 *  comment line
 *  # of elements
 *  weight matrix (doubles)
 */
static
SCIP_RETCODE LOPreadFile(
   SCIP*                 scip,               /**< SCIP data structure */
   const char*           filename,           /**< name of file to read */
   SCIP_PROBDATA*        probdata            /**< problem data to be filled */
   )
{
   int i, j;
   FILE *file;
   int status;
   int n;
   SCIP_Real** W;
   char s[SCIP_MAXSTRLEN];

   /* open file */
   file = fopen(filename, "r");
   if ( file == NULL )
   {
      SCIPerrorMessage("Could not open file <%s>.\n", filename);
      return SCIP_NOFILE;
   }

   /* skip one line */
   if ( fgets(s, SCIP_MAXSTRLEN, file) == NULL )
   {
      SCIPerrorMessage("Error reading file <%s>.\n", filename);
      return SCIP_READERROR;
   }

   /* read number of elements */
   status = fscanf(file, "%d", &n);
   if ( ! status )
   {
      SCIPerrorMessage("Reading failed.\n");
      return SCIP_READERROR;
   }
   assert( 0 < n );
   SCIPinfoMessage(scip, NULL, "Number of elements:\t%d\n\n", n);
   probdata->n = n;

   /* set up matrix */
   SCIP_CALL( SCIPallocMemoryArray(scip, &W, n) );
   for (i = 0; i < n; ++i)
      SCIP_CALL( SCIPallocMemoryArray(scip, &(W[i]), n) ); /*lint !e866*/
   probdata->W = W;

   /* read matrix */
   for (i = 0; i < n; ++i)
   {
      for (j = 0; j < n; ++j)
      {
	 SCIP_Real val;
	 status = fscanf(file, "%lf", &val);
	 if ( ! status )
	 {
	    SCIPerrorMessage("Reading failed.\n");
	    return SCIP_READERROR;
	 }
	 W[i][j] = val;
      }
   }
   fclose( file );

   return SCIP_OKAY;
}
Esempio n. 18
0
/** reads the blocks section */
static
SCIP_RETCODE readBlock(
    SCIP*                 scip,               /**< SCIP data structure */
    DECINPUT*             decinput,           /**< DEC reading data */
    SCIP_READERDATA*      readerdata          /**< reader data */
)
{
    int oldblock;
    int varidx;
    int consindex;
    int i;
    int blockid;
    int nvars;
    SCIP_CONS* cons;
    SCIP_VAR** vars;
    SCIP_Bool conshasvar;

    assert(decinput != NULL);
    assert(readerdata != NULL);

    while( getNextToken(decinput) )
    {
        /* check if we reached a new section */
        if( isNewSection(scip, decinput) )
            break;

        /* the token must be the name of an existing cons */
        cons = SCIPfindCons(scip, decinput->token);
        if( cons == NULL )
        {
            syntaxError(scip, decinput, "unknown constraint in block section");
            break;
        }

        conshasvar = FALSE;
        /* get all vars for the specific constraint */
        nvars = SCIPgetNVarsXXX(scip, cons);
        vars = NULL;
        if( nvars > 0 )
        {
            SCIP_CALL( SCIPallocMemoryArray(scip, &vars, nvars) );
            SCIP_CALL( SCIPgetVarsXXX(scip, cons, vars, nvars) );
        }

        blockid = decinput->blocknr;

        for( i = 0; i < nvars; i ++ )
        {
            SCIP_VAR* var;
            assert(vars != NULL); /* for flexelint */
            if( decinput->presolved )
            {
                var = SCIPvarGetProbvar(vars[i]);
                if( !SCIPisVarRelevant(var) )
                    continue;
            }
            else
                var = vars[i];

            conshasvar = TRUE;
            /* store for each var whether it is in none, one or more blocks */
            varidx = SCIPvarGetProbindex(var);
            assert(varidx >= 0 && varidx < SCIPgetNVars(scip));
            oldblock = readerdata->varstoblock[varidx];

            assert(oldblock == NOVALUE || oldblock == LINKINGVALUE || (oldblock >= 0 && oldblock < decinput->nblocks));

            /* variable was assigned to no block before, just assign it to the new block */
            if( oldblock == NOVALUE )
            {
                SCIPdebugMessage("\tVar %s temporary in block %d.\n", SCIPvarGetName(vars[i]), blockid);
                readerdata->varstoblock[varidx] = blockid;
                ++(readerdata->nblockvars[blockid]);
            }
            /* variable was assigned to another (non-linking) block before, so it becomes a linking variable, now */
            else if( (oldblock != LINKINGVALUE) && oldblock != blockid )
            {
                SCIPdebugMessage("\tVar %s is linking (old %d != %d new).\n", SCIPvarGetName(vars[i]), oldblock, blockid);
                assert(oldblock != blockid);

                readerdata->varstoblock[varidx] = LINKINGVALUE;

                /* decrease the value again if it is a linking var */
                --(readerdata->nblockvars[oldblock]);
                ++(readerdata->nlinkingvars);
            }
        }
        SCIPfreeMemoryArrayNull(scip, &vars);

        if( !conshasvar )
        {
            assert(!SCIPhashmapExists(readerdata->constoblock, cons));
            SCIPwarningMessage(scip, "Cons <%s> has been deleted by presolving, skipping.\n",  SCIPconsGetName(cons));
            continue;
        }
        /*
         * saving block <-> constraint
         */

        /** @todo check if linking constraints are not in the subscipcons */
        consindex = readerdata->nblockconss[blockid];
        readerdata->blockconss[blockid][consindex] = cons;
        ++(readerdata->nblockconss[blockid]);

        assert(SCIPhashmapGetImage(readerdata->constoblock, cons) == (void*)(size_t) LINKINGVALUE);

        SCIPdebugMessage("cons %s is in block %d\n", SCIPconsGetName(cons), blockid);
        SCIP_CALL( SCIPhashmapSetImage(readerdata->constoblock, cons, (void*) ((size_t) blockid)) );
        --(readerdata->nlinkingconss);


    }

    return SCIP_OKAY;
}
Esempio n. 19
0
/** 
 *  Preprocessing of the graph, using 2 methods in order to find redundant nodes
 *  that can be deleted and easily colored later.
 *
 *  Foundation of these methods is the computation of a maximum clique C with M nodes. 
 *  After this computation, the following two steps are repeated until no node was deleted
 *  in the last iteration:
 *  
 *  1: Low-Degree:
 *  Iterativly delete all nodes v in the graph G with degree d(v) < M ( don't delete nodes of C )
 *
 *  2: Dominated Neighbourhood:
 *  If the neighbourhood of one node v is part of the neighbourhood of another node w, v can 
 *  be deleted, since it can later get the same color as w.
 */
static 
SCIP_RETCODE preprocessGraph( 
   SCIP*                 scip               /**< SCIP data structure */
   )
{
   SCIP_PROBDATA*   probdata;           /* the problemdata */
   SCIP_Bool        changed;            /* was the graph changed in the last round of preprocessing? */
   SCIP_Bool        dominates;          /* is the neighbourhood of one node dominated by the neigbourhood of another one?*/
   int*             maxcliquenodes;     /* pointer to store nodes of the maximum weight clique */
   int              nmaxcliquenodes;    /* number of nodes in the maximum weight clique */
   TCLIQUE_WEIGHT   maxcliqueweight;    /* weight of the maximum weight clique */
   TCLIQUE_STATUS   status;             /* status of clique-computation */
   TCLIQUE_GRAPH*   currgraph;          /* the current, not preprocessed graph in each step */
   int currnnodes;                      /* the current number of nodes in each step */ 
   int actnewnode;                      /* the number of nodes yet marked for beeing in the graph in the next round */
   int* newnodes;                       /* the nodes that will be in the graph in the next round */
   int* degrees;                        /* the degrees of the nodes */
   int myround;                         /* the number of the current round */
   int ndeletednodes;                   /* the total number of deleted nodes */
   int nnodesdeleteddegreethisround;    /* the number of nodes deleted due to low degree in the current round */
   int nnodesdeletedneighbourthisround; /* the number of nodes deleted due to neighbourhood in the current round */
   int*  firstedge;                     /* pointer for the edges in the graph */
   int*  lastedge;                      /* pointer for the edges in the graph */
   int i;
   int j;
   char opt;

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

   printf("\npreprocessing...\n");

   /* copy the old graph */
   if( !tcliqueCreate(&currgraph) )
   {
      SCIPerrorMessage("could not flush the clique graph\n");
      return SCIP_ERROR;
   }

   assert(currgraph != NULL);

   if( !tcliqueAddNode(currgraph, tcliqueGetNNodes(probdata->oldgraph)-1, 0) )
   {
      SCIPerrorMessage("could not add a node to the clique graph\n");
      return SCIP_ERROR;
   }

   for ( i = 0; i < tcliqueGetNNodes(probdata->oldgraph); i++ )
   {
      /* get adjacent nodes for node i */
      firstedge = tcliqueGetFirstAdjedge(probdata->oldgraph, i);
      lastedge = tcliqueGetLastAdjedge(probdata->oldgraph, i);
      while ( firstedge <= lastedge )
      {
         if ( *firstedge > i )
         {
            if( !tcliqueAddEdge(currgraph, i, *firstedge) )
            {
               SCIPerrorMessage("could not add an edge to the clique graph\n");
               return SCIP_ERROR;
            }
         }
         firstedge++;
      }
   }

   if( !tcliqueFlush(currgraph) )
   {
      SCIPerrorMessage("could not flush the clique graph\n");
      return SCIP_ERROR;
   }

   currnnodes = tcliqueGetNNodes(probdata->oldgraph);

   /* get memory for array of deletednodes */  
   SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->deletednodes), COLORprobGetOriginalNNodes(scip)) );

   /* get memory for array new2oldnodes */
   SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->new2oldnode), COLORprobGetOriginalNNodes(scip)) );  

   SCIP_CALL( SCIPallocBufferArray(scip, &newnodes, COLORprobGetOriginalNNodes(scip)) );
   SCIP_CALL( SCIPallocBufferArray(scip, &maxcliquenodes, COLORprobGetOriginalNNodes(scip)) );
   
   for ( i = 0; i < currnnodes; i++ )
   {
      /* set weights of the nodes to 1 */
      tcliqueChangeWeight(currgraph, i, 1);
      /* every node in the graph represents the same node in the original graph */
      probdata->new2oldnode[i] = i;
   } 

   /* compute maximum clique */
   tcliqueMaxClique(NULL, NULL, NULL, NULL, currgraph, NULL, NULL, maxcliquenodes,
      &nmaxcliquenodes, &maxcliqueweight, 0, 0, 50000, 0, INT_MAX, -1, NULL, &status);
   opt = ( status == TCLIQUE_OPTIMAL ? ' ' : '*' );
   printf("size of the maximum clique: %d%c \n", nmaxcliquenodes, opt);

   ndeletednodes = 0;
   nnodesdeleteddegreethisround = 1;
   nnodesdeletedneighbourthisround = 1;
   myround = 0;

   /* main loop */
   while ( (nnodesdeleteddegreethisround > 0) || (nnodesdeletedneighbourthisround > 0) ) 
   {
      myround++;
      nnodesdeleteddegreethisround = 0;
      nnodesdeletedneighbourthisround = 0;
      changed = TRUE;

      /* node degree deletion loop */
      while ( changed == TRUE )
      {
         changed = FALSE;
         actnewnode = 0;
         degrees = tcliqueGetDegrees(currgraph);
         for (i = 0; i < currnnodes; i++)
         {
            /* degree is low, node can be deleted */
            if ( (degrees[i] < nmaxcliquenodes ) 
               && (!COLORprobIsNodeInArray(probdata->new2oldnode[i], maxcliquenodes, nmaxcliquenodes)) )
            {
               probdata->deletednodes[ndeletednodes] = probdata->new2oldnode[i];
               changed = TRUE;
               nnodesdeleteddegreethisround++;
               ndeletednodes++;
            }
            /* node will be in the new graph, because degree is not low enought for deletion or it is in the maxClique */
            else
            {
               newnodes[actnewnode] = probdata->new2oldnode[i];
               actnewnode++;
            }
         }

         /* at least one node was deletet, create new graph ( tclique doesn't support deletion of nodes) */
         if ( changed )
         {
            assert(actnewnode+ndeletednodes == COLORprobGetOriginalNNodes(scip));
            /* create new current graph */
            tcliqueFree(&currgraph);

            if( !tcliqueCreate(&currgraph) )
            {
               SCIPerrorMessage("could not create the clique graph\n");
               return SCIP_ERROR;
            }

            assert(currgraph != NULL);

            if( !tcliqueAddNode(currgraph, actnewnode-1, 0) )
            {
               SCIPerrorMessage("could not add a node to the clique graph\n");
               return SCIP_ERROR;
            }

            for ( i = 0; i < actnewnode; i++ )
            {
               /* get adjacent nodes for node newnodes[i] */
               firstedge = tcliqueGetFirstAdjedge(probdata->oldgraph, newnodes[i]);
               lastedge = tcliqueGetLastAdjedge(probdata->oldgraph, newnodes[i]);
               while ( firstedge <= lastedge )
               {
                  /* try to find a node in newnodes which corresponds 
                     to the node in the old graph, that is the end-node of the edge */
                  for ( j = i+1; j < actnewnode; j++ )
                  {
                     if ( *firstedge == newnodes[j] )
                     {
                        if( !tcliqueAddEdge(currgraph, i, j) )
                        {
                           SCIPerrorMessage("could not add an edge to the clique graph\n");
                           return SCIP_ERROR;
                        }

                        break;
                     }
                  }
                  firstedge++;
               }
            }

            if( !tcliqueFlush(currgraph) )
            {
               SCIPerrorMessage("could not flush the clique graph\n");
               return SCIP_ERROR;
            }

            /* update currnnodes */
            currnnodes = tcliqueGetNNodes(currgraph);
            /* update new2oldnodes */
            for ( i = 0; i < actnewnode; i++ )
            {
               probdata->new2oldnode[i] = newnodes[i];
            }
            /* set the corresponding old node to -1 for all nodes not in the current graph (only for bug-finding) */
            for ( i = actnewnode; i < COLORprobGetOriginalNNodes(scip); i++ )
            {
               probdata->new2oldnode[i] = -1;
            }
         }
      } /* end node degree deletion loop */

      /* set changed to TRUE for getting into the while-loop */
      changed = TRUE;
      /* loop for finding dominated neighbourhoods */
      while ( changed == TRUE )
      {
         changed = FALSE;
         actnewnode = 0;
         /* i is the node which is checked for beeing dominated */
         for ( i = 0; i < currnnodes; i++ )
         {
            assert(!COLORprobIsNodeInArray(probdata->new2oldnode[i], probdata->deletednodes, ndeletednodes));

            /* i must be not in the clique and not yet deleted */
            if ( (!COLORprobIsNodeInArray(probdata->new2oldnode[i], maxcliquenodes, nmaxcliquenodes)) )
            {
               /* j is the node for which is checked whether it dominates i */
               for ( j = 0; j < currnnodes; j++ )
               {
                  /* i must be distinct from j, there must be no edge between i and j, 
                     j may not have been deleted due to degree in the last round */
                  if ( (j != i) && !tcliqueIsEdge(currgraph, i, j) 
                     && (!COLORprobIsNodeInArray(probdata->new2oldnode[j], probdata->deletednodes, ndeletednodes)) )
                     /** @todo only check nodes deleted in the last round */
                  {
                     /* check whether nodes adjacent to i are also adjacent to j <-> j dominates i */
                     dominates = TRUE;
                     /* get adjacent nodes for node i in currgraph */
                     firstedge = tcliqueGetFirstAdjedge(currgraph, i);
                     lastedge = tcliqueGetLastAdjedge(currgraph, i);
                     while ( firstedge <= lastedge )
                     {
                        /* check whether (j,firstedge) is in currgraph, if not, j doesn't dominate i */
                        if ( !tcliqueIsEdge(currgraph, j, *firstedge) )
                        {
                           dominates = FALSE;
                           break;
                        }
                        firstedge++;
                     }
                     if ( dominates )
                     {
                        probdata->deletednodes[ndeletednodes] = probdata->new2oldnode[i];
                        changed = TRUE;
                        ndeletednodes++;
                        nnodesdeletedneighbourthisround++;
                        break; /* for j, because we already now that i is dominated and deleted i */
                     }
                  }
               } /* end for j */
               
               /* if i is dominated by no other node and thus not deleted, 
                  put it into newnodes, so that it is in the next graph */
               if ( ndeletednodes == 0 || probdata->deletednodes[ndeletednodes-1] != probdata->new2oldnode[i])
               {
                  newnodes[actnewnode] = probdata->new2oldnode[i];
                  actnewnode++;
               }
            }
            /* if i is in the maxClique und was thus not deleted,
               put it into newnodes, so that it is in the next graph */
            else
            {
               newnodes[actnewnode] = probdata->new2oldnode[i];
               actnewnode++;
            }
         } /*end for i */

         /* at least one node was deletet, create new graph ( tclique doesn't support deletion of nodes) */
         if ( changed )
         {
            assert(actnewnode+ndeletednodes == COLORprobGetOriginalNNodes(scip));
            /* create new current graph */
            tcliqueFree(&currgraph);

            if( !tcliqueCreate(&currgraph) )
            {
               SCIPerrorMessage("could not create the clique graph\n");
               return SCIP_ERROR;
            }

            assert(currgraph != NULL);

            if( !tcliqueAddNode(currgraph, actnewnode-1, 0) )
            {
               SCIPerrorMessage("could not add a node to the clique graph\n");
               return SCIP_ERROR;
            }

            for ( i = 0; i < actnewnode; i++ )
            {
               /* get adjacent nodes for node newnodes[i] */
               firstedge = tcliqueGetFirstAdjedge(probdata->oldgraph, newnodes[i]);
               lastedge = tcliqueGetLastAdjedge(probdata->oldgraph, newnodes[i]);
               while ( firstedge <= lastedge )
               {
                  /* try to find a node in newnodes which corresponds 
                     to the node in the old graph, that is the end-node of the edge */
                  for ( j = i+1; j < actnewnode; j++ )
                  {
                     if ( *firstedge == newnodes[j] )
                     {

                        if( !tcliqueAddEdge(currgraph, i, j) )
                        {
                           SCIPerrorMessage("could not add an edge to the clique graph\n");
                           return SCIP_ERROR;
                        }
                        break;
                     }
                  }
                  firstedge++;
               }
            }

            if( !tcliqueFlush(currgraph) )
            {
               SCIPerrorMessage("could not flush the clique graph\n");
               return SCIP_ERROR;
            }

            /* update currnnodes */
            currnnodes = tcliqueGetNNodes(currgraph);

            /* update new2oldnodes */
            for ( i = 0; i < actnewnode; i++ )
            {
               probdata->new2oldnode[i] = newnodes[i];
            }

            /* set the corresponding old node to -1 for all nodes not in the current graph (only for bug-finding) */
            for ( i = actnewnode; i < COLORprobGetOriginalNNodes(scip); i++ )
            {
               probdata->new2oldnode[i] = -1;
            }
         }
      } /* end of loop for finding dominated neighbourhoods */
      
      printf("Round %d of preprocessing:\n", myround);
      printf("   deleted low degree vertices: %d\n", nnodesdeleteddegreethisround);
      printf("   deleted almost cliques:      %d\n", nnodesdeletedneighbourthisround);

   }

   for ( i = ndeletednodes; i < COLORprobGetOriginalNNodes(scip); i++ )
   {
      probdata->deletednodes[i] = -1;
   }

   printf("preprocessing overall deleted vertices: %d\n\n", ndeletednodes);
   /* copy preprocessed graph into problem data */
   probdata->graph = currgraph;

   SCIPfreeBufferArray(scip, &newnodes);
   SCIPfreeBufferArray(scip, &maxcliquenodes);

   return SCIP_OKAY;
}
Esempio n. 20
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;
}
Esempio n. 21
0
/** performs the all fullstrong branching */
static
SCIP_RETCODE branch(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
   SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
   )
{
   SCIP_BRANCHRULEDATA* branchruledata;
   SCIP_VAR** pseudocands;
   SCIP_Real bestdown;
   SCIP_Real bestup;
   SCIP_Real bestscore;
   SCIP_Real provedbound;
   SCIP_Bool exactsolve;
   SCIP_Bool allcolsinlp;
   SCIP_Bool bestdownvalid;
   SCIP_Bool bestupvalid;
   int npseudocands;
   int npriopseudocands;
   int bestpseudocand;
#ifndef NDEBUG
   SCIP_Real cutoffbound;
   cutoffbound = SCIPgetCutoffbound(scip);
#endif

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

   /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */
   allcolsinlp = SCIPallColsInLP(scip);

   /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful
    * for cutting off sub problems and improving lower bounds of children
    */
   exactsolve = SCIPisExactSolve(scip);

   /* get branching rule data */
   branchruledata = SCIPbranchruleGetData(branchrule);
   assert(branchruledata != NULL);

   if( branchruledata->skipdown == NULL )
   {
      int nvars;
      nvars = SCIPgetNVars(scip);

      assert(branchruledata->skipup == NULL);

      SCIP_CALL( SCIPallocMemoryArray(scip, &branchruledata->skipdown, nvars) );
      SCIP_CALL( SCIPallocMemoryArray(scip, &branchruledata->skipup, nvars) );
      BMSclearMemoryArray(branchruledata->skipdown, nvars);
      BMSclearMemoryArray(branchruledata->skipup, nvars);
   }

   /* get all non-fixed variables (not only the fractional ones) */
   SCIP_CALL( SCIPgetPseudoBranchCands(scip, &pseudocands, &npseudocands, &npriopseudocands) );
   assert(npseudocands > 0);
   assert(npriopseudocands > 0);

   SCIP_CALL( SCIPselectVarPseudoStrongBranching(scip, pseudocands, branchruledata->skipdown, branchruledata->skipup, npseudocands, npriopseudocands,
      allowaddcons, &bestpseudocand, &bestdown, &bestup, &bestscore, &bestdownvalid, &bestupvalid, &provedbound, result) );

   if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM && *result != SCIP_CONSADDED )
   {
      SCIP_NODE* downchild;
      SCIP_NODE* eqchild;
      SCIP_NODE* upchild;
      SCIP_VAR* var;

      assert(*result == SCIP_DIDNOTRUN);
      assert(0 <= bestpseudocand && bestpseudocand < npseudocands);
      assert(SCIPisLT(scip, provedbound, cutoffbound));

      var = pseudocands[bestpseudocand];

      /* perform the branching */
      SCIPdebugMessage(" -> %d candidates, selected candidate %d: variable <%s>[%g,%g] (solval=%g, down=%g, up=%g, score=%g)\n",
         npseudocands, bestpseudocand, SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), SCIPvarGetLPSol(var),
         bestdown, bestup, bestscore);
      SCIP_CALL( SCIPbranchVarVal(scip, var, SCIPvarGetLPSol(var), &downchild, &eqchild, &upchild) );

      /* update the lower bounds in the children */
      if( allcolsinlp && !exactsolve )
      {
         if( downchild != NULL )
         {
            SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, bestdownvalid ? MAX(bestdown, provedbound) : provedbound) );
            SCIPdebugMessage(" -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild));
         }
         if( eqchild != NULL )
         {
            SCIP_CALL( SCIPupdateNodeLowerbound(scip, eqchild, provedbound) );
            SCIPdebugMessage(" -> eq child's lowerbound:   %g\n", SCIPnodeGetLowerbound(eqchild));
         }
         if( upchild != NULL )
         {
            SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, bestupvalid ? MAX(bestup, provedbound) : provedbound) );
            SCIPdebugMessage(" -> up child's lowerbound:   %g\n", SCIPnodeGetLowerbound(upchild));
         }
      }

      *result = SCIP_BRANCHED;
   }

   return SCIP_OKAY;
}
Esempio n. 22
0
/** reads an objective or constraint with name and coefficients */
static
SCIP_RETCODE readCoefficients(
   SCIP*                 scip,               /**< SCIP data structure */
   LPINPUT*              lpinput,            /**< LP reading data */
   SCIP_Bool             isobjective,        /**< indicates whether we are currently reading the coefficients of the objective */
   char*                 name,               /**< pointer to store the name of the line; must be at least of size
                                              *   LP_MAX_LINELEN */
   SCIP_VAR***           vars,               /**< pointer to store the array with variables (must be freed by caller) */
   SCIP_Real**           coefs,              /**< pointer to store the array with coefficients (must be freed by caller) */
   int*                  ncoefs,             /**< pointer to store the number of coefficients */
   SCIP_Bool*            newsection          /**< pointer to store whether a new section was encountered */
   )
{
   SCIP_Bool havesign;
   SCIP_Bool havevalue;
   SCIP_Real coef;
   int coefsign;
   int coefssize;

   assert(lpinput != NULL);
   assert(name != NULL);
   assert(vars != NULL);
   assert(coefs != NULL);
   assert(ncoefs != NULL);
   assert(newsection != NULL);

   *vars = NULL;
   *coefs = NULL;
   *name = '\0';
   *ncoefs = 0;
   *newsection = FALSE;

   /* read the first token, which may be the name of the line */
   if( getNextToken(scip, lpinput) )
   {
      /* check if we reached a new section */
      if( isNewSection(scip, lpinput) )
      {
         *newsection = TRUE;
         return SCIP_OKAY;
      }

      /* remember the token in the token buffer */
      swapTokenBuffer(lpinput);

      /* get the next token and check, whether it is a colon */
      if( getNextToken(scip, lpinput) )
      {
         if( strcmp(lpinput->token, ":") == 0 )
         {
            /* the second token was a colon: the first token is the line name */
            (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', LP_MAX_LINELEN);

            name[LP_MAX_LINELEN - 1] = '\0';
            SCIPdebugMessage("(line %d) read constraint name: '%s'\n", lpinput->linenumber, name);
         }
         else
         {
            /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
            pushToken(lpinput);
            pushBufferToken(lpinput);
         }
      }
      else
      {
         /* there was only one token left: push it back onto the token stack and parse it as coefficient */
         pushBufferToken(lpinput);
      }
   }

   /* initialize buffers for storing the coefficients */
   coefssize = LP_INIT_COEFSSIZE;
   SCIP_CALL( SCIPallocMemoryArray(scip, vars, coefssize) );
   SCIP_CALL( SCIPallocMemoryArray(scip, coefs, coefssize) );

   /* read the coefficients */
   coefsign = +1;
   coef = 1.0;
   havesign = FALSE;
   havevalue = FALSE;
   *ncoefs = 0;
   while( getNextToken(scip, lpinput) )
   {
      SCIP_VAR* var;

      /* check if we read a sign */
      if( isSign(lpinput, &coefsign) )
      {
         SCIPdebugMessage("(line %d) read coefficient sign: %+d\n", lpinput->linenumber, coefsign);
         havesign = TRUE;
         continue;
      }

      /* check if we read a value */
      if( isValue(scip, lpinput, &coef) )
      {
         SCIPdebugMessage("(line %d) read coefficient value: %g with sign %+d\n", lpinput->linenumber, coef, coefsign);
         if( havevalue )
         {
            syntaxError(scip, lpinput, "two consecutive values.");
            return SCIP_OKAY;
         }
         havevalue = TRUE;
         continue;
      }

      /* check if we reached an equation sense */
      if( isSense(lpinput, NULL) )
      {
         if( isobjective )
         {
            syntaxError(scip, lpinput, "no sense allowed in objective");
            return SCIP_OKAY;
         }

         /* put the sense back onto the token stack */
         pushToken(lpinput);
         break;
      }

      /* check if we reached a new section, that will be only allowed when having no current sign and value and if we
       * are not in the quadratic part
       */
      if( (isobjective || (!havevalue && !havesign)) && isNewSection(scip, lpinput) )
      {
         if( havesign && !havevalue )
         {
            SCIPwarningMessage(scip, "skipped single sign %c without value or variable in objective\n", coefsign == 1 ? '+' : '-');
         }
         else if( isobjective && havevalue && !SCIPisZero(scip, coef) )
         {
            SCIPwarningMessage(scip, "constant term %+g in objective is skipped\n", coef * coefsign);
         }

         *newsection = TRUE;
         return SCIP_OKAY;
      }

      /* check if we start a quadratic part */
      if( *lpinput->token ==  '[' )
      {
         syntaxError(scip, lpinput, "diff reader does not support quadratic objective function.");
         return SCIP_READERROR;
      }

      /* all but the first coefficient need a sign */
      if( *ncoefs > 0 && !havesign )
      {
         syntaxError(scip, lpinput, "expected sign ('+' or '-') or sense ('<' or '>').");
         return SCIP_OKAY;
      }

      /* check if the last variable should be squared */
      if( *lpinput->token == '^' )
      {
         syntaxError(scip, lpinput, "diff reader does not support quadratic objective function.");
         return SCIP_READERROR;
      }
      else
      {
         /* the token is a variable name: get the corresponding variable */
         SCIP_CALL( getVariable(scip, lpinput->token, &var) );
      }

      /* insert the linear coefficient */
      SCIPdebugMessage("(line %d) read linear coefficient: %+g<%s>\n", lpinput->linenumber, coefsign * coef, SCIPvarGetName(var));
      if( !SCIPisZero(scip, coef) )
      {
         /* resize the vars and coefs array if needed */
         if( *ncoefs >= coefssize )
         {
            coefssize *= 2;
            coefssize = MAX(coefssize, (*ncoefs)+1);
            SCIP_CALL( SCIPreallocMemoryArray(scip, vars, coefssize) );
            SCIP_CALL( SCIPreallocMemoryArray(scip, coefs, coefssize) );
         }
         assert(*ncoefs < coefssize);

         /* add coefficient */
         (*vars)[*ncoefs] = var;
         (*coefs)[*ncoefs] = coefsign * coef;
         (*ncoefs)++;
      }

      /* reset the flags and coefficient value for the next coefficient */
      coefsign = +1;
      coef = 1.0;
      havesign = FALSE;
      havevalue = FALSE;
   }

   return SCIP_OKAY;
}
Esempio n. 23
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;
}
Esempio n. 24
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;
}