/** returns the variable with the given name, or creates a new variable if it does not exist */ static SCIP_RETCODE getVariable( SCIP* scip, /**< SCIP data structure */ char* name, /**< name of the variable */ SCIP_VAR** var /**< pointer to store the variable */ ) { assert(name != NULL); assert(var != NULL); *var = SCIPfindVar(scip, name); if( *var == NULL ) return SCIP_READERROR; return SCIP_OKAY; }
/** reads a block section */ static SCIP_RETCODE readBlock( SCIP* scip, /**< SCIP data structure */ BLKINPUT* blkinput, /**< BLK reading data */ SCIP_READERDATA* readerdata /**< reader data */ ) { int blockid; assert(blkinput != NULL); blockid = blkinput->blocknr; while( getNextToken(blkinput) ) { SCIP_VAR* var; int varidx; int oldblock; /* check if we reached a new section */ if( isNewSection(scip, blkinput) ) return SCIP_OKAY; /* the token must be the name of an existing variable */ var = SCIPfindVar(scip, blkinput->token); if( var == NULL ) { syntaxError(scip, blkinput, "unknown variable in block section"); return SCIP_OKAY; } varidx = SCIPvarGetProbindex(var); oldblock = readerdata->varstoblock[varidx]; /* set the block number of the variable to the number of the current block */ if( oldblock == NOVALUE ) { SCIPdebugMessage("\tVar %s temporary in block %d.\n", SCIPvarGetName(var), blockid); readerdata->varstoblock[varidx] = blockid; ++(readerdata->nblockvars[blockid]); } /* variable was assigned to another (non-linking) block before, so it becomes a linking variable, now */ else if( (oldblock != LINKINGVALUE) ) { assert(oldblock != blockid); SCIPdebugMessage("\tVar %s is linking (old %d != %d new).\n", SCIPvarGetName(var), oldblock, blockid); readerdata->varstoblock[varidx] = LINKINGVALUE; /* decrease the number of variables in the old block and increase the number of linking variables */ --(readerdata->nblockvars[oldblock]); ++(readerdata->nlinkingvars); assert(readerdata->nlinkingvarsblocks[varidx] == 0); assert(readerdata->linkingvarsblocks[varidx] == NULL); SCIP_CALL( SCIPallocMemoryArray(scip, &readerdata->linkingvarsblocks[varidx], 2) ); /*lint !e506 !e866*/ readerdata->linkingvarsblocks[varidx][0] = oldblock; readerdata->linkingvarsblocks[varidx][1] = blockid; readerdata->nlinkingvarsblocks[varidx] = 2; } /* variable is a linking variable already, store the new block to which it belongs */ else { assert(oldblock == LINKINGVALUE); assert(readerdata->nlinkingvarsblocks[varidx] >= 2); assert(readerdata->linkingvarsblocks[varidx] != NULL); SCIP_CALL( SCIPreallocMemoryArray(scip, &readerdata->linkingvarsblocks[varidx], readerdata->nlinkingvarsblocks[varidx] + 1) ); /*lint !e866*/ readerdata->linkingvarsblocks[varidx][readerdata->nlinkingvarsblocks[varidx]] = blockid; ++(readerdata->nlinkingvarsblocks[varidx]); } } 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 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; } }
/** reads a given xml solution file */ static SCIP_RETCODE readXMLSol( SCIP* scip, /**< SCIP data structure */ const char* filename /**< name of the input file */ ) { SCIP_Bool unknownvariablemessage; SCIP_SOL* sol; SCIP_Bool error; XML_NODE* start; const XML_NODE* varsnode; const XML_NODE* varnode; const char* tag; assert( scip != NULL ); assert( filename != NULL ); /* read xml file */ start = xmlProcess(filename); if( start == NULL ) { SCIPerrorMessage("Some error occured during parsing the XML solution file.\n"); return SCIP_READERROR; } /* create zero solution */ SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) ); error = FALSE; /* find variable sections */ tag = "variables"; varsnode = xmlFindNodeMaxdepth(start, tag, 0, 3); if( varsnode == NULL ) { /* free xml data */ xmlFreeNode(start); SCIPerrorMessage("Variable section not found.\n"); return SCIP_READERROR; } /* loop through all variables */ unknownvariablemessage = FALSE; for( varnode = xmlFirstChild(varsnode); varnode != NULL; varnode = xmlNextSibl(varnode) ) { SCIP_VAR* var; const char* varname; const char* varvalue; SCIP_Real value; int nread; /* find variable name */ varname = xmlGetAttrval(varnode, "name"); if( varname == NULL ) { SCIPerrorMessage("Attribute \"name\" of variable not found.\n"); error = TRUE; break; } /* find the variable */ var = SCIPfindVar(scip, varname); if( var == NULL ) { if( !unknownvariablemessage ) { SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> of solution file <%s>\n", varname, filename); SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n"); unknownvariablemessage = TRUE; } continue; } /* find value of variable */ varvalue = xmlGetAttrval(varnode, "value"); if( varvalue == NULL ) { SCIPerrorMessage("Attribute \"value\" of variable not found.\n"); error = TRUE; break; } /* cast the value */ if( strncasecmp(varvalue, "inv", 3) == 0 ) continue; else if( strncasecmp(varvalue, "+inf", 4) == 0 || strncasecmp(varvalue, "inf", 3) == 0 ) value = SCIPinfinity(scip); else if( strncasecmp(varvalue, "-inf", 4) == 0 ) value = -SCIPinfinity(scip); else { nread = sscanf(varvalue, "%lf", &value); if( nread != 1 ) { SCIPwarningMessage(scip, "invalid solution value <%s> for variable <%s> in XML solution file <%s>\n", varvalue, varname, filename); 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 ); } } } if( !error ) { SCIP_Bool stored; /* 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", filename, stored ? "accepted" : "rejected - solution is infeasible or objective too poor"); } else { SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) ); /* display result */ SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n", filename, stored ? "accepted as candidate, will be checked when solving starts" : "rejected - solution objective too poor"); } } else { /* free solution */ SCIP_CALL( SCIPfreeSol(scip, &sol) ); /* free xml data */ xmlFreeNode(start); return SCIP_READERROR; } /* free xml data */ xmlFreeNode(start); return SCIP_OKAY; }
/** reads solution from given file into given arrays */ static SCIP_RETCODE readSolfile( SCIP_SET* set, /**< global SCIP settings */ const char* solfilename, /**< solution filename to read */ char*** names, /**< pointer to store the array of variable names */ SCIP_Real** vals, /**< pointer to store the array of solution values */ int* nvals, /**< pointer to store the number of non-zero elements */ int* valssize /**< pointer to store the length of the variable names and solution values arrays */ ) { FILE* file; int nonvalues; int i; assert(set != NULL); assert(solfilename != NULL); assert(names != NULL); assert(*names == NULL); assert(vals != NULL); assert(*vals == NULL); assert(nvals != NULL); assert(valssize != NULL); printf("***** debug: reading solution file <%s>\n", solfilename); /* open solution file */ file = fopen(solfilename, "r"); if( file == NULL ) { SCIPerrorMessage("cannot open solution file <%s> specified in scip/debug.h\n", solfilename); SCIPprintSysError(solfilename); return SCIP_NOFILE; } /* read data */ nonvalues = 0; *valssize = 0; while( !feof(file) ) { char buf[SCIP_MAXSTRLEN]; char name[SCIP_MAXSTRLEN]; char objstring[SCIP_MAXSTRLEN]; SCIP_Real val; int nread; if( fgets(buf, SCIP_MAXSTRLEN, file) == NULL ) { if( feof(file) ) break; else return SCIP_READERROR; } /* the lines "solution status: ..." and "objective value: ..." may preceed the solution information */ if( strncmp(buf, "solution", 8) == 0 || strncmp(buf, "objective", 9) == 0 ) { nonvalues++; continue; } /* skip empty lines */ if( strlen(buf) == 1 ) { nonvalues++; continue; } nread = sscanf(buf, "%s %lf %s\n", name, &val, objstring); if( nread < 2 ) { printf("invalid input line %d in solution file <%s>: <%s>\n", *nvals + nonvalues, SCIP_DEBUG_SOLUTION, name); fclose(file); return SCIP_READERROR; } /* allocate memory */ if( *nvals >= *valssize ) { *valssize = MAX(2 * *valssize, (*nvals)+1); SCIP_ALLOC( BMSreallocMemoryArray(names, *valssize) ); SCIP_ALLOC( BMSreallocMemoryArray(vals, *valssize) ); } assert(*nvals < *valssize); /* store solution value in sorted list */ for( i = *nvals; i > 0 && strcmp(name, (*names)[i-1]) < 0; --i ) { (*names)[i] = (*names)[i-1]; (*vals)[i] = (*vals)[i-1]; } SCIP_ALLOC( BMSduplicateMemoryArray(&(*names)[i], name, strlen(name)+1) ); SCIPdebugMessage("found variable <%s>: value <%g>\n", (*names)[i], val); (*vals)[i] = val; (*nvals)++; } debugsolval = 0.0; /* get solution value */ for( i = *nvals - 1; i >= 0; --i) { SCIP_VAR* var; var = SCIPfindVar(set->scip, (*names)[i]); if( var != NULL ) debugsolval += (*vals)[i] * SCIPvarGetObj(var); } SCIPdebugMessage("Debug Solution value is %g.\n", debugsolval); /* close file */ fclose(file); /* remember the set pointer to identify sub-MIP calls */ mainscipset = set; printf("***** debug: read %d non-zero entries\n", *nvals); return SCIP_OKAY; }