/** creates all node-constraints and saves them in an array */ SCIP_RETCODE COLORprobSetUpArrayOfCons( SCIP* scip /**< SCIP data structure */ ) { SCIP_CONS** constraints; int nnodes; int i; assert(scip != NULL); constraints = COLORprobGetConstraints(scip); assert(constraints != NULL); nnodes = COLORprobGetNNodes(scip); for ( i = 0; i < nnodes; i++ ) { char consname[SCIP_MAXSTRLEN]; /* create the constraint */ sprintf(consname, "Node-Constraint%d", i+1); SCIP_CALL( SCIPcreateConsSetcover(scip, &constraints[i], consname, 0, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE) ); SCIP_CALL( SCIPaddCons(scip, constraints[i]) ); } return SCIP_OKAY; }
/* Read SAT formula in "CNF File Format". * * The specification is taken from the * * Satisfiability Suggested Format * * Online available at http://www.intellektik.informatik.tu-darmstadt.de/SATLIB/Benchmarks/SAT/satformat.ps * * The method reads all files of CNF format. Other formats (SAT, SATX, SATE) are not supported. */ static SCIP_RETCODE readCnf( SCIP* scip, /**< SCIP data structure */ SCIP_FILE* file /**< input file */ ) { SCIP_RETCODE retcode; SCIP_VAR** vars; SCIP_VAR** clausevars; SCIP_CONS* cons; int* varsign; char* tok; char* nexttok; char line[MAXLINELEN]; char format[SCIP_MAXSTRLEN]; char varname[SCIP_MAXSTRLEN]; char s[SCIP_MAXSTRLEN]; SCIP_Bool dynamicconss; SCIP_Bool dynamiccols; SCIP_Bool dynamicrows; SCIP_Bool useobj; int linecount; int clauselen; int clausenum; int nvars; int nclauses; int varnum; int v; assert(scip != NULL); assert(file != NULL); retcode = SCIP_OKAY; linecount = 0; /* read header */ SCIP_CALL( readCnfLine(scip, file, line, (int) sizeof(line), &linecount) ); if( *line != 'p' ) { readError(scip, linecount, "problem declaration line expected"); return SCIP_READERROR; } if( sscanf(line, "p %8s %d %d", format, &nvars, &nclauses) != 3 ) { readError(scip, linecount, "invalid problem declaration (must be 'p cnf <nvars> <nclauses>')"); return SCIP_READERROR; } if( strcmp(format, "cnf") != 0 ) { (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "invalid format tag <%s> (must be 'cnf')", format); readError(scip, linecount, s); return SCIP_READERROR; } if( nvars <= 0 ) { (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "invalid number of variables <%d> (must be positive)", nvars); readError(scip, linecount, s); return SCIP_READERROR; } if( nclauses <= 0 ) { (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "invalid number of clauses <%d> (must be positive)", nclauses); readError(scip, linecount, s); return SCIP_READERROR; } /* get parameter values */ SCIP_CALL( SCIPgetBoolParam(scip, "reading/cnfreader/dynamicconss", &dynamicconss) ); SCIP_CALL( SCIPgetBoolParam(scip, "reading/cnfreader/dynamiccols", &dynamiccols) ); SCIP_CALL( SCIPgetBoolParam(scip, "reading/cnfreader/dynamicrows", &dynamicrows) ); SCIP_CALL( SCIPgetBoolParam(scip, "reading/cnfreader/useobj", &useobj) ); /* get temporary memory */ SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) ); SCIP_CALL( SCIPallocBufferArray(scip, &clausevars, nvars) ); SCIP_CALL( SCIPallocBufferArray(scip, &varsign, nvars) ); /* create the variables */ for( v = 0; v < nvars; ++v ) { (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x%d", v+1); SCIP_CALL( SCIPcreateVar(scip, &vars[v], varname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) ); SCIP_CALL( SCIPaddVar(scip, vars[v]) ); varsign[v] = 0; } /* read clauses */ clausenum = 0; clauselen = 0; do { retcode = readCnfLine(scip, file, line, (int) sizeof(line), &linecount); if( retcode != SCIP_OKAY ) goto TERMINATE; if( *line != '\0' && *line != '%' ) { tok = SCIPstrtok(line, " \f\n\r\t", &nexttok); while( tok != NULL ) { /* parse literal and check for errors */ if( sscanf(tok, "%d", &v) != 1 ) { (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "invalid literal <%s>", tok); readError(scip, linecount, s); retcode = SCIP_READERROR; goto TERMINATE; } /* interpret literal number: v == 0: end of clause, v < 0: negated literal, v > 0: positive literal */ if( v == 0 ) { /* end of clause: construct clause and add it to SCIP */ if( clauselen == 0 ) readWarning(scip, linecount, "empty clause detected in line -- problem infeasible"); clausenum++; (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "c%d", clausenum); if( SCIPfindConshdlr(scip, "logicor") != NULL ) { /* if the constraint handler logicor exit create a logicor constraint */ SCIP_CALL( SCIPcreateConsLogicor(scip, &cons, s, clauselen, clausevars, !dynamicrows, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) ); } else if( SCIPfindConshdlr(scip, "setppc") != NULL ) { /* if the constraint handler logicor does not exit but constraint * handler setppc create a setppc constraint */ SCIP_CALL( SCIPcreateConsSetcover(scip, &cons, s, clauselen, clausevars, !dynamicrows, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) ); } else { /* if none of the previous constraint handler exits create a linear * constraint */ SCIP_Real* vals; int i; SCIP_CALL( SCIPallocBufferArray(scip, &vals, clauselen) ); for( i = 0; i < clauselen; ++i ) vals[i] = 1.0; SCIP_CALL( SCIPcreateConsLinear(scip, &cons, s, clauselen, clausevars, vals, 1.0, SCIPinfinity(scip), !dynamicrows, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) ); SCIPfreeBufferArray(scip, &vals); } SCIP_CALL( SCIPaddCons(scip, cons) ); SCIP_CALL( SCIPreleaseCons(scip, &cons) ); clauselen = 0; } else if( v >= -nvars && v <= nvars ) { if( clauselen >= nvars ) { readError(scip, linecount, "too many literals in clause"); retcode = SCIP_READERROR; goto TERMINATE; } /* add literal to clause */ varnum = ABS(v)-1; if( v < 0 ) { SCIP_CALL( SCIPgetNegatedVar(scip, vars[varnum], &clausevars[clauselen]) ); varsign[varnum]--; } else { clausevars[clauselen] = vars[varnum]; varsign[varnum]++; } clauselen++; } else { (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "invalid variable number <%d>", ABS(v)); readError(scip, linecount, s); retcode = SCIP_READERROR; goto TERMINATE; } /* get next token */ tok = SCIPstrtok(NULL, " \f\n\r\t", &nexttok); } } } while( *line != '\0' && *line != '%' ); /* check for additional literals */ if( clauselen > 0 ) { SCIPwarningMessage(scip, "found %d additional literals after last clause\n", clauselen); } /* check number of clauses */ if( clausenum != nclauses ) { SCIPwarningMessage(scip, "expected %d clauses, but found %d\n", nclauses, clausenum); } TERMINATE: /* change objective values and release variables */ SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) ); if( useobj ) { for( v = 0; v < nvars; ++v ) { SCIP_CALL( SCIPchgVarObj(scip, vars[v], (SCIP_Real)varsign[v]) ); SCIP_CALL( SCIPreleaseVar(scip, &vars[v]) ); } } /* free temporary memory */ SCIPfreeBufferArray(scip, &varsign); SCIPfreeBufferArray(scip, &clausevars); SCIPfreeBufferArray(scip, &vars); return retcode; }