예제 #1
0
/** reads the masterconss section */
static
SCIP_RETCODE readMasterconss(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput,           /**< BLK reading data */
    SCIP_READERDATA*      readerdata          /**< reader data */
)
{
    assert(blkinput != NULL);

    while( getNextToken(blkinput) )
    {
        SCIP_CONS* cons;

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

        /* the token must be the name of an existing constraint */
        cons = SCIPfindCons(scip, blkinput->token);
        if( cons == NULL )
        {
            syntaxError(scip, blkinput, "unknown constraint in masterconss section");
            return SCIP_OKAY;
        }
        else
        {
            assert(SCIPhashmapGetImage(readerdata->constoblock, cons) == (void*)(size_t)NOVALUE);
            SCIP_CALL( SCIPhashmapSetImage(readerdata->constoblock, cons, (void*)(size_t) (blkinput->nblocks +1)) );
        }
    }

    return SCIP_OKAY;
}
예제 #2
0
/** reads the nblocks section */
static
SCIP_RETCODE readNBlocks(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput            /**< BLK reading data */
)
{
    int nblocks;

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

    while( getNextToken(blkinput) )
    {
        /* check if we reached a new section */
        if( isNewSection(scip, blkinput) )
        {
            if( blkinput->nblocks == NOVALUE )
                syntaxError(scip, blkinput, "no integer value in nblocks section");
            else
                return SCIP_OKAY;
        }

        /* read number of blocks */
        if( isInt(scip, blkinput, &nblocks) )
        {
            if( blkinput->nblocks == NOVALUE )
                blkinput->nblocks = nblocks;
            else
                syntaxError(scip, blkinput, "2 integer values in nblocks section");
            SCIPdebugMessage("Number of blocks = %d\n", blkinput->nblocks);
        }
    }

    return SCIP_OKAY;
}
예제 #3
0
/** reads the presolved section */
static
SCIP_RETCODE readPresolved(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput            /**< DEC reading data */
)
{
    int presolved;

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

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

        /* read number of blocks */
        if( isInt(scip, blkinput, &presolved) )
        {
            blkinput->haspresolvesection = TRUE;
            if( presolved == 1 )
                blkinput->presolved = TRUE;
            else if ( presolved == 0 )
                blkinput->presolved = FALSE;
            else
                syntaxError(scip, blkinput, "presolved parameter must be 0 or 1");
            SCIPdebugMessage("Decomposition is%s from presolved problem\n",
                             blkinput->presolved ? "" : " not");
        }
    }

    return SCIP_OKAY;
}
예제 #4
0
/** reads the header of the file */
static
SCIP_RETCODE readStart(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput            /**< BLK reading data */
)
{
    assert(blkinput != NULL);

    /* everything before first section is treated as comment */
    do
    {
        /* get token */
        if( !getNextToken(blkinput) )
            return SCIP_OKAY;
    }
    while( !isNewSection(scip, blkinput) );

    return SCIP_OKAY;
}
예제 #5
0
/** reads the masterconss section */
static
SCIP_RETCODE readMasterconss(
    SCIP*                 scip,               /**< SCIP data structure */
    DECINPUT*             decinput,           /**< DEC reading data */
    SCIP_READERDATA*      readerdata          /**< reader data */
)
{
    assert(scip != NULL);
    assert(decinput != NULL);
    assert(readerdata != NULL);

    while( getNextToken(decinput) )
    {
        SCIP_CONS* cons;

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

        /* the token must be the name of an existing constraint */
        cons = SCIPfindCons(scip, decinput->token);
        if( cons == NULL )
        {
            syntaxError(scip, decinput, "unknown constraint in masterconss section");
            break;
        }
        else
        {
            if( !SCIPhashmapExists( readerdata->constoblock, cons) )
            {
                SCIPwarningMessage(scip, "Cons <%s> has been deleted by presolving, skipping.\n", SCIPconsGetName(cons));
                continue;
            }

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

            SCIPdebugMessage("cons %s is linking constraint\n", decinput->token);
        }
    }

    return SCIP_OKAY;
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
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;
}