示例#1
0
/** adds a new stable set, the set must be sorted descendingly, 
 *  attention: you need to check whether it is new before adding it
 */
SCIP_RETCODE COLORprobAddNewStableSet(
   SCIP*                 scip,               /**< SCIP data structure */
   int*                  stablesetnodes,     /**< array of nodes in the stable set */
   int                   nstablesetnodes,    /**< number of nodes in the stable set */
   int*                  setindex            /**< return value: index of the stable set */
   )
{
   SCIP_PROBDATA* probdata; 
   int newsize;
   int i;
   
   assert(stablesetnodes != NULL);
   assert(scip != NULL);
   probdata = SCIPgetProbData(scip);
   assert(probdata != NULL);

   /* the set should be sorted descendingly */
#ifndef NDEBUG
   for ( i = 0; i < nstablesetnodes-2; i++ )
   {
      assert(stablesetnodes[i]>stablesetnodes[i+1]);
   }
#endif
 
   /* ensure that array is big enough */
   if ( (probdata->nstablesets + 1) > probdata->maxstablesets)
   {
      newsize = 2* probdata->maxstablesets;
      assert(newsize >  probdata->nstablesets + 1);
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(probdata->stablesets), newsize) );
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(probdata->stablesetlengths), newsize) );
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(probdata->stablesetvars), newsize) );
      probdata->maxstablesets = newsize;
      SCIPdebugMessage("Set-array resized: %d --> %d\n", newsize/2, newsize);
   }

   /* alloc memory for the new stable set */
   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(probdata->stablesets[probdata->nstablesets]), nstablesetnodes) ); /*lint !e866*/
   probdata->stablesetlengths[probdata->nstablesets] = nstablesetnodes;
   probdata->stablesetvars[probdata->nstablesets] = NULL;
   for ( i = 0; i < nstablesetnodes; i++ )
   {
      assert(stablesetnodes[i] >= 0);
      probdata->stablesets[probdata->nstablesets][i] = stablesetnodes[i];
   }
   *setindex = probdata->nstablesets;

   probdata->nstablesets++;

   return SCIP_OKAY;
}
示例#2
0
/** adds a bound change on an original variable found by propagation in the original problem
 *  to the given origbranch constraint so that it will be transferred to the master problem */
SCIP_RETCODE GCGconsOrigbranchAddPropBoundChg(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_CONS*            cons,               /**< origbranch constraint to which the bound change is added */
   SCIP_VAR*             var,                /**< variable on which the bound change was performed */
   SCIP_BOUNDTYPE        boundtype,          /**< bound type of the bound change */
   SCIP_Real             newbound            /**< new bound of the variable after the bound change */
   )
{
   SCIP_CONSDATA* consdata;

   assert(scip != NULL);
   assert(cons != NULL);
   assert(var != NULL);

   consdata = SCIPconsGetData(cons);
   assert(consdata != NULL);

   /* realloc the arrays, if needed */
   if( consdata->npropbounds >= consdata->maxpropbounds )
   {
      consdata->maxpropbounds = consdata->npropbounds+5;
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(consdata->propvars), consdata->maxpropbounds) );
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(consdata->propboundtypes), consdata->maxpropbounds) );
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(consdata->propbounds), consdata->maxpropbounds) );
   }

   SCIPdebugMessage("Bound change stored at branch orig constraint: <%s>.\n", SCIPconsGetName(cons));

   /* store the new bound change */
   consdata->propvars[consdata->npropbounds] = var;
   consdata->propboundtypes[consdata->npropbounds] = boundtype;
   consdata->propbounds[consdata->npropbounds] = newbound;
   consdata->npropbounds++;

   /* mark the corresponding master node to be repropagated */
   if( consdata->mastercons != NULL )
   {
      SCIP_CALL( SCIPrepropagateNode(GCGrelaxGetMasterprob(scip), GCGconsMasterbranchGetNode(consdata->mastercons)) );
   }

   return SCIP_OKAY;
}
示例#3
0
/** adds given variable to the problem data */
SCIP_RETCODE SCIPprobdataAddVar(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_PROBDATA*        probdata,           /**< problem data */
   SCIP_VAR*             var                 /**< variables to add */
   )
{
   /* check if enough memory is left */
   if( probdata->varssize == probdata->nvars )
   {
      probdata->varssize = MAX(100, probdata->varssize * 2);
      SCIP_CALL( SCIPreallocMemoryArray(scip, &probdata->vars, probdata->varssize) );
   }

   /* caputure variables */
   SCIP_CALL( SCIPcaptureVar(scip, var) );

   probdata->vars[probdata->nvars] = var;
   probdata->nvars++;

   SCIPdebugMessage("added variable to probdata; nvars = %d\n", probdata->nvars);

   return SCIP_OKAY;
}
示例#4
0
/** constraint activation notification method of constraint handler */
static
SCIP_DECL_CONSACTIVE(consActiveOrigbranch)
{  /*lint --e{715}*/
   SCIP_CONSHDLRDATA* conshdlrData;

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

   conshdlrData = SCIPconshdlrGetData(conshdlr);
   assert(conshdlrData != NULL);
   assert(conshdlrData->stack != NULL);

   assert(SCIPconsGetData(cons) != NULL);

   if( SCIPconsGetData(cons)->node == NULL )
      SCIPconsGetData(cons)->node = SCIPgetRootNode(scip);

   SCIPdebugMessage("Activating branch orig constraint: <%s>[stack size: %d].\n", SCIPconsGetName(cons),
      conshdlrData->nstack+1);

   /* put constraint on the stack */
   if( conshdlrData->nstack >= conshdlrData->maxstacksize )
   {
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(conshdlrData->stack), 2*(conshdlrData->maxstacksize)) );
      conshdlrData->maxstacksize = 2*(conshdlrData->maxstacksize);
      SCIPdebugMessage("reallocating Memory for stack! %d --> %d\n", conshdlrData->maxstacksize/2, conshdlrData->maxstacksize);
   }

   /* put constraint on the stack */
   assert(conshdlrData->stack != NULL);
   conshdlrData->stack[conshdlrData->nstack] = cons;
   ++(conshdlrData->nstack);

   return SCIP_OKAY;
}
示例#5
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;
}
示例#6
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;
}