Beispiel #1
0
/** creates and captures an and constraint
 *  in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
 *  method SCIPcreateConsConjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
 *
 *  @see SCIPcreateConsConjunction() for information about the basic constraint flag configuration
 *
 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
 */
SCIP_RETCODE SCIPcreateConsBasicConjunction(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
   const char*           name,               /**< name of constraint */
   int                   nconss,             /**< number of initial constraints in conjunction */
   SCIP_CONS**           conss               /**< initial constraint in conjunction */
   )
{
   assert(scip != NULL);

   SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
         TRUE, TRUE, FALSE, FALSE, FALSE) );

   return SCIP_OKAY;
}
Beispiel #2
0
/** constraint parsing method of constraint handler */
static
SCIP_DECL_CONSPARSE(consParseConjunction)
{  /*lint --e{715}*/
   SCIP_CONS** conss;
   int nconss;
   int sconss;
   char* token;
   char* saveptr;
   char* nexttokenstart;
   char* copystr;

   assert(scip != NULL);
   assert(conshdlr != NULL);
   assert(cons != NULL);
   assert(success != NULL);
   assert(str != NULL);
   assert(name != NULL);

   SCIPdebugMessage("parsing conjunction <%s>\n", name);

   *success = TRUE;

   /* allocate memory for constraint in conjunction, initial size is set to 10 */
   nconss = 0;
   sconss = 10;
   SCIP_CALL( SCIPallocBufferArray(scip, &conss, sconss) );
   SCIP_CALL( SCIPduplicateBufferArray(scip, &copystr, str, (int)strlen(str)+1) );

   /* find '(' at the beginning, string should start with 'conjunction(' */
   saveptr = strpbrk(copystr, "("); /*lint !e158*/

   if( saveptr == NULL )
   {
      SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
      *success = FALSE;
      goto TERMINATE;
   }

   /* skip '(' */
   ++saveptr;
   /* remember token start position */
   nexttokenstart = saveptr;

   /* brackets '(' and ')' can exist co we check for them and the constraint delimeter */
   saveptr = strpbrk(saveptr, "(,");

   /* brackets '(' and ')' can exist in the rest of the string so we need to skip them to find the end of the first
    * sub-constraint marked by a ','
    */
   if( saveptr != NULL )
   {
      do
      {
	 int bracketcounter = 0;

	 if( *saveptr == '(' )
	 {
	    do
	    {
	       ++bracketcounter;
	       ++saveptr;

	       /* find last ending bracket */
	       while( bracketcounter > 0 )
	       {
		  saveptr = strpbrk(saveptr, "()");

		  if( saveptr != NULL )
		  {
		     if( *saveptr == '(' )
			++bracketcounter;
		     else
			--bracketcounter;

		     ++saveptr;
		  }
		  else
		  {
		     SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
		     *success = FALSE;
		     goto TERMINATE;
		  }
	       }

	       saveptr = strpbrk(saveptr, "(,");
	    }
	    while( saveptr != NULL && *saveptr == '(' );
	 }

	 /* we found a ',' so the end of the first sub-constraint is determined */
	 if( saveptr != NULL )
	 {
	    assert(*saveptr == ',');

	    /* resize constraint array if necessary */
	    if( nconss == sconss )
	    {
	       sconss = SCIPcalcMemGrowSize(scip, nconss+1);
	       assert(nconss < sconss);

	       SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
	    }

	    assert(saveptr > nexttokenstart);

	    /* extract token for parsing */
	    SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
	    token[saveptr - nexttokenstart] = '\0';

	    SCIPdebugMessage("conjunctive parsing token(constraint): %s\n", token);

	    /* parsing a constraint, part of the conjunction */
	    SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );

	    SCIPfreeBufferArray(scip, &token);

	    if( *success )
	       ++nconss;
	    else
	    {
	       SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
	       goto TERMINATE;
	    }
	    /* skip ',' delimeter */
	    ++saveptr;
	    /* remember token start position */
	    nexttokenstart = saveptr;

	    saveptr = strpbrk(saveptr, "(,");
	 }
      }
      while( saveptr != NULL );
   }

   /* find end of conjunction constraint */
   saveptr = strrchr(nexttokenstart, ')');

   if( saveptr == NULL )
   {
      SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
      *success = FALSE;
      goto TERMINATE;
   }
   /* parse last sub-constraint */
   else
   {
      /* resize constraint array if necessary */
      if( nconss == sconss )
      {
	 ++sconss;
	 SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
      }

      assert(saveptr > nexttokenstart);

      /* extract token for parsing */
      SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
      token[saveptr - nexttokenstart] = '\0';

      SCIPdebugMessage("conjunctive parsing token(constraint): %s\n", token);

      /* parsing a constraint, part of the conjunction */
      SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );

      if( *success )
	 ++nconss;

      SCIPfreeBufferArray(scip, &token);
   }
   assert(nconss > 0 || !(*success));

   /* if parsing sub-constraints was fine, create the conjunctive constraint */
   if( *success )
   {
      /* create conjunctive constraint */
      SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
	    enforce, check, local, modifiable, dynamic) );
   }

   /* free parsed constraints */
   for( --nconss; nconss >= 0; --nconss )
   {
      SCIP_CALL( SCIPreleaseCons(scip, &conss[nconss]) );
   }

 TERMINATE:
   /* free temporary memory */
   SCIPfreeBufferArray(scip, &copystr);
   SCIPfreeBufferArray(scip, &conss);

   return SCIP_OKAY;
}
/** constraint copying method of constraint handler */
static
SCIP_DECL_CONSCOPY(consCopyConjunction)
{  /*lint --e{715}*/
   SCIP_CONSDATA* sourcedata;
   SCIP_CONS** sourceconss;
   SCIP_CONS** conss;
   int nconss;
   int c;

   *valid = TRUE;

   sourcedata = SCIPconsGetData(sourcecons);
   assert(sourcedata != NULL);

   sourceconss = sourcedata->conss;
   nconss = sourcedata->nconss;

   if( nconss > 0 )
   {
      assert(sourceconss != NULL);

      SCIP_CALL( SCIPallocBufferArray(scip, &conss, nconss) );

      /* copy each constraint one by one */
      for( c = 0; c < nconss && (*valid); ++c )
      {
         SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceconss[c], &conss[c], SCIPconsGetHdlr(sourceconss[c]),
               varmap, consmap, SCIPconsGetName(sourceconss[c]),
               SCIPconsIsInitial(sourceconss[c]), SCIPconsIsSeparated(sourceconss[c]), SCIPconsIsEnforced(sourceconss[c]),
               SCIPconsIsChecked(sourceconss[c]), SCIPconsIsPropagated(sourceconss[c]),
               SCIPconsIsLocal(sourceconss[c]), SCIPconsIsModifiable(sourceconss[c]),
               SCIPconsIsDynamic(sourceconss[c]), SCIPconsIsRemovable(sourceconss[c]), SCIPconsIsStickingAtNode(sourceconss[c]),
               global, valid) );
         assert(!(*valid) || conss[c] != NULL);
      }

      if( *valid )
      {
         if( name == NULL )
         {
            SCIP_CALL( SCIPcreateConsConjunction(scip, cons, SCIPconsGetName(sourcecons), nconss, conss,
                  enforce, check, local, modifiable, dynamic) );
         }
         else
         {
            SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
                  enforce, check, local, modifiable, dynamic) );
         }
      }

      /* release the copied constraints */
      for( c = (*valid ? c - 1 : c - 2); c >= 0; --c )
      {
         assert(conss[c] != NULL);
         SCIP_CALL( SCIPreleaseCons(scip, &conss[c]) );
      }

      SCIPfreeBufferArray(scip, &conss);
   }

   return SCIP_OKAY;
}