/** reads the next non-empty non-comment line of a cnf file */ static SCIP_RETCODE readCnfLine( SCIP* scip, /**< SCIP data structure */ SCIP_FILE* file, /**< input file */ char* buffer, /**< buffer for storing the input line */ int size, /**< size of the buffer */ int* linecount /**< pointer to the line number counter */ ) { char* line; int linelen; assert(file != NULL); assert(buffer != NULL); assert(size >= 2); assert(linecount != NULL); do { (*linecount)++; line = SCIPfgets(buffer, size, file); if( line != NULL ) { linelen = (int)strlen(line); if( linelen == size-1 ) { char s[SCIP_MAXSTRLEN]; (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "line too long (exceeds %d characters)", size-2); readError(scip, *linecount, s); return SCIP_READERROR; } } else linelen = 0; } while( line != NULL && (*line == 'c' || *line == '\n') ); if( line != NULL && linelen >= 2 && line[linelen-2] == '\n' ) line[linelen-2] = '\0'; else if( linelen == 0 ) *buffer = '\0'; assert((line == NULL) == (*buffer == '\0')); return SCIP_OKAY; }
/** reads the next line from the input file into the line buffer; skips comments; * returns whether a line could be read */ static SCIP_Bool getNextLine( BLKINPUT* blkinput /**< BLK reading data */ ) { int i; assert(blkinput != NULL); /* clear the line */ BMSclearMemoryArray(blkinput->linebuf, BLK_MAX_LINELEN); /* read next line */ blkinput->linepos = 0; blkinput->linebuf[BLK_MAX_LINELEN-2] = '\0'; if( SCIPfgets(blkinput->linebuf, sizeof(blkinput->linebuf), blkinput->file) == NULL ) return FALSE; blkinput->linenumber++; if( blkinput->linebuf[BLK_MAX_LINELEN-2] != '\0' ) { SCIPerrorMessage("Error: line %d exceeds %d characters\n", blkinput->linenumber, BLK_MAX_LINELEN-2); blkinput->haserror = TRUE; return FALSE; } blkinput->linebuf[BLK_MAX_LINELEN-1] = '\0'; blkinput->linebuf[BLK_MAX_LINELEN-2] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */ /* skip characters after comment symbol */ for( i = 0; commentchars[i] != '\0'; ++i ) { char* commentstart; commentstart = strchr(blkinput->linebuf, commentchars[i]); if( commentstart != NULL ) { *commentstart = '\0'; *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */ } } return TRUE; }
/** problem reading method of reader */ static SCIP_DECL_READERREAD(readerReadBpa) { /*lint --e{715}*/ SCIP_FILE* file; SCIP_Longint* weights; int* ids; SCIP_Bool error; char name[SCIP_MAXSTRLEN]; char format[16]; char buffer[SCIP_MAXSTRLEN]; int capacity; int nitems; int bestsolvalue; int nread; int weight; int nweights; int lineno; *result = SCIP_DIDNOTRUN; /* open file */ file = SCIPfopen(filename, "r"); if( file == NULL ) { SCIPerrorMessage("cannot open file <%s> for reading\n", filename); SCIPprintSysError(filename); return SCIP_NOFILE; } lineno = 0; /* read problem name */ if( !SCIPfeof(file) ) { /* get next line */ if( SCIPfgets(buffer, sizeof(buffer), file) == NULL ) return SCIP_READERROR; lineno++; /* parse dimension line */ sprintf(format, "%%%ds\n", SCIP_MAXSTRLEN); nread = sscanf(buffer, format, name); if( nread == 0 ) { SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer); return SCIP_READERROR; } SCIPdebugMessage("problem name <%s>\n", name); } /* read problem dimension */ if( !SCIPfeof(file) ) { /* get next line */ if( SCIPfgets(buffer, sizeof(buffer), file) == NULL ) return SCIP_READERROR; lineno++; /* parse dimension line */ nread = sscanf(buffer, "%d %d %d\n", &capacity, &nitems, &bestsolvalue); if( nread < 2 ) { SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer); return SCIP_READERROR; } SCIPdebugMessage("capacity = <%d>, number of items = <%d>, best known solution = <%d>\n", capacity, nitems, bestsolvalue); } /* allocate buffer memory for storing the weights and ids temporary */ SCIP_CALL( SCIPallocBufferArray(scip, &weights, nitems) ); SCIP_CALL( SCIPallocBufferArray(scip, &ids, nitems) ); /* pasre weights */ nweights = 0; error = FALSE; while( !SCIPfeof(file) && !error ) { /* get next line */ if( SCIPfgets(buffer, sizeof(buffer), file) == NULL ) break; lineno++; /* parse the line */ nread = sscanf(buffer, "%d\n", &weight); if( nread == 0 ) { SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer); error = TRUE; break; } SCIPdebugMessage("found weight %d <%d>\n", nweights, weight); weights[nweights] = weight; ids[nweights] = nweights; nweights++; if( nweights == nitems ) break; } if( nweights < nitems ) { SCIPwarningMessage(scip, "set nitems from <%d> to <%d> since the file <%s> only contains <%d> weights\n", nitems, weights, filename, weights); nitems = nweights; } if( !error ) { /* create a new problem in SCIP */ SCIP_CALL( SCIPprobdataCreate(scip, name, ids, weights, nitems, (SCIP_Longint)capacity) ); } (void)SCIPfclose(file); SCIPfreeBufferArray(scip, &ids); SCIPfreeBufferArray(scip, &weights); if( error ) return SCIP_READERROR; *result = SCIP_SUCCESS; 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; }
/** get next input line; this are all characters until the next semicolon */ static SCIP_RETCODE getInputString( SCIP* scip, /**< SCIP data structure */ CIPINPUT* cipinput /**< CIP parsing data */ ) { char* endline; char* endcharacter; char* windowsendlinechar; assert(cipinput != NULL); /* read next line */ cipinput->endfile = (SCIPfgets(cipinput->strbuf, cipinput->len, cipinput->file) == NULL); if( cipinput->endfile ) { /* clear the line for safety reason */ BMSclearMemoryArray(cipinput->strbuf, cipinput->len); return SCIP_OKAY; } cipinput->linenumber++; endline = strchr(cipinput->strbuf, '\n'); endcharacter = strchr(cipinput->strbuf, ';'); while( endline == NULL || (endcharacter == NULL && cipinput->section == CIP_CONSTRAINTS && strncmp(cipinput->strbuf, "END", 3) != 0 ) ) { int pos; /* we refill the buffer from the '\n' character */ if( endline == NULL ) pos = cipinput->len - 1; else pos = (int) (endline - cipinput->strbuf); /* don't erase the '\n' from all buffers for constraints */ if( endline != NULL && cipinput->section == CIP_CONSTRAINTS ) pos++; /* if necessary reallocate memory */ if( pos + cipinput->readingsize >= cipinput->len ) { cipinput->len = SCIPcalcMemGrowSize(scip, pos + cipinput->readingsize); SCIP_CALL( SCIPreallocBufferArray(scip, &(cipinput->strbuf), cipinput->len) ); } /* read next line */ cipinput->endfile = (SCIPfgets(&(cipinput->strbuf[pos]), cipinput->len - pos, cipinput->file) == NULL); if( cipinput->endfile ) { /* clear the line for safety reason */ BMSclearMemoryArray(cipinput->strbuf, cipinput->len); return SCIP_OKAY; } cipinput->linenumber++; endline = strrchr(cipinput->strbuf, '\n'); endcharacter = strchr(cipinput->strbuf, ';'); } assert(endline != NULL); /*SCIPdebugMessage("read line: %s\n", cipinput->strbuf);*/ /* check for windows "carriage return" endline character */ windowsendlinechar = strrchr(cipinput->strbuf, '\r'); if( windowsendlinechar != NULL && windowsendlinechar + 1 == endline ) --endline; else /* if the assert should not hold we found a windows "carriage return" which was not at the end of the line */ assert(windowsendlinechar == NULL); if( cipinput->section == CIP_CONSTRAINTS && endcharacter != NULL && endline - endcharacter != 1 ) { SCIPerrorMessage("Constraint line has to end with ';\\n' (line: %d).\n", cipinput->linenumber); cipinput->haserror = TRUE; return SCIP_OKAY; /* return error at hightest level */ } *endline = '\0'; return SCIP_OKAY; }
/** evaluates command line parameters and runs GCG appropriately in the given SCIP instance */ static SCIP_RETCODE SCIPprocessGCGShellArguments( SCIP* scip, /**< SCIP data structure */ int argc, /**< number of shell parameters */ char** argv, /**< array with shell parameters */ const char* defaultsetname /**< name of default settings file */ ) { /*lint --e{850}*/ char* probname = NULL; char* decname = NULL; char* settingsname = NULL; char* mastersetname = NULL; char* logname = NULL; SCIP_Bool quiet; SCIP_Bool paramerror; SCIP_Bool interactive; int i; /******************** * Parse parameters * ********************/ quiet = FALSE; paramerror = FALSE; interactive = FALSE; for( i = 1; i < argc; ++i ) { if( strcmp(argv[i], "-l") == 0 ) { i++; if( i < argc ) logname = argv[i]; else { SCIPinfoMessage(scip, NULL, "missing log filename after parameter '-l'\n"); paramerror = TRUE; } } else if( strcmp(argv[i], "-q") == 0 ) quiet = TRUE; else if( strcmp(argv[i], "-s") == 0 ) { i++; if( i < argc ) settingsname = argv[i]; else { SCIPinfoMessage(scip, NULL, "missing settings filename after parameter '-s'\n"); paramerror = TRUE; } } else if( strcmp(argv[i], "-m") == 0 ) { i++; if( i < argc ) mastersetname = argv[i]; else { SCIPinfoMessage(scip, NULL, "missing master settings filename after parameter '-m'\n"); paramerror = TRUE; } } else if( strcmp(argv[i], "-f") == 0 ) { i++; if( i < argc ) probname = argv[i]; else { SCIPinfoMessage(scip, NULL, "missing problem filename after parameter '-f'\n"); paramerror = TRUE; } } else if( strcmp(argv[i], "-d") == 0 ) { i++; if( i < argc ) decname = argv[i]; else { SCIPinfoMessage(scip, NULL, "missing decomposition filename after parameter '-d'\n"); paramerror = TRUE; } } else if( strcmp(argv[i], "-c") == 0 ) { i++; if( i < argc ) { SCIP_CALL( SCIPaddDialogInputLine(scip, argv[i]) ); interactive = TRUE; } else { SCIPinfoMessage(scip, NULL, "missing command line after parameter '-c'\n"); paramerror = TRUE; } } else if( strcmp(argv[i], "-b") == 0 ) { i++; if( i < argc ) { SCIP_FILE* file; file = SCIPfopen(argv[i], "r"); if( file == NULL ) { SCIPinfoMessage(scip, NULL, "cannot read command batch file <%s>\n", argv[i]); SCIPprintSysError(argv[i]); paramerror = TRUE; } else { while( !SCIPfeof(file) ) { char buffer[SCIP_MAXSTRLEN]; (void)SCIPfgets(buffer, sizeof(buffer), file); if( buffer[0] != '\0' ) { SCIP_CALL( SCIPaddDialogInputLine(scip, buffer) ); } } SCIPfclose(file); interactive = TRUE; } } else { SCIPinfoMessage(scip, NULL, "missing command batch filename after parameter '-b'\n"); paramerror = TRUE; } } else { SCIPinfoMessage(scip, NULL, "invalid parameter <%s>\n", argv[i]); paramerror = TRUE; } } if( interactive && probname != NULL ) { SCIPinfoMessage(scip, NULL, "cannot mix batch mode '-c' and '-b' with file mode '-f'\n"); paramerror = TRUE; } if( probname == NULL && decname != NULL ) { SCIPinfoMessage(scip, NULL, "cannot read decomposition file without given problem\n"); paramerror = TRUE; } if( !paramerror ) { /*********************************** * create log file message handler * ***********************************/ if( quiet ) { SCIPsetMessagehdlrQuiet(scip, quiet); } if( logname != NULL ) { SCIPsetMessagehdlrLogfile(scip, logname); } /*********************************** * Version and library information * ***********************************/ SCIPprintVersion(scip, NULL); SCIPinfoMessage(scip, NULL, "\n"); SCIPprintExternalCodes(scip, NULL); SCIPinfoMessage(scip, NULL, "\n"); /***************** * Load settings * *****************/ if( settingsname != NULL ) { SCIP_CALL( readParams(scip, settingsname) ); } else if( defaultsetname != NULL ) { SCIP_CALL( readParams(scip, defaultsetname) ); } if( mastersetname != NULL ) { SCIP_CALL( readParams(GCGrelaxGetMasterprob(scip), mastersetname) ); } /************** * Start SCIP * **************/ if( probname != NULL ) { SCIP_CALL( fromCommandLine(scip, probname, decname) ); } else { SCIPinfoMessage(scip, NULL, "\n"); SCIP_CALL( SCIPstartInteraction(scip) ); } } else { SCIPinfoMessage(scip, NULL, "\nsyntax: %s [-l <logfile>] [-q] [-s <settings>] [-f <problem>] [-m <mastersettings>] [-d <decomposition>] [-b <batchfile>] [-c \"command\"]\n" " -l <logfile> : copy output into log file\n" " -q : suppress screen messages\n" " -s <settings> : load parameter settings (.set) file\n" " -m <mastersettings> : load master parameter settings (.set) file\n" " -f <problem> : load and solve problem file\n" " -d <decomposition> : load decomposition file\n" " -b <batchfile> : load and execute dialog command batch file (can be used multiple times)\n" " -c \"command\" : execute single line of dialog commands (can be used multiple times)\n\n", argv[0]); } return SCIP_OKAY; }
/** reads the given solution file */ static SCIP_RETCODE readSol( SCIP* scip, /**< SCIP data structure */ const char* filename /**< name of the input file */ ) { SCIP_FILE* file; SCIP_Bool error; SCIP_Bool unknownvariablemessage; int lineno; int nfixed; assert(scip != NULL); assert(filename != NULL); /* open input file */ file = SCIPfopen(filename, "r"); if( file == NULL ) { SCIPerrorMessage("cannot open file <%s> for reading\n", filename); SCIPprintSysError(filename); return SCIP_NOFILE; } /* read the file */ error = FALSE; unknownvariablemessage = FALSE; lineno = 0; nfixed = 0; while( !SCIPfeof(file) && !error ) { char buffer[SCIP_MAXSTRLEN]; char varname[SCIP_MAXSTRLEN]; char valuestring[SCIP_MAXSTRLEN]; char objstring[SCIP_MAXSTRLEN]; SCIP_VAR* var; SCIP_Real value; SCIP_Bool infeasible; SCIP_Bool fixed; int nread; /* get next line */ if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL ) break; lineno++; /* the lines "solution status: ..." and "objective value: ..." may preceed the solution information */ if( strncasecmp(buffer, "solution status:", 16) == 0 || strncasecmp(buffer, "objective value:", 16) == 0 ) continue; /* parse the line */ nread = sscanf(buffer, "%s %s %s\n", varname, valuestring, objstring); if( nread < 2 ) { SCIPerrorMessage("invalid input line %d in solution file <%s>: <%s>\n", lineno, filename, buffer); error = TRUE; break; } /* find the variable */ var = SCIPfindVar(scip, varname); if( var == NULL ) { if( !unknownvariablemessage ) { SCIPwarningMessage(scip, "unknown variable <%s> in line %d of solution file <%s>\n", varname, lineno, filename); SCIPwarningMessage(scip, " (further unknown variables are ignored)\n"); unknownvariablemessage = TRUE; } continue; } /* cast the value */ if( strncasecmp(valuestring, "inv", 3) == 0 ) continue; else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 ) value = SCIPinfinity(scip); else if( strncasecmp(valuestring, "-inf", 4) == 0 ) value = -SCIPinfinity(scip); else { nread = sscanf(valuestring, "%lf", &value); if( nread != 1 ) { SCIPerrorMessage("invalid solution value <%s> for variable <%s> in line %d of solution file <%s>\n", valuestring, varname, lineno, filename); error = TRUE; break; } } /* fix the variable */ SCIP_CALL( SCIPfixVar(scip, var, value, &infeasible, &fixed) ); if( infeasible ) { SCIPerrorMessage("infeasible solution value of <%s>[%.15g,%.15g] to %.15g in line %d of solution file <%s>\n", varname, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), value, lineno, filename); error = TRUE; break; } if( fixed ) nfixed++; } /* close input file */ SCIPfclose(file); /* display result */ SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "fixed %d variables from solution file <%s>\n", nfixed, filename); if( error ) return SCIP_READERROR; else return SCIP_OKAY; }
/** reads the next line from the input file into the line buffer; skips comments; * returns whether a line could be read */ static SCIP_Bool getNextLine( SCIP* scip, /**< SCIP data structure */ LPINPUT* lpinput /**< LP reading data */ ) { int i; assert(lpinput != NULL); /* if we previously detected a comment we have to parse the remaining line away if there is something left */ if( !lpinput->endline && lpinput->comment ) { SCIPdebugMessage("Throwing rest of comment away.\n"); do { lpinput->linebuf[LP_MAX_LINELEN-2] = '\0'; (void)SCIPfgets(lpinput->linebuf, (int) sizeof(lpinput->linebuf), lpinput->file); } while( lpinput->linebuf[LP_MAX_LINELEN-2] != '\0' ); lpinput->comment = FALSE; lpinput->endline = TRUE; } /* read next line */ lpinput->linepos = 0; lpinput->linebuf[LP_MAX_LINELEN-2] = '\0'; if( SCIPfgets(lpinput->linebuf, (int) sizeof(lpinput->linebuf), lpinput->file) == NULL ) { /* clear the line, this is really necessary here! */ BMSclearMemoryArray(lpinput->linebuf, LP_MAX_LINELEN); return FALSE; } lpinput->linenumber++; /* if line is too long for our buffer correct the buffer and correct position in file */ if( lpinput->linebuf[LP_MAX_LINELEN-2] != '\0' ) { char* last; /* buffer is full; erase last token since it might be incomplete */ lpinput->endline = FALSE; last = strrchr(lpinput->linebuf, ' '); if( last == NULL ) { SCIPwarningMessage(scip, "we read %d characters from the file; this might indicate a corrupted input file!", LP_MAX_LINELEN - 2); lpinput->linebuf[LP_MAX_LINELEN-2] = '\0'; SCIPdebugMessage("the buffer might be corrupted\n"); } else { SCIPfseek(lpinput->file, -(long) strlen(last) - 1, SEEK_CUR); SCIPdebugMessage("correct buffer, reread the last %ld characters\n", (long) strlen(last) + 1); *last = '\0'; } } else { /* found end of line */ lpinput->endline = TRUE; } lpinput->linebuf[LP_MAX_LINELEN-1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */ lpinput->comment = FALSE; /* skip characters after comment symbol */ for( i = 0; commentchars[i] != '\0'; ++i ) { char* commentstart; commentstart = strchr(lpinput->linebuf, commentchars[i]); if( commentstart != NULL ) { *commentstart = '\0'; *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */ lpinput->comment = TRUE; break; } } return TRUE; }
/** reads a given SCIP solution file, problem has to be transformed in advance */ static SCIP_RETCODE readSol( SCIP* scip, /**< SCIP data structure */ const char* fname /**< name of the input file */ ) { SCIP_SOL* sol; SCIP_FILE* file; SCIP_Bool error; SCIP_Bool unknownvariablemessage; SCIP_Bool stored; SCIP_Bool usevartable; int lineno; assert(scip != NULL); assert(fname != NULL); SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) ); if( !usevartable ) { SCIPerrorMessage("Cannot read solution file if vartable is disabled. Make sure parameter 'misc/usevartable' is set to TRUE.\n"); return SCIP_READERROR; } /* open input file */ file = SCIPfopen(fname, "r"); if( file == NULL ) { SCIPerrorMessage("cannot open file <%s> for reading\n", fname); SCIPprintSysError(fname); return SCIP_NOFILE; } /* create zero solution */ SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) ); /* read the file */ error = FALSE; unknownvariablemessage = FALSE; lineno = 0; while( !SCIPfeof(file) && !error ) { char buffer[SCIP_MAXSTRLEN]; char varname[SCIP_MAXSTRLEN]; char valuestring[SCIP_MAXSTRLEN]; char objstring[SCIP_MAXSTRLEN]; SCIP_VAR* var; SCIP_Real value; int nread; /* get next line */ if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL ) break; lineno++; /* there are some lines which may preceed the solution information */ if( strncasecmp(buffer, "solution status:", 16) == 0 || strncasecmp(buffer, "objective value:", 16) == 0 || strncasecmp(buffer, "Log started", 11) == 0 || strncasecmp(buffer, "Variable Name", 13) == 0 || strncasecmp(buffer, "All other variables", 19) == 0 || strncasecmp(buffer, "\n", 1) == 0 || strncasecmp(buffer, "NAME", 4) == 0 || strncasecmp(buffer, "ENDATA", 6) == 0 ) /* allow parsing of SOL-format on the MIPLIB 2003 pages */ continue; /* parse the line */ nread = sscanf(buffer, "%s %s %s\n", varname, valuestring, objstring); if( nread < 2 ) { SCIPerrorMessage("Invalid input line %d in solution file <%s>: <%s>.\n", lineno, fname, buffer); error = TRUE; break; } /* find the variable */ var = SCIPfindVar(scip, varname); if( var == NULL ) { if( !unknownvariablemessage ) { SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> in line %d of solution file <%s>\n", varname, lineno, fname); SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n"); unknownvariablemessage = TRUE; } continue; } /* cast the value */ if( strncasecmp(valuestring, "inv", 3) == 0 ) continue; else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 ) value = SCIPinfinity(scip); else if( strncasecmp(valuestring, "-inf", 4) == 0 ) value = -SCIPinfinity(scip); else { nread = sscanf(valuestring, "%lf", &value); if( nread != 1 ) { SCIPerrorMessage("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n", valuestring, varname, lineno, fname); error = TRUE; break; } } /* set the solution value of the variable, if not multiaggregated */ if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR ) { SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var)); } else { SCIP_RETCODE retcode; retcode = SCIPsetSolVal(scip, sol, var, value); if( retcode == SCIP_INVALIDDATA ) { if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED ) { SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n", SCIPvarGetName(var)); } else { SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var)); } } else { SCIP_CALL( retcode ); } } } /* close input file */ SCIPfclose(file); if( !error ) { /* add and free the solution */ if( SCIPisTransformed(scip) ) { SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, &stored) ); /* display result */ SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n", fname, stored ? "accepted" : "rejected - solution is infeasible or objective too poor"); } else { /* add primal solution to solution candidate storage, frees the solution afterwards */ SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) ); /* display result */ SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n", fname, stored ? "accepted as candidate, will be checked when solving starts" : "rejected - solution objective too poor"); } return SCIP_OKAY; } else { /* free solution */ SCIP_CALL( SCIPfreeSol(scip, &sol) ); return SCIP_READERROR; } }
/** problem reading method of reader * * In order to determine the type of the file, we have to open it. Thus, it has to be opened * twice. This might be removed, but is likely to not hurt the performance too much. */ static SCIP_DECL_READERREAD(readerReadSol) { /*lint --e{715}*/ SCIP_FILE* file; char buffer[SCIP_MAXSTRLEN]; char *s; assert(reader != NULL); assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0); assert(result != NULL); *result = SCIP_DIDNOTRUN; if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM ) { SCIPerrorMessage("reading of solution file is only possible after a problem was created\n"); return SCIP_READERROR; } if( SCIPgetStage(scip) == SCIP_STAGE_SOLVED ) { SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was ignored - problem is already solved to optimality\n", filename); *result = SCIP_SUCCESS; return SCIP_OKAY; } /* open input file in order to determine type */ file = SCIPfopen(filename, "r"); if( file == NULL ) { SCIPerrorMessage("cannot open file <%s> for reading\n", filename); SCIPprintSysError(filename); return SCIP_NOFILE; } /* get next line */ if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL ) { SCIPerrorMessage("cannot parse file.\n"); return SCIP_READERROR; } /* close file */ SCIPfclose(file); /* decide whether it is xml */ s = buffer; /* skip spaces */ while( isspace((unsigned char)*s) ) ++s; if( s[0] == '<' && s[1] == '?' && s[2] == 'x' && s[3] == 'm' && s[4] == 'l' ) { /* read XML solution and add it to the solution pool */ SCIP_CALL( readXMLSol(scip, filename) ); } else { /* read the solution and add it to the solution pool */ SCIP_CALL( readSol(scip, filename) ); } *result = SCIP_SUCCESS; return SCIP_OKAY; }
/** read file */ static SCIP_RETCODE readFile( SCIP* scip, /**< SCIP data structure */ const char* filename, /**< name of input file */ SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */ ) { SCIP_FILE* fp; char buf[SM_MAX_LINELEN]; int lineno = 0; char* s; STATE state = NEXT; assert(filename != NULL); if( NULL == (fp = SCIPfopen(filename, "r")) ) { perror(filename); return SCIP_READERROR; } /* parse file line by line */ while( state != END && state != ERROR && (NULL != SCIPfgets(buf, sizeof(buf), fp)) ) { /* count line number */ lineno++; if( NULL != (s = strpbrk(buf, "*\r\n")) ) *s = '\0'; else { parseError(scip, lineno, "line truncated", NULL, &state); break; } s = buf; /* remove white space */ while(isspace(*s)) s++; /* skip empty lines */ if (*s == '\0') continue; if( state == NEXT ) { checkForNewSection(s, &state); } SCIPdebugMessage("input line: <%s>\n", s); switch( state ) { case ERROR: break; case NEXT: break; case NJOBS: SCIP_CALL( getNJobs(scip, lineno, s, &state, rcpspdata) ); break; case JOBS: SCIP_CALL( getJobs(scip, lineno, s, &state, rcpspdata) ); break; case NRESOURCES: SCIP_CALL( getNResources(scip, lineno, s, &state, rcpspdata) ); break; case RESOURCENAMES: SCIP_CALL( getResourcesNames(scip, lineno, s, &state, rcpspdata) ); break; case RESOURCECAPACITIES: SCIP_CALL( getResourcesCapacities(scip, lineno, s, &state, rcpspdata) ); break; case PRECEDENCES: SCIP_CALL( getPrecedence(scip, lineno, s, &state, rcpspdata) ); break; case END: parseError(scip, lineno, "additional characters after END", NULL, &state); break; default: SCIPerrorMessage("invalid reading state\n"); SCIPABORT(); } } SCIPfclose(fp); if( state != END && state != ERROR ) parseError(scip, lineno, "unexpected EOF", NULL, &state); if( state == ERROR ) return SCIP_READERROR; else return SCIP_OKAY; }