/** main method starting SCIP */ int main( int argc, /**< number of arguments from the shell */ char** argv /**< array of shell arguments */ ) { SCIP_RETCODE retcode; SCIP_Bool interactive; const char* setfile; int i; assert(argc >= 1); if( argc == 1 ) { SCIP* scip; SCIP_CALL_ABORT( SCIPcreate(&scip) ); SCIPprintVersion(scip, NULL); printf("\n"); SCIP_CALL_ABORT( SCIPfree(&scip) ); printf("Usage: %s <nl-file> { [-AMPL] | [<settings-file>] | -i }\n", argv[0]); printf("\n"); printf(" -i starts the SCIP shell after reading settings and .nl file, instead of starting the SCIP solve\n"); return 0; } /* check command line arguments after .nl file */ interactive = FALSE; setfile = NULL; for( i = 2; i < argc; ++i ) { if( strcmp(argv[i], "-AMPL") == 0 ) continue; if( strcmp(argv[i], "-i") == 0 ) { interactive = TRUE; continue; } setfile = argv[i]; } if( setfile == NULL && SCIPfileExists("scip.set") ) setfile = "scip.set"; retcode = run(argv[1], setfile, interactive); /* evaluate retrun code of the SCIP process */ if( retcode != SCIP_OKAY ) { /* write error back trace */ SCIPprintError(retcode); return -1; } return 0; }
/* standard "main" method for mex interface */ void mexFunction( int nlhs, /* number of expected outputs */ mxArray* plhs[], /* array of pointers to output arguments */ int nrhs, /* number of inputs */ const mxArray* prhs[] /* array of pointers to input arguments */ ) { SCIP* scip; SCIP_VAR** vars; SCIP_Real* objs; SCIP_Real* lhss; SCIP_Real* rhss; SCIP_Real* lbs; SCIP_Real* ubs; SCIP_Real* matrix; SCIP_Real* bestsol; SCIP_Real* objval; char* vartypes; char objsense[SCIP_MAXSTRLEN]; int nvars; int nconss; int stringsize; int i; if( SCIPmajorVersion() < 2 ) { mexErrMsgTxt("SCIP versions less than 2.0 are not supported\n"); return; } /* initialize SCIP */ SCIP_CALL_ABORT( SCIPcreate(&scip) ); /* output SCIP information */ SCIPprintVersion(scip, NULL); /* include default SCIP plugins */ SCIP_CALL_ABORT( SCIPincludeDefaultPlugins(scip) ); if( nlhs != 2 || nrhs != 8 ) mexErrMsgTxt("invalid number of parameters. Call as [bestsol, objval] = matscip(matrix, lhs, rhs, obj, lb, ub, vartype, objsense)\n"); if( mxIsSparse(prhs[0]) ) mexErrMsgTxt("sparse matrices are not supported yet"); /* ???????? of course this has to change */ /* get linear constraint coefficient matrix */ matrix = mxGetPr(prhs[0]); if( matrix == NULL ) mexErrMsgTxt("matrix must not be NULL"); if( mxGetNumberOfDimensions(prhs[0]) != 2 ) mexErrMsgTxt("matrix must have exactly two dimensions"); /* get dimensions of matrix */ nconss = mxGetM(prhs[0]); nvars = mxGetN(prhs[0]); assert(nconss > 0); assert(nvars > 0); /* get left hand sides of linear constraints */ lhss = mxGetPr(prhs[1]); if( mxGetM(prhs[1]) != nconss ) mexErrMsgTxt("dimension of left hand side vector does not match matrix dimension"); assert(lhss != NULL); /* get right hand sides of linear constraints */ rhss = mxGetPr(prhs[2]); if( mxGetM(prhs[2]) != nconss ) mexErrMsgTxt("dimension of right hand side vector does not match matrix dimension"); assert(rhss != NULL); /* get objective coefficients */ objs = mxGetPr(prhs[3]); if( mxGetM(prhs[3]) != nvars ) mexErrMsgTxt("dimension of objective coefficient vector does not match matrix dimension"); /* get lower bounds of variables */ lbs = mxGetPr(prhs[4]); if( mxGetM(prhs[4]) != nvars ) mexErrMsgTxt("dimension of lower bound vector does not match matrix dimension"); /* get upper bounds of variables */ ubs = mxGetPr(prhs[5]); if( mxGetM(prhs[5]) != nvars ) mexErrMsgTxt("dimension of upper bound vector does not match matrix dimension"); /* allocate memory for variable type characters */ SCIP_CALL_ABORT( SCIPallocMemoryArray(scip, &vartypes, nvars+1) ); /* get variable types */ if( mxGetString(prhs[6], vartypes, nvars+1) != 0 ) mexErrMsgTxt("Error when parsing variable types, maybe a wrong vector dimension?"); /* get objective sense */ stringsize = mxGetNumberOfElements(prhs[7]); if( stringsize != 3 ) mexErrMsgTxt("objective sense must be a three character word: \"max\" or \"min\""); if( mxGetString(prhs[7], objsense, stringsize+1) != 0) mexErrMsgTxt("Error when parsing objective sense string"); if( strcmp(objsense,"max") != 0 && strcmp(objsense,"min") != 0 ) mexErrMsgTxt("objective sense must be either \"max\" or \"min\""); /* get output parameters */ plhs[0] = mxCreateDoubleMatrix(nvars, 1, mxREAL); bestsol = mxGetPr(plhs[0]); plhs[1] = mxCreateDoubleScalar(mxREAL); objval = mxGetPr(plhs[1]); /* create SCIP problem */ SCIP_CALL_ABORT( SCIPcreateProb(scip, "mex_prob", NULL, NULL, NULL, NULL, NULL, NULL, NULL) ); /* allocate memory for variable array */ SCIP_CALL_ABORT( SCIPallocMemoryArray(scip, &vars, nvars) ); /* create variables */ for( i = 0; i < nvars; ++i) { SCIP_VARTYPE vartype; char varname[SCIP_MAXSTRLEN]; /* convert vartype character to SCIP vartype */ if( vartypes[i] == 'i' ) vartype = SCIP_VARTYPE_INTEGER; else if( vartypes[i] == 'b' ) vartype = SCIP_VARTYPE_BINARY; else if( vartypes[i] == 'c' ) vartype = SCIP_VARTYPE_CONTINUOUS; else mexErrMsgTxt("unkown variable type"); /* variables get canonic names x_i */ (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "x_%d", i); /* create variable object and add it to SCIP */ SCIP_CALL_ABORT( SCIPcreateVar(scip, &vars[i], varname, lbs[i], ubs[i], objs[i], vartype, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) ); assert(vars[i] != NULL); SCIP_CALL_ABORT( SCIPaddVar(scip, vars[i]) ); } /* create linear constraints */ for( i = 0; i < nconss; ++i ) { SCIP_CONS* cons; char consname[SCIP_MAXSTRLEN]; int j; /* constraints get canonic names cons_i */ (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cons_%d", i); /* create empty linear constraint */ SCIP_CALL_ABORT( SCIPcreateConsLinear(scip, &cons, consname, 0, NULL, NULL, lhss[i], rhss[i], TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) ); /* add non-zero coefficients to linear constraint */ for( j = 0; j < nvars; ++j ) { if( !SCIPisFeasZero(scip, matrix[i+j*nconss]) ) { SCIP_CALL_ABORT( SCIPaddCoefLinear(scip, cons, vars[j], matrix[i+j*nconss]) ); } } /* add constraint to SCIP and release it */ SCIP_CALL_ABORT( SCIPaddCons(scip, cons) ); SCIP_CALL_ABORT( SCIPreleaseCons(scip, &cons) ); } /* set objective sense in SCIP */ if( strcmp(objsense,"max") == 0) { SCIP_CALL_ABORT( SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE) ); } else if( strcmp(objsense,"min") == 0) { SCIP_CALL_ABORT( SCIPsetObjsense(scip, SCIP_OBJSENSE_MINIMIZE) ); } else /* this should have been caught earlier when parsing objsense */ mexErrMsgTxt("unkown objective sense"); /* solve SCIP problem */ SCIP_CALL_ABORT( SCIPsolve(scip) ); /* if SCIP found a solution, pass it back into MATLAB output parameters */ if( SCIPgetNSols > 0 ) { SCIP_SOL* scipbestsol; /* get incumbent solution vector */ scipbestsol = SCIPgetBestSol(scip); assert(scipbestsol != NULL); /* get objective value of incumbent solution */ *objval = SCIPgetSolOrigObj(scip, scipbestsol); assert(!SCIPisInfinity(scip, REALABS(*objval))); /* copy solution values into output vector */ for( i = 0; i < nvars; ++i ) bestsol[i] = SCIPgetSolVal(scip,scipbestsol,vars[i]); } /* release variables */ for( i = 0; i < nvars; ++i ) { SCIP_CALL_ABORT( SCIPreleaseVar(scip, &vars[i]) ); } /* free memory for variable arrays */ SCIPfreeMemoryArray(scip, &vartypes); SCIPfreeMemoryArray(scip, &vars); /* deinitialize SCIP */ SCIP_CALL_ABORT( SCIPfree(&scip) ); /* check for memory leaks */ BMScheckEmptyMemory(); return; }
/** 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; }
/** creates a SCIP instance with default plugins, evaluates command line parameters, runs SCIP appropriately, * and frees the SCIP instance */ static SCIP_RETCODE runSCIP( int argc, /**< number of shell parameters */ char** argv /**< array with shell parameters */ ) { SCIP* scip = NULL; /********* * Setup * *********/ /* initialize SCIP */ SCIP_CALL( SCIPcreate(&scip) ); /*********************** * Version information * ***********************/ SCIPprintVersion(scip, NULL); std::cout << std::endl; /* include default SCIP plugins */ SCIP_CALL( SCIPincludeDefaultPlugins(scip) ); /************** * Parameters * **************/ if( argc >= 3 ) { SCIP_CALL( readParams(scip, argv[2]) ); } else { SCIP_CALL( readParams(scip, NULL) ); } /*CHECK_OKAY( SCIPwriteParams(scip, "scipmip.set", TRUE) );*/ /************** * Start SCIP * **************/ if( argc >= 2 ) { SCIP_CALL( fromCommandLine(scip, argv[1]) ); } else { printf("\n"); SCIP_CALL( interactive(scip) ); } /******************** * Deinitialization * ********************/ SCIP_CALL( SCIPfree(&scip) ); BMScheckEmptyMemory(); return SCIP_OKAY; }
static SCIP_RETCODE run( const char* nlfile, /**< name of AMPL .nl file */ const char* setfile, /**< SCIP settings file, or NULL to try default scip.set */ SCIP_Bool interactive /**< whether to start SCIP interactive shell instead of solving command */ ) { SCIP* scip; char buffer[SCIP_MAXSTRLEN]; SCIP_Bool printstat; assert(nlfile != NULL); /* setup SCIP and print version information */ SCIP_CALL( SCIPcreate(&scip) ); SCIPprintVersion(scip, NULL); SCIPinfoMessage(scip, NULL, "\n"); SCIP_CALL( SCIPincludeDefaultPlugins(scip) ); SCIP_CALL( SCIPincludeReaderNl(scip) ); SCIP_CALL( SCIPaddBoolParam(scip, "display/statistics", "whether to print statistics on a solve", NULL, FALSE, FALSE, NULL, NULL) ); SCIPprintExternalCodes(scip, NULL); SCIPinfoMessage(scip, NULL, "\n"); /* read setting file */ if( setfile != NULL ) { SCIP_CALL( SCIPreadParams(scip, setfile) ); } SCIP_CALL( SCIPgetBoolParam(scip, "display/statistics", &printstat) ); /* setup commands to be executed by SCIP */ SCIP_CALL( SCIPaddDialogInputLine(scip, "display param") ); /* add .nl extension, if not given */ (void) SCIPsnprintf(buffer, SCIP_MAXSTRLEN, "read %s%s", nlfile, (strlen(nlfile) < 3 || strcmp(nlfile+(strlen(nlfile)-3), ".nl") != 0) ? ".nl" : ""); SCIP_CALL( SCIPaddDialogInputLine(scip, buffer) ); if( !interactive ) { /* SCIP_CALL( SCIPaddDialogInputLine(scip, "display problem") ); */ SCIP_CALL( SCIPaddDialogInputLine(scip, "optimize") ); SCIP_CALL( SCIPaddDialogInputLine(scip, "write amplsol") ); if( printstat ) { SCIP_CALL( SCIPaddDialogInputLine(scip, "display statistics") ); } SCIP_CALL( SCIPaddDialogInputLine(scip, "quit") ); } /* run SCIP */ SCIP_CALL( SCIPstartInteraction(scip) ); SCIP_CALL( SCIPfree(&scip) ); return SCIP_OKAY; }