/** constraint activation notification method of constraint handler */ static SCIP_DECL_CONSACTIVE(consActiveSamediff) { /*lint --e{715}*/ SCIP_CONSDATA* consdata; assert(scip != NULL); assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0); assert(cons != NULL); consdata = SCIPconsGetData(cons); assert(consdata != NULL); assert(consdata->npropagatedvars <= SCIPprobdataGetNVars(SCIPgetProbData(scip))); SCIPdebugMessage("activate constraint <%s> at node <%"SCIP_LONGINT_FORMAT"> in depth <%d>: ", SCIPconsGetName(cons), SCIPnodeGetNumber(consdata->node), SCIPnodeGetDepth(consdata->node)); SCIPdebug( consdataPrint(scip, consdata, NULL) ); if( consdata->npropagatedvars != SCIPprobdataGetNVars(SCIPgetProbData(scip)) ) { SCIPdebugMessage("-> mark constraint to be repropagated\n"); consdata->propagated = FALSE; SCIP_CALL( SCIPrepropagateNode(scip, consdata->node) ); } return SCIP_OKAY; }
/** checks whether the given stable set is new returns TRUE if the stable is new, FALSE if it is equal to an already existing stable set */ SCIP_Bool COLORprobStableSetIsNew( SCIP* scip, /**< SCIP data structure */ int* stablesetnodes, /**< array of nodes in the stable set */ int nstablesetnodes /**< number of nodes in the stable set */ ) { SCIP_PROBDATA* probdata; int i; assert(stablesetnodes != NULL); assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); /* sort the set */ SCIPsortDownInt(stablesetnodes, nstablesetnodes); for ( i = 0; i < COLORprobGetNStableSets(scip); i++ ) { if ( COLORprobStableSetsAreEqual(scip, stablesetnodes, nstablesetnodes, probdata->stablesets[i], probdata->stablesetlengths[i]) ) { return FALSE; } } return TRUE; }
static SCIP_RETCODE selectBranchingVertex( SCIP* scip, /**< original SCIP data structure */ int* vertex /**< the vertex to branch on */ ) { SCIP_PROBDATA* probdata; SCIP_VAR** edgevars; GRAPH* g; SCIP_Real maxflow; SCIP_Real* inflow; int a; int k; int nnodes; int branchvert; /* get problem data */ probdata = SCIPgetProbData(scip); assert(probdata != NULL); /* get graph */ g = SCIPprobdataGetGraph(probdata); assert(g != NULL); /* LP has not been solved */ if( !SCIPhasCurrentNodeLP(scip) || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL ) { *vertex = UNKNOWN; return SCIP_OKAY; } edgevars = SCIPprobdataGetEdgeVars(scip); assert(edgevars != NULL); nnodes = g->knots; SCIP_CALL( SCIPallocBufferArray(scip, &inflow, nnodes) ); branchvert = UNKNOWN; maxflow = 1.0; for( k = 0; k < nnodes; k++ ) { inflow[k] = 0.0; for( a = g->inpbeg[k]; a != EAT_LAST; a = g->ieat[a] ) inflow[k] += SCIPvarGetLPSol(edgevars[a]); if( !Is_term(g->term[k]) && SCIPisLT(scip, inflow[k], 1.0) && SCIPisLT(scip, fabs(inflow[k] - 0.5), maxflow) ) { branchvert = k; maxflow = fabs(inflow[k] - 0.5); SCIPdebugMessage("new maxflow %f on vertex %d \n", inflow[k], branchvert ); } } SCIPdebugMessage("maxflow %f on vertex %d, term? %d \n", maxflow, branchvert, Is_term(g->term[branchvert]) ); (*vertex) = branchvert; SCIPfreeBufferArray(scip, &inflow); return SCIP_OKAY; }
/** prints vardata to file stream */ void SCIPvardataPrint( SCIP* scip, /**< SCIP data structure */ SCIP_VARDATA* vardata, /**< variable data */ FILE* file /**< the text file to store the information into */ ) { SCIP_PROBDATA* probdata; int* ids; int i; probdata = SCIPgetProbData(scip); assert(probdata != NULL); ids = SCIPprobdataGetIds(probdata); assert(ids != NULL); SCIPinfoMessage(scip, file, "consids = {"); for( i = 0; i < vardata->nconsids; ++i ) { SCIPinfoMessage(scip, file, "%d->%d", ids[vardata->consids[i]], vardata->consids[i]); if( i < vardata->nconsids - 1 ) SCIPinfoMessage(scip, file, ","); } SCIPinfoMessage(scip, file, "}\n"); }
/** checks whether a node is in a given stable set, returns true iff it is */ SCIP_Bool COLORprobIsNodeInStableSet( SCIP* scip, /**< SCIP data structure */ int setindex, /**< index of the stable set */ int node /**< number of the node */ ) { SCIP_PROBDATA* probdata; int l; int u; int m; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); l = 0; u = probdata->stablesetlengths[setindex]-1; while ( l <= u ) { m = (l+u)/2; if ( probdata->stablesets[setindex][m] == node ) { return TRUE; } if ( probdata->stablesets[setindex][m] > node ) { l = m+1; } if ( probdata->stablesets[setindex][m] < node ) { u = m-1; } } return FALSE; }
/** constraint deactivation notification method of constraint handler */ static SCIP_DECL_CONSDEACTIVE(consDeactiveSamediff) { /*lint --e{715}*/ SCIP_CONSDATA* consdata; SCIP_PROBDATA* probdata; assert(scip != NULL); assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0); assert(cons != NULL); consdata = SCIPconsGetData(cons); assert(consdata != NULL); assert(consdata->propagated || SCIPgetNChildren(scip) == 0); probdata = SCIPgetProbData(scip); assert(probdata != NULL); /* check if all variables which are not fixed locally to zero are valid for this constraint/node */ assert( consdataCheck(scip, probdata, consdata) ); SCIPdebugMessage("deactivate constraint <%s> at node <%"SCIP_LONGINT_FORMAT"> in depth <%d>: ", SCIPconsGetName(cons), SCIPnodeGetNumber(consdata->node), SCIPnodeGetDepth(consdata->node)); SCIPdebug( consdataPrint(scip, consdata, NULL) ); /* set the number of propagated variables to current number of variables is SCIP */ consdata->npropagatedvars = SCIPprobdataGetNVars(probdata); /* check if all variables are valid for this constraint */ assert( consdataCheck(scip, probdata, consdata) ); return SCIP_OKAY; }
/** return the number of elements */ int LOPgetNElements( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; /* get problem data */ probdata = SCIPgetProbData(scip); assert( probdata != NULL ); return probdata->n; }
/** returns the number of stable sets / variables */ int COLORprobGetNStableSets( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); return probdata->nstablesets; }
/** returns the array in which for every node in the preprocessed graph, the related node in the original graph is saved */ int* COLORprobGetOriginalNodesForNewNodes( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); return probdata->new2oldnode; }
/** returns the array of nodes deleted during preprocessing, length = COLORprobGetOriginalNNodes(), filled with -1 at the end */ int* COLORprobGetDeletedNodes( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); return probdata->deletednodes; }
/** returns the original graph */ TCLIQUE_GRAPH* COLORprobGetOriginalGraph( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); return probdata->oldgraph; }
/** returns the number of nodes in the original graph */ int COLORprobGetOriginalNNodes( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); return tcliqueGetNNodes(probdata->oldgraph); }
/** adds a new stable set, the set must be sorted descendingly, * attention: you need to check whether it is new before adding it */ SCIP_RETCODE COLORprobAddNewStableSet( SCIP* scip, /**< SCIP data structure */ int* stablesetnodes, /**< array of nodes in the stable set */ int nstablesetnodes, /**< number of nodes in the stable set */ int* setindex /**< return value: index of the stable set */ ) { SCIP_PROBDATA* probdata; int newsize; int i; assert(stablesetnodes != NULL); assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); /* the set should be sorted descendingly */ #ifndef NDEBUG for ( i = 0; i < nstablesetnodes-2; i++ ) { assert(stablesetnodes[i]>stablesetnodes[i+1]); } #endif /* ensure that array is big enough */ if ( (probdata->nstablesets + 1) > probdata->maxstablesets) { newsize = 2* probdata->maxstablesets; assert(newsize > probdata->nstablesets + 1); SCIP_CALL( SCIPreallocMemoryArray(scip, &(probdata->stablesets), newsize) ); SCIP_CALL( SCIPreallocMemoryArray(scip, &(probdata->stablesetlengths), newsize) ); SCIP_CALL( SCIPreallocMemoryArray(scip, &(probdata->stablesetvars), newsize) ); probdata->maxstablesets = newsize; SCIPdebugMessage("Set-array resized: %d --> %d\n", newsize/2, newsize); } /* alloc memory for the new stable set */ SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(probdata->stablesets[probdata->nstablesets]), nstablesetnodes) ); /*lint !e866*/ probdata->stablesetlengths[probdata->nstablesets] = nstablesetnodes; probdata->stablesetvars[probdata->nstablesets] = NULL; for ( i = 0; i < nstablesetnodes; i++ ) { assert(stablesetnodes[i] >= 0); probdata->stablesets[probdata->nstablesets][i] = stablesetnodes[i]; } *setindex = probdata->nstablesets; probdata->nstablesets++; return SCIP_OKAY; }
/** returns the node-constraint belonging to a given node */ SCIP_CONS* COLORprobGetConstraint( SCIP* scip, /**< SCIP data structure */ int node /**< number of the node, for which this constraint assures coloring */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); assert(node >= 0 && node < tcliqueGetNNodes(probdata->graph)); return probdata->constraints[node]; }
/** gets the variable belonging to a given stable set */ SCIP_VAR* COLORprobGetVarForStableSet( SCIP* scip, /**< SCIP data structure */ int setindex /**< index of the stable set */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); assert ( (setindex >= 0) && (setindex < probdata->nstablesets)); return probdata->stablesetvars[setindex]; }
/** execution method of event handler */ static SCIP_DECL_EVENTEXEC(eventExecAddedVar) { /*lint --e{715}*/ assert(eventhdlr != NULL); assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0); assert(event != NULL); assert(SCIPeventGetType(event) == SCIP_EVENTTYPE_VARADDED); SCIPdebugMessage("exec method of event handler for added variable to probdata\n"); /* add new variable to probdata */ SCIP_CALL( SCIPprobdataAddVar(scip, SCIPgetProbData(scip), SCIPeventGetVar(event)) ); return SCIP_OKAY; }
/** returns the stable set with the given index */ void COLORprobGetStableSet( SCIP* scip, /**< SCIP data structure */ int setindex, /**< index of the stable set */ int** stableset, /**< return value: pointer to the stable set */ int* nelements /**< return value: number of elements in the stable set */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); *stableset = probdata->stablesets[setindex]; *nelements = probdata->stablesetlengths[setindex]; }
/** domain propagation method of constraint handler */ static SCIP_DECL_CONSPROP(consPropStp) { /*lint --e{715}*/ SCIP_PROBDATA* probdata; GRAPH* graph; probdata = SCIPgetProbData(scip); assert(probdata != NULL); graph = SCIPprobdataGetGraph(probdata); assert(graph != NULL); /* for degree constrained model, check whether problem is infeasible */ if( graph->stp_type == STP_DEG_CONS ) { int k; int nnodes; int degsum; int* maxdegs; nnodes = graph->knots; maxdegs = graph->maxdeg; assert(maxdegs != NULL); degsum = 0; for( k = 0; k < nnodes; k++ ) { if( Is_term(graph->term[k]) ) { assert(maxdegs[k] > 0); degsum += maxdegs[k] - 1; } else { assert(maxdegs[k] >= 0); degsum += MAX(maxdegs[k] - 2, 0); } } if( degsum < graph->terms - 2 ) *result = SCIP_CUTOFF; else *result = SCIP_DIDNOTFIND; } return SCIP_OKAY; }
/** returns all stable sets */ void COLORprobGetStableSets( SCIP* scip, /**< SCIP data structure */ int*** stablesets, /**< return value: pointer to the stable sets */ int** nelements, /**< return value: number of elements in the stable sets */ int* nstablesets /**< return value: number of sets */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); *stablesets = probdata->stablesets; *nelements = probdata->stablesetlengths; *nstablesets = probdata->nstablesets; }
/** create linear ordering problem model */ SCIP_RETCODE LOPgenerateModel( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; SCIP_CONS* cons; int i, j; /* get problem data */ probdata = SCIPgetProbData(scip); assert( probdata != NULL ); /* generate variables */ SCIP_CALL( SCIPallocMemoryArray(scip, &probdata->vars, probdata->n) ); for (i = 0; i < probdata->n; ++i) { SCIP_CALL( SCIPallocMemoryArray(scip, &(probdata->vars[i]), probdata->n) ); /*lint !e866*/ for (j = 0; j < probdata->n; ++j) { if (j != i) { char s[SCIP_MAXSTRLEN]; (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "x#%d#%d", i, j); SCIP_CALL( SCIPcreateVar(scip, &(probdata->vars[i][j]), s, 0.0, 1.0, probdata->W[i][j], SCIP_VARTYPE_BINARY, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL)); SCIP_CALL( SCIPaddVar(scip, probdata->vars[i][j]) ); } else probdata->vars[i][j] = NULL; } } /* generate linear ordering constraint */ SCIP_CALL( SCIPcreateConsLinearOrdering(scip, &cons, "LOP", probdata->n, probdata->vars, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)); SCIP_CALL( SCIPaddCons(scip, cons) ); SCIP_CALL( SCIPreleaseCons(scip, &cons) ); /* set maximization */ SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) ); return SCIP_OKAY; }
/** display constraints */ static void consdataPrint( SCIP* scip, /**< SCIP data structure */ SCIP_CONSDATA* consdata, /**< constraint data */ FILE* file /**< file stream */ ) { SCIP_PROBDATA* probdata; int* ids; probdata = SCIPgetProbData(scip); assert(probdata != NULL); ids = SCIPprobdataGetIds(probdata); assert(ids != NULL); SCIPinfoMessage(scip, file, "%s(%d,%d) at node %d\n", consdata->type == SAME ? "same" : "diff", ids[consdata->itemid1], ids[consdata->itemid2], SCIPnodeGetNumber(consdata->node) ); }
/** adds a variable that belongs to a given stable set */ SCIP_RETCODE COLORprobAddVarForStableSet( SCIP* scip, /**< SCIP data structure */ int setindex, /**< index of the stable set */ SCIP_VAR* var /**< pointer to the variable */ ) { SCIP_PROBDATA* probdata; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); assert((setindex >= 0) && (setindex < probdata->nstablesets)); /* catch variable deleted event on the variable to update the stablesetvars array in the problem data */ SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_VARDELETED, SCIPfindEventhdlr(scip, EVENTHDLR_NAME), (SCIP_EVENTDATA*) probdata, NULL) ); probdata->stablesetvars[setindex] = var; return SCIP_OKAY; }
/** constraint copying method of constraint handler */ static SCIP_DECL_CONSCOPY(consCopyStp) { /*lint --e{715}*/ const char* consname; SCIP_PROBDATA* probdata; GRAPH* graph; probdata = SCIPgetProbData(scip); assert(probdata != NULL); graph = SCIPprobdataGetGraph(probdata); assert(graph != NULL); consname = SCIPconsGetName(sourcecons); /* creates and captures a and constraint */ SCIP_CALL( SCIPcreateConsStp(scip, cons, consname, graph) ); *valid = TRUE; return SCIP_OKAY; }
/** prints the requested stable set to standart output */ void COLORprobPrintStableSet( SCIP* scip, /**< SCIP data structure */ int setnumber /**< the number of the requested set */ ) { SCIP_PROBDATA* probdata; int i; int j; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); i = setnumber; printf( "Set %d: ", i); for ( j = 0; j < probdata->stablesetlengths[i]; j++ ) { printf("%d, ", probdata->stablesets[i][j]+1); } if ( probdata->stablesetvars[i] != NULL ) printf("ub = %f", SCIPvarGetUbLocal(probdata->stablesetvars[i])); printf("\n"); }
/** returns the node in the preprocessed graph, that belongs to the given node, returns -1 if node was deleted */ int COLORprobGetNewNodeForOriginalNode( SCIP* scip, /**< SCIP data structure */ int node /**< a node in the original graph */ ) { SCIP_PROBDATA* probdata; int i; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); assert(node >= 0 && node < COLORprobGetOriginalNNodes(scip)); for ( i = 0; i < COLORprobGetOriginalNNodes(scip); i++ ) { if ( probdata->new2oldnode[i] == node ) return i; if ( probdata->new2oldnode[i] == -1 ) return -1; } return -1; }
/** prints all stable sets to standart output */ void COLORprobPrintStableSets( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; int i; int j; assert(scip != NULL); probdata = SCIPgetProbData(scip); assert(probdata != NULL); for ( i = 0; i < probdata->nstablesets; i++ ) { printf( "Set %d: ", i); for ( j = 0; j < probdata->stablesetlengths[i]; j++ ) { printf("%d, ", probdata->stablesets[i][j]+1); } printf("ub = %f", SCIPvarGetUbLocal(probdata->stablesetvars[i])); printf(", inLP = %u", SCIPvarIsInLP(probdata->stablesetvars[i])); printf("\n"); } }
/** domain propagation method of constraint handler */ static SCIP_DECL_CONSPROP(consPropSamediff) { /*lint --e{715}*/ SCIP_PROBDATA* probdata; SCIP_CONSDATA* consdata; SCIP_VAR** vars; int nvars; int c; assert(scip != NULL); assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0); SCIPdebugMessage("propagation constraints of constraint handler <"CONSHDLR_NAME">\n"); probdata = SCIPgetProbData(scip); assert(probdata != NULL); vars = SCIPprobdataGetVars(probdata); nvars = SCIPprobdataGetNVars(probdata); *result = SCIP_DIDNOTFIND; for( c = 0; c < nconss; ++c ) { consdata = SCIPconsGetData(conss[c]); #ifndef NDEBUG { /* check if there are no equal consdatas */ SCIP_CONSDATA* consdata2; int i; for( i = c+1; i < nconss; ++i ) { consdata2 = SCIPconsGetData(conss[i]); assert( !(consdata->itemid1 == consdata2->itemid1 && consdata->itemid2 == consdata2->itemid2 && consdata->type == consdata2->type) ); assert( !(consdata->itemid1 == consdata2->itemid2 && consdata->itemid2 == consdata2->itemid1 && consdata->type == consdata2->type) ); } } #endif if( !consdata->propagated ) { SCIPdebugMessage("propagate constraint <%s> ", SCIPconsGetName(conss[c])); SCIPdebug( consdataPrint(scip, consdata, NULL) ); SCIP_CALL( consdataFixVariables(scip, consdata, vars, nvars, result) ); consdata->npropagations++; if( *result != SCIP_CUTOFF ) { consdata->propagated = TRUE; consdata->npropagatedvars = nvars; } else break; } /* check if constraint is completely propagated */ assert( consdataCheck(scip, probdata, consdata) ); } return SCIP_OKAY; }
/** method for either Farkas or Redcost pricing */ static SCIP_RETCODE pricing( SCIP* scip, /**< SCIP data structure */ SCIP_PRICER* pricer, /**< pricer */ SCIP_Real* lowerbound, /**< lowerbound pointer */ SCIP_Bool farkas /**< TRUE: Farkas pricing; FALSE: Redcost pricing */ ) { SCIP_PRICERDATA* pricerdata; /* the data of the pricer */ SCIP_PROBDATA* probdata; GRAPH* graph; SCIP_VAR* var; PATH* path; SCIP_Real* edgecosts; /* edgecosts of the current subproblem */ char varname[SCIP_MAXSTRLEN]; SCIP_Real newlowerbound = -SCIPinfinity(scip); SCIP_Real redcost; /* reduced cost */ int tail; int e; int t; int i; assert(scip != NULL); assert(pricer != NULL); /* get pricer data */ pricerdata = SCIPpricerGetData(pricer); assert(pricerdata != NULL); /* get problem data */ probdata = SCIPgetProbData(scip); assert(probdata != NULL); SCIPdebugMessage("solstat=%d\n", SCIPgetLPSolstat(scip)); if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL ) newlowerbound = SCIPgetSolTransObj(scip, NULL); SCIPdebug( SCIP_CALL( SCIPprintSol(scip, NULL, NULL, FALSE) ) ); # if 0 if ( pricerdata->lowerbound <= 4 ) { char label[SCIP_MAXSTRLEN]; (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "X%g.gml", pricerdata->lowerbound); SCIP_CALL( SCIPprobdataPrintGraph(scip, label , NULL, TRUE) ); pricerdata->lowerbound++; } #endif /* get the graph*/ graph = SCIPprobdataGetGraph(probdata); /* get dual solutions and save them in mi and pi */ for( t = 0; t < pricerdata->realnterms; ++t ) { if( farkas ) { pricerdata->mi[t] = SCIPgetDualfarkasLinear(scip, pricerdata->pathcons[t]); } else { pricerdata->mi[t] = SCIPgetDualsolLinear(scip, pricerdata->pathcons[t]); assert(!SCIPisNegative(scip, pricerdata->mi[t])); } } for( e = 0; e < pricerdata->nedges; ++e ) { if( !pricerdata->bigt ) { for( t = 0; t < pricerdata->realnterms; ++t ) { if( farkas ) { pricerdata->pi[t * pricerdata->nedges + e] = SCIPgetDualfarkasLinear( scip, pricerdata->edgecons[t * pricerdata->nedges + e]); } else { pricerdata->pi[t * pricerdata->nedges + e] = SCIPgetDualsolLinear( scip, pricerdata->edgecons[t * pricerdata->nedges + e]); } } } else { if( farkas ) { pricerdata->pi[e] = SCIPgetDualfarkasLinear( scip, pricerdata->edgecons[e]); } else { pricerdata->pi[e] = SCIPgetDualsolLinear( scip, pricerdata->edgecons[e]); } } } SCIP_CALL( SCIPallocMemoryArray(scip, &path, graph->knots) ); SCIP_CALL( SCIPallocMemoryArray(scip, &edgecosts, pricerdata->nedges) ); if( pricerdata->bigt ) { for( e = 0; e < pricerdata->nedges; ++e ) { edgecosts[e] = (-pricerdata->pi[e]); } } /* find shortest r-t (r root, t terminal) paths and create corresponding variables iff reduced cost < 0 */ for( t = 0; t < pricerdata->realnterms; ++t ) { for( e = 0; e < pricerdata->nedges; ++e ) { if( !pricerdata->bigt ) { edgecosts[e] = (-pricerdata->pi[t * pricerdata->nedges + e]); } assert(!SCIPisNegative(scip, edgecosts[e])); } for( i = 0; i < graph->knots; i++ ) graph->mark[i] = 1; graph_path_exec(scip, graph, FSP_MODE, pricerdata->root, edgecosts, path); /* compute reduced cost of shortest path to terminal t */ redcost = 0.0; tail = pricerdata->realterms[t]; while( tail != pricerdata->root ) { redcost += edgecosts[path[tail].edge]; tail = graph->tail[path[tail].edge]; } redcost -= pricerdata->mi[t]; if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL ) { newlowerbound += redcost; } /* check if reduced cost < 0 */ if( SCIPisNegative(scip, redcost) ) { /* create variable to the shortest path (having reduced cost < 0) */ var = NULL; sprintf(varname, "PathVar%d_%d", t, pricerdata->ncreatedvars[t]); ++(pricerdata->ncreatedvars[t]); SCIP_CALL( SCIPcreateVarBasic(scip, &var, varname, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS) ); SCIP_CALL( SCIPaddPricedVar(scip, var, -redcost) ); tail = pricerdata->realterms[t]; while( tail != pricerdata->root ) { /* add variable to constraints */ if( !pricerdata->bigt ) { SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->edgecons[t * pricerdata->nedges + path[tail].edge], var, 1.0) ); } else { SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->edgecons[path[tail].edge], var, 1.0) ); } tail = graph->tail[path[tail].edge]; } SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->pathcons[t], var, 1.0) ); } } if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL ) *lowerbound = newlowerbound; SCIPfreeMemoryArray(scip, &edgecosts); SCIPfreeMemoryArray(scip, &path); return SCIP_OKAY; }
/** evalutate solution */ SCIP_RETCODE LOPevalSolution( SCIP* scip /**< SCIP data structure */ ) { SCIP_PROBDATA* probdata; SCIP_VAR*** vars; SCIP_SOL* sol; int* outDegree; int* indices; int i; int j; int n; /* get problem data */ probdata = SCIPgetProbData(scip); assert( probdata != NULL ); assert( probdata->vars != NULL ); n = probdata->n; vars = probdata->vars; sol = SCIPgetBestSol(scip); if ( sol == NULL ) printf("\nNo solution found.\n"); else { SCIP_CALL( SCIPallocBufferArray(scip, &outDegree, n) ); SCIP_CALL( SCIPallocBufferArray(scip, &indices, n) ); /* compute out-degree */ for (i = 0; i < n; ++i) { int deg = 0; for (j = 0; j < n; ++j) { SCIP_Real val; if (j == i) continue; val = SCIPgetSolVal(scip, sol, vars[i][j]); assert( SCIPisIntegral(scip, val) ); if ( val < 0.5 ) ++deg; } outDegree[i] = deg; indices[i] = i; } /* sort such that degrees are non-decreasing */ SCIPsortIntInt(outDegree, indices, n); /* output */ printf("\nFinal order:\n"); for (i = 0; i < n; ++i) printf("%d ", indices[i]); printf("\n"); SCIPfreeBufferArray(scip, &indices); SCIPfreeBufferArray(scip, &outDegree); } return SCIP_OKAY; }
/** add branching decisions constraints to the sub SCIP */ static SCIP_RETCODE addBranchingDecisionConss( SCIP* scip, /**< SCIP data structure */ SCIP* subscip, /**< pricing SCIP data structure */ SCIP_VAR** vars, /**< variable array of the subscuip oder variables */ SCIP_CONSHDLR* conshdlr /**< constraint handler for branching data */ ) { SCIP_CONS** conss; SCIP_CONS* cons; int nconss; int id1; int id2; CONSTYPE type; SCIP_Real vbdcoef; SCIP_Real lhs; SCIP_Real rhs; int c; assert( scip != NULL ); assert( subscip != NULL ); assert( conshdlr != NULL ); /* collect all branching decision constraints */ conss = SCIPconshdlrGetConss(conshdlr); nconss = SCIPconshdlrGetNConss(conshdlr); /* loop over all branching decision constraints and apply the branching decision if the corresponding constraint is * active */ for( c = 0; c < nconss; ++c ) { cons = conss[c]; /* ignore constraints which are not active since these are not laying on the current active path of the search * tree */ if( !SCIPconsIsActive(cons) ) continue; /* collect the two item ids and the branching type (SAME or DIFFER) on which the constraint branched */ id1 = SCIPgetItemid1Samediff(scip, cons); id2 = SCIPgetItemid2Samediff(scip, cons); type = SCIPgetTypeSamediff(scip, cons); SCIPdebugMessage("create varbound for %s(%d,%d)\n", type == SAME ? "same" : "diff", SCIPprobdataGetIds(SCIPgetProbData(scip))[id1], SCIPprobdataGetIds(SCIPgetProbData(scip))[id2]); /* depending on the branching type select the correct left and right hand side for the linear constraint which * enforces this branching decision in the pricing problem MIP */ if( type == SAME ) { lhs = 0.0; rhs = 0.0; vbdcoef = -1.0; } else if( type == DIFFER ) { lhs = -SCIPinfinity(scip); rhs = 1.0; vbdcoef = 1.0; } else { SCIPerrorMessage("unknow constraint type <%d>\n, type"); return SCIP_INVALIDDATA; } /* add linear (in that case a variable bound) constraint to pricing MIP depending on the branching type: * * - branching type SAME: x1 = x2 <=> x1 - x2 = 0 <=> 0 <= x1 - x2 <= 0 * * - branching type DIFFER: x1 - x2 <= 1 <=> -inf <= x1 - x2 <= 1 * */ SCIP_CALL( SCIPcreateConsBasicVarbound(subscip, &cons, SCIPconsGetName(conss[c]), vars[id1], vars[id2], vbdcoef, lhs, rhs) ); SCIPdebug( SCIPprintCons(subscip, cons, NULL) ); SCIP_CALL( SCIPaddCons(subscip, cons) ); SCIP_CALL( SCIPreleaseCons(subscip, &cons) ); } return SCIP_OKAY; }