/** sets up the problem data */ SCIP_RETCODE SCIPprobdataCreate( SCIP* scip, /**< SCIP data structure */ const char* probname, /**< problem name */ int* ids, /**< array of item ids */ SCIP_Longint* weights, /**< array containing the item weights */ int nitems, /**< number of items */ SCIP_Longint capacity /**< bin capacity */ ) { SCIP_PROBDATA* probdata; SCIP_CONS** conss; char name[SCIP_MAXSTRLEN]; int i; assert(scip != NULL); /* create event handler if it does not exist yet */ if( SCIPfindEventhdlr(scip, EVENTHDLR_NAME) == NULL ) { SCIP_CALL( SCIPincludeEventhdlrBasic(scip, NULL, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecAddedVar, NULL) ); } /* create problem in SCIP and add non-NULL callbacks via setter functions */ SCIP_CALL( SCIPcreateProbBasic(scip, probname) ); SCIP_CALL( SCIPsetProbDelorig(scip, probdelorigBinpacking) ); SCIP_CALL( SCIPsetProbTrans(scip, probtransBinpacking) ); SCIP_CALL( SCIPsetProbDeltrans(scip, probdeltransBinpacking) ); SCIP_CALL( SCIPsetProbInitsol(scip, probinitsolBinpacking) ); SCIP_CALL( SCIPsetProbExitsol(scip, probexitsolBinpacking) ); /* set objective sense */ SCIP_CALL( SCIPsetObjsense(scip, SCIP_OBJSENSE_MINIMIZE) ); /* tell SCIP that the objective will be always integral */ SCIP_CALL( SCIPsetObjIntegral(scip) ); SCIP_CALL( SCIPallocBufferArray(scip, &conss, nitems) ); /* create set covering constraints for each item */ for( i = 0; i < nitems; ++i ) { (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "item_%d", ids[i]); SCIP_CALL( SCIPcreateConsBasicSetcover(scip, &conss[i], name, 0, NULL) ); /* declare constraint modifiable for adding variables during pricing */ SCIP_CALL( SCIPsetConsModifiable(scip, conss[i], TRUE) ); SCIP_CALL( SCIPaddCons(scip, conss[i]) ); } /* create problem data */ SCIP_CALL( probdataCreate(scip, &probdata, NULL, conss, weights, ids, 0, nitems, capacity) ); SCIP_CALL( createInitialColumns(scip, probdata) ); /* set user problem data */ SCIP_CALL( SCIPsetProbData(scip, probdata) ); SCIP_CALL( SCIPpricerBinpackingActivate(scip, conss, weights, ids, nitems, capacity) ); /* free local buffer arrays */ SCIPfreeBufferArray(scip, &conss); return SCIP_OKAY; }
/** read LP in "COL File Format" */ static SCIP_RETCODE readCol( SCIP* scip, /**< SCIP data structure */ const char* filename /**< name of the input file */ ) { SCIP_FILE* fp; /* file-reader */ char buf[COL_MAX_LINELEN]; /* maximal length of line */ int nedges; int nnodes; int line_nr; char* char_p; char* probname; int** edges; int i; int j; int begin; int end; int nduplicateedges; SCIP_Bool duplicateedge; assert(scip != NULL); assert(filename != NULL); if (NULL == (fp = SCIPfopen(filename, "r"))) { SCIPerrorMessage("cannot open file <%s> for reading\n", filename); perror(filename); return SCIP_NOFILE; } /* Get problem name from filename and save it */ SCIPfgets(buf, sizeof(buf), fp); i = 1; while ( (filename[i] != '/') && (filename[i] != '\0') ) { i++; } if ( filename[i] != '/' ) { j = i; i = -1; } else { j = i+1; while ( filename[i] == '/' && filename[j] != '\0' ) { j = i+1; while ( filename[j] != '\0' ) { j++; if ( filename[j] == '/' ) { i = j; break; } } } } SCIPallocMemoryArray(scip, &probname, j-i-4); strncpy(probname, &filename[i+1], j-i-5); probname[j-i-5]= '\0'; /* Read until information about graph starts */ line_nr = 0; while( !SCIPfeof(fp) && (buf[0] != 'p') ) { SCIPfgets(buf, sizeof(buf), fp); line_nr++; } /* no graph information in file! */ if ( SCIPfeof(fp) ) { SCIPerrorMessage("Error! Could not find line starting with 'p'.\n"); return SCIP_READERROR; } /* wrong format of the line containig number of nodes and edges */ if ( buf[2] != 'e' || buf[3] != 'd' || buf[4] != 'g' || buf[5] != 'e' ) { SCIPerrorMessage("Line starting with 'p' must continue with 'edge'!\n"); return SCIP_READERROR; } char_p = &buf[6]; /* if line reads 'edges' (non-standard!), instead of 'edge'. */ if ( *char_p == 's' ) ++(char_p); /* read out number of nodes and edges, the pointer char_p will be changed */ nduplicateedges = 0; nnodes = getNextNumber(&char_p); nedges = getNextNumber(&char_p); if ( nnodes <= 0 ) { SCIPerrorMessage("Number of vertices must be positive!\n"); return SCIP_READERROR; } if ( nedges < 0 ) { SCIPerrorMessage("Number of edges must be nonnegative!\n"); return SCIP_READERROR; } /* create array for edges */ SCIP_CALL( SCIPallocMemoryArray(scip, &edges, nedges) ); for( i = 0; i < nedges; i++) { SCIP_CALL( SCIPallocMemoryArray(scip, &(edges[i]), 2) ); } /* fill array for edges */ i = 0; while ( !SCIPfeof(fp) ) { SCIPfgets(buf, sizeof(buf), fp); line_nr++; if ( buf[0] == 'e') { duplicateedge = FALSE; char_p = &buf[2]; begin = getNextNumber(&char_p); end = getNextNumber(&char_p); for ( j = 0; j < i; j++) { if ( ((edges[j][0] == begin) && (edges[j][1] == end)) || ((edges[j][1] == begin) && (edges[j][0] == end)) ) { duplicateedge = TRUE; nduplicateedges++; break; } } if ( !duplicateedge ) { if( i >= nedges ) { SCIPerrorMessage("more edges than expected: expected %d many, but got already %d'th (non-duplicate) edge", nedges, i+1); return SCIP_READERROR; } edges[i][0] = begin; edges[i][1] = end; assert((edges[i][0] > 0) && (edges[i][0] <= nnodes)); assert((edges[i][1] > 0) && (edges[i][1] <= nnodes)); i++; } } } if( i + nduplicateedges != nedges ) { SCIPerrorMessage("incorrect number of edges: expected %d many, but got %d many\n", nedges, i + nduplicateedges); return SCIP_ERROR; } printf("Read graph: %d nodes, %d edges (%d duplicates)\n", nnodes, nedges, nduplicateedges); /* create problem data */ SCIP_CALL( SCIPcreateProbColoring(scip, probname, nnodes, nedges-nduplicateedges, edges) ); /* create LP */ SCIPdebugMessage("Erstelle LP...\n"); COLORprobSetUpArrayOfCons(scip); /* activate the pricer */ SCIP_CALL( SCIPactivatePricer(scip, SCIPfindPricer(scip, "coloring")) ); SCIP_CALL( SCIPsetObjIntegral(scip) ); for ( i = nedges-1; i >= 0; i--) { SCIPfreeMemoryArray(scip, &(edges[i])); } SCIPfreeMemoryArray(scip, &edges); SCIPfreeMemoryArray(scip, &probname); SCIPfclose(fp); return SCIP_OKAY; }