//******************************************************************* int CSolver:: Create(int estRows, int estCols, int estNonZeros, int probsense, char* probname, int namesize, int nSerialnum, char* licenvstring) { int i; char buff[100]; setLogFile( (char*)probname); memset( m_error, sizeof(m_error), 0 ); m_debugLog = 0; m_probType = PROBLEM_TYPE_LP; m_estRows = estRows; m_estCols = estCols; m_estNonZeros = estNonZeros; m_nObjSense = probsense; m_nNameSize = namesize; m_nColCount = 0; m_nRowCount = 0; // create arrays given problem size estimates // matrix m_pRowNdx = new int[estNonZeros]; m_pColNdx = new int[estNonZeros]; m_pCoef = new double[estNonZeros]; m_nRowItems = 0; m_nColItems = 0; m_nCoefItems = 0; // rim m_pObj = new double[estCols]; m_pRhs = new double[estRows]; m_pRhsSense = new char[estRows]; m_pCtype = new char[estCols]; // column type m_pRstat = new int[estRows]; m_pCstat = new int[estCols]; m_nObjItems = 0; m_nRhsItems = 0; m_nRhsSense = 0; // column bounds m_pBdl = new double[estCols]; m_pBdu = new double[estCols]; m_nBdItems = 0; if (m_pBdl == NULL || m_pBdu == NULL ) return -1; for( i=0; i< estCols; i++ ) { m_pBdl[i] = 0.0; m_pBdu[i] = INFBOUND; } //---misc // build problem name string if( probname != NULL ) { // user supplied a problem name on construction, so use that name m_pszProbname = new char[strlen(probname)+1]; strcpy(m_pszProbname,probname); } else { // no name given for problem m_pszProbname = new char[strlen("NONAME")+1]; strcpy(m_pszProbname,"NONAME"); } m_lp = NULL; m_env = NULL; m_obj = 0; m_x = NULL; m_pi = NULL; m_slack = NULL; m_dj = NULL; m_nPosInCstore =0; m_cstore=NULL; m_nPosInCname =0; m_cname=NULL; m_nPosInRstore =0; m_rstore=NULL; m_nPosInRname =0; m_rname=NULL; m_RowMap.Create(estRows); m_ColMap.Create(estCols); CreateNameSpace(); // check for memory allocation error if( m_pRowNdx == NULL || m_pColNdx == NULL || m_pCoef == NULL || m_pObj == NULL || m_pRhs == NULL || m_pRhsSense ==NULL || m_pBdl == NULL || m_pBdu == NULL || m_cstore == NULL || m_cname == NULL || m_rstore == NULL || m_rname == NULL ) { Message("Not enough memory!"); return -1; // failure error } sprintf(buff,"CPLEX Serial Number = %d", nSerialnum); Message(buff); //! if ( nSerialnum == 0 ) //! // no serial number assume development license //! else //! // serial number provide assume runtime license m_env = CPXopenCPLEXruntime(&m_status, nSerialnum, licenvstring); if (m_env == NULL){ CPXgeterrorstring( m_env, m_status, m_error ); if (nSerialnum == 0 ) Message( "CPXopenCPLEXdevelop returned NULL !"); else Message( "CPXopenCPLEXruntime returned NULL"); SetError("Failed to get a CPLEX environment"); return -1; } CPXgetchannels(m_env, &m_cpxresults, &m_cpxwarning, &m_cpxerror, &m_cpxlog); char cpxbuff[80]; sprintf(cpxbuff, "%s.%s", probname, "cpx"); m_cpxFile = CPXfopen(cpxbuff,"w"); if (m_cpxFile == NULL ) { m_log.write("opening cplexlog.log failed"); } CPXaddfuncdest(m_env, m_cpxresults, &m_cbData, channelsfunc); CPXaddfuncdest(m_env, m_cpxwarning, &m_cbData, channelsfunc); CPXaddfuncdest(m_env, m_cpxerror, &m_cbData, channelsfunc); if ( CPXsetlogfile(m_env, m_cpxFile) != 0 ) { m_log.write("failed to set channels file"); } m_log.getTimeStamp(buff); m_bCreated = 1; CPXmsg(m_cpxlog, "%s : %s\n\n","*** Begin Log ***", buff ); return 0; }
int main (void) { char probname[16]; /* Problem name is max 16 characters */ /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ int solstat; double objval; double x[NUMCOLS]; double pi[NUMROWS]; double slack[NUMROWS]; double dj[NUMCOLS]; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int i, j; int cur_numrows, cur_numcols; char errmsg[CPXMESSAGEBUFSIZE]; CPXCHANNELptr cpxerror = NULL; CPXCHANNELptr cpxwarning = NULL; CPXCHANNELptr cpxresults = NULL; CPXCHANNELptr ourchannel = NULL; char errorlabel[] = "cpxerror"; char warnlabel[] = "cpxwarning"; char reslabel[] = "cpxresults"; char ourlabel[] = "Our Channel"; char ourmessage[] = "Our Message"; CPXFILEptr fpout = NULL; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ /* Since the message handler is yet to be set up, we'll call our messaging function directly to print out any errors */ if ( env == NULL ) { ourmsgfunc (ourmessage, "Could not open CPLEX environment.\n"); goto TERMINATE; } /* Now get the standard channels. If an error, just call our message function directly. */ status = CPXgetchannels (env, &cpxresults, &cpxwarning, &cpxerror, NULL); if ( status ) { ourmsgfunc (ourmessage, "Could not get standard channels.\n"); CPXgeterrorstring (env, status, errmsg); ourmsgfunc (ourmessage, errmsg); goto TERMINATE; } /* Now set up the error channel first. The label will be "cpxerror" */ status = CPXaddfuncdest (env, cpxerror, errorlabel, ourmsgfunc); if ( status ) { ourmsgfunc (ourmessage, "Could not set up error message handler.\n"); CPXgeterrorstring (env, status, errmsg); ourmsgfunc (ourmessage, errmsg); } /* Now that we have the error message handler set up, all CPLEX generated errors will go through ourmsgfunc. So we don't have to use CPXgeterrorstring to determine the text of the message. We can also use CPXmsg to do any other printing. */ status = CPXaddfuncdest (env, cpxwarning, warnlabel, ourmsgfunc); if ( status ) { CPXmsg (cpxerror, "Failed to set up handler for cpxwarning.\n"); goto TERMINATE; } status = CPXaddfuncdest (env, cpxresults, reslabel, ourmsgfunc); if ( status ) { CPXmsg (cpxerror, "Failed to set up handler for cpxresults.\n"); goto TERMINATE; } /* Now turn on the iteration display. */ status = CPXsetintparam (env, CPXPARAM_Simplex_Display, 2); if ( status ) { CPXmsg (cpxerror, "Failed to turn on simplex display level.\n"); goto TERMINATE; } /* Create the problem. */ strcpy (probname, "example"); lp = CPXcreateprob (env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { CPXmsg (cpxerror, "Failed to create LP.\n"); goto TERMINATE; } /* Now populate the problem with the data. */ status = populatebycolumn (env, lp); if ( status ) { CPXmsg (cpxerror, "Failed to populate problem data.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); if ( status ) { CPXmsg (cpxerror, "Failed to optimize LP.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { CPXmsg (cpxerror, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. We will also write it to a file as well by setting up a file destination and a function destination. */ ourchannel = CPXaddchannel (env); if ( ourchannel == NULL ) { CPXmsg (cpxerror, "Failed to set up our private channel.\n"); goto TERMINATE; } fpout = CPXfopen ("lpex5.msg", "w"); if ( fpout == NULL ) { CPXmsg (cpxerror, "Failed to open lpex5.msg file for output.\n"); goto TERMINATE; } status = CPXaddfpdest (env, ourchannel, fpout); if ( status ) { CPXmsg (cpxerror, "Failed to set up output file destination.\n"); goto TERMINATE; } status = CPXaddfuncdest (env, ourchannel, ourlabel, ourmsgfunc); if ( status ) { CPXmsg (cpxerror, "Failed to set up our output function.\n"); goto TERMINATE; } /* Now any message to channel ourchannel will go into the file and into the file opened above. */ CPXmsg (ourchannel, "\nSolution status = %d\n", solstat); CPXmsg (ourchannel, "Solution value = %f\n\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is, rather than using sizes from when the problem was built. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); for (i = 0; i < cur_numrows; i++) { CPXmsg (ourchannel, "Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); } for (j = 0; j < cur_numcols; j++) { CPXmsg (ourchannel, "Column %d: Value = %10f Reduced cost = %10f\n", j, x[j], dj[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "lpex5.lp", NULL); if ( status ) { CPXmsg (cpxerror, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* First check if ourchannel is open */ if ( ourchannel != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, ourchannel, ourlabel, ourmsgfunc); if ( chanstat ) { strcpy (errmsg, "CPXdelfuncdest failed.\n"); ourmsgfunc (ourmessage, errmsg); if (!status) status = chanstat; } if ( fpout != NULL ) { chanstat = CPXdelfpdest (env, ourchannel, fpout); if ( chanstat ) { strcpy (errmsg, "CPXdelfpdest failed.\n"); ourmsgfunc (ourmessage, errmsg); if (!status) status = chanstat; } CPXfclose (fpout); } chanstat = CPXdelchannel (env, &ourchannel); if ( chanstat ) { strcpy (errmsg, "CPXdelchannel failed.\n"); ourmsgfunc (ourmessage, errmsg); if (!status) status = chanstat; } } /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { strcpy (errmsg, "CPXfreeprob failed.\n"); ourmsgfunc (ourmessage, errmsg); } } /* Now delete our function destinations from the 3 CPLEX channels. */ if ( cpxresults != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, cpxresults, reslabel, ourmsgfunc); if ( chanstat && !status ) { status = chanstat; strcpy (errmsg, "Failed to delete cpxresults function.\n"); ourmsgfunc (ourmessage, errmsg); } } if ( cpxwarning != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, cpxwarning, warnlabel, ourmsgfunc); if ( chanstat && !status ) { status = chanstat; strcpy (errmsg, "Failed to delete cpxwarning function.\n"); ourmsgfunc (ourmessage, errmsg); } } if ( cpxerror != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, cpxerror, errorlabel, ourmsgfunc); if ( chanstat && !status ) { status = chanstat; strcpy (errmsg, "Failed to delete cpxerror function.\n"); ourmsgfunc (ourmessage, errmsg); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { strcpy (errmsg, "Could not close CPLEX environment.\n"); ourmsgfunc (ourmessage, errmsg); CPXgeterrorstring (env, status, errmsg); ourmsgfunc (ourmessage, errmsg); } } return (status); } /* END main */