/** creates disjunction constraint data, captures initial constraints of disjunction */ static SCIP_RETCODE consdataCreate( SCIP* scip, /**< SCIP data structure */ SCIP_CONSDATA** consdata, /**< pointer to constraint data */ SCIP_CONS** conss, /**< initial constraint in disjunction */ int nconss /**< number of initial constraints in disjunction */ ) { assert(scip != NULL); assert(consdata != NULL); SCIP_CALL( SCIPallocBlockMemory(scip, consdata) ); if( nconss > 0 ) { assert(conss != NULL); SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->conss, conss, nconss) ); (*consdata)->consssize = nconss; (*consdata)->nconss = nconss; /* we need to capture the constraints to avoid that SCIP deletes them since they are not (yet) added to the * problem */ if( SCIPisTransformed(scip) ) { SCIP_CALL( SCIPtransformConss(scip, nconss, (*consdata)->conss, (*consdata)->conss) ); } else { int c; for( c = 0; c < nconss; ++c ) { assert(conss[c] != NULL); SCIP_CALL( SCIPcaptureCons(scip, conss[c]) ); } } } else { (*consdata)->conss = NULL; (*consdata)->consssize = 0; (*consdata)->nconss = 0; } return SCIP_OKAY; }
/** creates user data of transformed problem by transforming the original user problem data * (called after problem was transformed) */ static SCIP_DECL_PROBTRANS(probtransBinpacking) { /* create transform probdata */ SCIP_CALL( probdataCreate(scip, targetdata, sourcedata->vars, sourcedata->conss, sourcedata->weights, sourcedata->ids, sourcedata->nvars, sourcedata->nitems, sourcedata->capacity) ); /* transform all constraints */ SCIP_CALL( SCIPtransformConss(scip, (*targetdata)->nitems, (*targetdata)->conss, (*targetdata)->conss) ); /* transform all variables */ SCIP_CALL( SCIPtransformVars(scip, (*targetdata)->nvars, (*targetdata)->vars, (*targetdata)->vars) ); return SCIP_OKAY; }
/** creates conjunction constraint data, captures initial constraints of conjunction */ static SCIP_RETCODE consdataCreate( SCIP* scip, /**< SCIP data structure */ SCIP_CONSDATA** consdata, /**< pointer to constraint data */ SCIP_CONS** conss, /**< initial constraint in conjunction */ int nconss /**< number of initial constraints in conjunction */ ) { assert(consdata != NULL); SCIP_CALL( SCIPallocBlockMemory(scip, consdata) ); if( nconss > 0 ) { SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->conss, conss, nconss) ); (*consdata)->consssize = nconss; (*consdata)->nconss = nconss; if( SCIPisTransformed(scip) ) { SCIP_CALL( SCIPtransformConss(scip, nconss, (*consdata)->conss, (*consdata)->conss) ); } else { int c; for( c = 0; c < nconss; ++c ) { SCIP_CALL( SCIPcaptureCons(scip, conss[c]) ); } } } else { (*consdata)->conss = NULL; (*consdata)->consssize = 0; (*consdata)->nconss = 0; } return SCIP_OKAY; }
/** transforms the problem */ static SCIP_DECL_PROBTRANS(probtransColoring) { int i; int j; int* firstedge; int* lastedge; assert(scip != NULL); assert(sourcedata != NULL); assert(targetdata != NULL); /* allocate memory */ SCIP_CALL( SCIPallocMemory(scip, targetdata) ); if( !tcliqueCreate(&((*targetdata)->graph)) ) /* create the transformed graph */ { SCIPerrorMessage("could not create the clique graph\n"); return SCIP_ERROR; } (*targetdata)->maxstablesets = sourcedata->maxstablesets; /* copy length of array sets */ (*targetdata)->nstablesets = sourcedata->nstablesets; /* copy number of sets saved in array sets */ (*targetdata)->oldgraph = sourcedata->oldgraph; /* copy link to original graph */ /* allocate memory for sets and lenghts of the sets */ SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->stablesets), sourcedata->maxstablesets) ); SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->stablesetlengths), sourcedata->maxstablesets) ); SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->stablesetvars), sourcedata->maxstablesets) ); SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->deletednodes), tcliqueGetNNodes(sourcedata->oldgraph)) ); SCIP_CALL( SCIPallocMemoryArray(scip, &((*targetdata)->new2oldnode), tcliqueGetNNodes(sourcedata->oldgraph)) ); for ( i = 0; i < tcliqueGetNNodes(sourcedata->oldgraph); i++ ) { (*targetdata)->deletednodes[i] = sourcedata->deletednodes[i]; (*targetdata)->new2oldnode[i] = sourcedata->new2oldnode[i]; } /* copy stablesetlengths and stablesets */ for ( i = 0; i < sourcedata->nstablesets; i++ ) { assert(sourcedata->stablesetvars[i] != NULL); (*targetdata)->stablesetlengths[i] = sourcedata->stablesetlengths[i]; SCIP_CALL( SCIPtransformVar(scip, sourcedata->stablesetvars[i], &((*targetdata)->stablesetvars[i])) ); SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*targetdata)->stablesets[i]), sourcedata->stablesetlengths[i]) ); /*lint !e866*/ for ( j = 0; j <sourcedata->stablesetlengths[i]; j++ ) { (*targetdata)->stablesets[i][j] = sourcedata->stablesets[i][j]; } } /* create array for constraints */ SCIP_CALL( SCIPallocMemoryArray(scip, &(*targetdata)->constraints, tcliqueGetNNodes(sourcedata->graph)) ); /* tranform constraints */ SCIP_CALL( SCIPtransformConss(scip, tcliqueGetNNodes(sourcedata->graph), sourcedata->constraints, (*targetdata)->constraints) ); /* copy the graph */ if( !tcliqueAddNode((*targetdata)->graph, tcliqueGetNNodes(sourcedata->graph)-1, 0) ) { SCIPerrorMessage("could not add a node to the clique graph\n"); return SCIP_ERROR; } for ( i = 0; i < tcliqueGetNNodes(sourcedata->graph); i++ ) { /* get adjacent nodes for node i */ firstedge = tcliqueGetFirstAdjedge(sourcedata->graph, i); lastedge = tcliqueGetLastAdjedge(sourcedata->graph, i); while ( firstedge <= lastedge ) { if ( *firstedge > i ) { if( !tcliqueAddEdge((*targetdata)->graph, i, *firstedge) ) { SCIPerrorMessage("could not add an edge to the clique graph\n"); return SCIP_ERROR; } } firstedge++; } } if( !tcliqueFlush((*targetdata)->graph) ) { SCIPerrorMessage("could not flush the clique graph\n"); return SCIP_ERROR; } return SCIP_OKAY; }