Esempio n. 1
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. 2
0
/** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
static
SCIP_Bool isNewSection(
    SCIP*                 scip,               /**< SCIP data structure */
    BLKINPUT*             blkinput            /**< BLK reading data */
)
{
    SCIP_Bool iscolon;

    assert(blkinput != NULL);

    /* remember first token by swapping the token buffer */
    swapTokenBuffer(blkinput);

    /* look at next token: if this is a ':', the first token is a name and no section keyword */
    iscolon = FALSE;
    if( getNextToken(blkinput) )
    {
        iscolon = (strcmp(blkinput->token, ":") == 0);
        pushToken(blkinput);
    }

    /* reinstall the previous token by swapping back the token buffer */
    swapTokenBuffer(blkinput);

    /* check for ':' */
    if( iscolon )
        return FALSE;

    if( strcasecmp(blkinput->token, "PRESOLVED") == 0 )
    {
        SCIPdebugMessage("(line %d) new section: PRESOLVED\n", blkinput->linenumber);
        blkinput->section = BLK_PRESOLVED;
        return TRUE;
    }

    if( strcasecmp(blkinput->token, "NBLOCKS") == 0 )
    {
        SCIPdebugMessage("(line %d) new section: NBLOCKS\n", blkinput->linenumber);
        blkinput->section = BLK_NBLOCKS;
        return TRUE;
    }

    if( strcasecmp(blkinput->token, "BLOCK") == 0 )
    {
        int blocknr;

        blkinput->section = BLK_BLOCK;

        if( getNextToken(blkinput) )
        {
            /* read block number */
            if( isInt(scip, blkinput, &blocknr) )
            {
                assert(blocknr >= 0);
                assert(blocknr <= blkinput->nblocks);

                blkinput->blocknr = blocknr-1;
            }
            else
                syntaxError(scip, blkinput, "no block number after block keyword!\n");
        }
        else
            syntaxError(scip, blkinput, "no block number after block keyword!\n");

        SCIPdebugMessage("new section: BLOCK %d\n", blkinput->blocknr);

        return TRUE;

    }

    if( strcasecmp(blkinput->token, "MASTERCONSS") == 0 )
    {
        blkinput->section = BLK_MASTERCONSS;

        SCIPdebugMessage("new section: MASTERCONSS\n");

        return TRUE;
    }

    if( strcasecmp(blkinput->token, "END") == 0 )
    {
        SCIPdebugMessage("(line %d) new section: END\n", blkinput->linenumber);
        blkinput->section = BLK_END;
        return TRUE;
    }

    return FALSE;
}
Esempio n. 3
0
/** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
static
SCIP_Bool isNewSection(
   SCIP*                 scip,               /**< SCIP data structure */
   LPINPUT*              lpinput             /**< LP reading data */
   )
{
   SCIP_Bool iscolon;
   size_t len;

   assert(lpinput != NULL);

   /* remember first token by swapping the token buffer */
   swapTokenBuffer(lpinput);

   /* look at next token: if this is a ':', the first token is a name and no section keyword */
   iscolon = FALSE;
   if( getNextToken(scip, lpinput) )
   {
      iscolon = (*lpinput->token == ':');
      pushToken(lpinput);
   }

   /* reinstall the previous token by swapping back the token buffer */
   swapTokenBuffer(lpinput);

   /* check for ':' */
   if( iscolon )
      return FALSE;

   len = strlen(lpinput->token);
   assert(len < LP_MAX_LINELEN);

   /* the section keywords are at least 2 characters up to 8 or exactly 15 characters long */
   if( len > 1 && (len < 9 || len == 15) )
   {
      char token[16];
      int c = 0;

      while( lpinput->token[c] != '\0' )
      {
         token[c] = toupper(lpinput->token[c]); /*lint !e734*/
         ++c;
         assert(c < 16);
      }
      token[c] = '\0';

      if( (len == 3 && strcmp(token, "MIN") == 0)
         || (len == 7 && strcmp(token, "MINIMUM") == 0)
         || (len == 8 && strcmp(token, "MINIMIZE") == 0) )
      {
         SCIPdebugMessage("(line %d) new section: OBJECTIVE\n", lpinput->linenumber);
         lpinput->section = LP_OBJECTIVE;
         lpinput->objsense = SCIP_OBJSENSE_MINIMIZE;
         return TRUE;
      }

      if( (len == 3 && strcmp(token, "MAX") == 0)
         || (len == 7 && strcmp(token, "MAXIMUM") == 0)
         || (len == 8 && strcmp(token, "MAXIMIZE") == 0) )
      {
         SCIPdebugMessage("(line %d) new section: OBJECTIVE\n", lpinput->linenumber);
         lpinput->section = LP_OBJECTIVE;
         lpinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
         return TRUE;
      }

      if( len == 3 && strcmp(token, "END") == 0 )
      {
         SCIPdebugMessage("(line %d) new section: END\n", lpinput->linenumber);
         lpinput->section = LP_END;
         return TRUE;
      }
   }

   return FALSE;
}