//===========================================================================// void MILPBlock_DecompApp::initializeApp() { UtilPrintFuncBegin(m_osLog, m_classTag, "initializeApp()", m_appParam.LogLevel, 2); //--- //--- read MILPBlock instance (mps format) //--- string fileName; if (m_appParam.DataDir != "") { fileName = m_appParam.DataDir + UtilDirSlash() + m_param.Instance; } else { fileName = m_appParam.Instance; } m_mpsIO.messageHandler()->setLogLevel(m_param.LogLpLevel); int rstatus = m_mpsIO.readMps(fileName.c_str()); if(rstatus < 0){ cerr << "Error: Filename = " << fileName << " failed to open." << endl; throw UtilException("I/O Error.", "initalizeApp", "MILPBlock_DecompApp"); } if(m_appParam.LogLevel >= 2) (*m_osLog) << "Objective Offset = " << UtilDblToStr(m_mpsIO.objectiveOffset()) << endl; //--- //--- set best known lb/ub //--- double offset = m_mpsIO.objectiveOffset(); setBestKnownLB(m_appParam.BestKnownLB + offset); setBestKnownUB(m_appParam.BestKnownUB + offset); //--- //--- read block file //--- readBlockFile(); //--- //--- create models //--- createModels(); UtilPrintFuncEnd(m_osLog, m_classTag, "initializeApp()", m_appParam.LogLevel, 2); }
//===========================================================================// int main(int argc, char** argv) { try { //--- //--- create the utility class for parsing parameters //--- UtilParameters utilParam(argc, argv); bool doCut = utilParam.GetSetting("doCut", true); bool doPriceCut = utilParam.GetSetting("doPriceCut", false); bool doDirect = utilParam.GetSetting("doDirect", false); UtilTimer timer; double timeSetupReal = 0.0; double timeSetupCpu = 0.0; double timeSolveReal = 0.0; double timeSolveCpu = 0.0; //--- //--- start overall timer //--- timer.start(); //--- //--- create the user application (a DecompApp) //--- MCF_DecompApp mmkp(utilParam); //--- //--- create the algorithm (a DecompAlgo) //--- DecompAlgo* algo = NULL; assert(doCut + doPriceCut == 1); //--- //--- create the CPM algorithm object //--- if (doCut) { algo = new DecompAlgoC(&mmkp, utilParam); } //--- //--- create the PC algorithm object //--- if (doPriceCut) { algo = new DecompAlgoPC(&mmkp, utilParam); } if (doCut && doDirect) { timer.stop(); timeSetupCpu = timer.getCpuTime(); timeSetupReal = timer.getRealTime(); //--- //--- solve //--- timer.start(); algo->solveDirect(); timer.stop(); timeSolveCpu = timer.getCpuTime(); timeSolveReal = timer.getRealTime(); } else { //--- //--- create the driver AlpsDecomp model //--- int status = 0; AlpsDecompModel alpsModel(utilParam, algo); timer.stop(); timeSetupCpu = timer.getCpuTime(); timeSetupReal = timer.getRealTime(); //--- //--- solve //--- timer.start(); status = alpsModel.solve(); timer.stop(); timeSolveCpu = timer.getCpuTime(); timeSolveReal = timer.getRealTime(); //--- //--- sanity check //--- cout << setiosflags(ios::fixed | ios::showpoint); cout << "Status= " << status << " BestLB= " << setw(10) << UtilDblToStr(alpsModel.getGlobalLB(), 5) << " BestUB= " << setw(10) << UtilDblToStr(alpsModel.getGlobalUB(), 5) << " Nodes= " << setw(6) << alpsModel.getNumNodesProcessed() << " SetupCPU= " << timeSetupCpu << " SolveCPU= " << timeSolveCpu << " TotalCPU= " << timeSetupCpu + timeSolveCpu << " SetupReal= " << timeSetupReal << " SolveReal= " << timeSolveReal << " TotalReal= " << timeSetupReal + timeSolveReal << endl; //--- //--- free local memory //--- delete algo; } } catch (CoinError& ex) { cerr << "COIN Exception [ " << ex.message() << " ]" << " at " << ex.fileName() << ":L" << ex.lineNumber() << " in " << ex.className() << "::" << ex.methodName() << endl; return 1; } return 0; }
//===========================================================================// int main(int argc, char ** argv){ try{ //--- //--- create the utility class for parsing parameters //--- UtilParameters utilParam(argc, argv); bool doGenRandom = utilParam.GetSetting("doGenRandom", false); int randSeed = utilParam.GetSetting("randSeed", 1 ); int randNumAtms = utilParam.GetSetting("randNumAtms", 5 ); int randNumDates = utilParam.GetSetting("randNumDates", 10 ); bool doCut = utilParam.GetSetting("doCut", true); bool doPriceCut = utilParam.GetSetting("doPriceCut", false); bool doDirect = utilParam.GetSetting("doDirect", false); UtilTimer timer; double timeSetupReal = 0.0; double timeSetupCpu = 0.0; double timeSolveReal = 0.0; double timeSolveCpu = 0.0; //--- //--- start overall timer //--- timer.start(); if(doGenRandom){ //--- //--- generate a random instance //--- ATM_Instance instance; instance.generateRandom(randNumAtms, randNumDates, randSeed); } else{ //--- //--- create the user application (a DecompApp) //--- ATM_DecompApp atm(utilParam); //--- //--- create the algorithm (a DecompAlgo) //--- DecompAlgo * algo = NULL; assert(doCut + doPriceCut == 1); //--- //--- create the CPM algorithm object //--- if(doCut) algo = new DecompAlgoC(&atm, utilParam); //--- //--- create the PC algorithm object //--- if(doPriceCut) algo = new DecompAlgoPC(&atm, utilParam); if(doCut && doDirect){ timer.stop(); timeSetupCpu = timer.getCpuTime(); timeSetupReal = timer.getRealTime(); //--- //--- solve //--- timer.start(); algo->solveDirect(); timer.stop(); timeSolveCpu = timer.getCpuTime(); timeSolveReal = timer.getRealTime(); } else{ //--- //--- create the driver AlpsDecomp model //--- int status = 0; AlpsDecompModel alpsModel(utilParam, algo); timer.stop(); timeSetupCpu = timer.getCpuTime(); timeSetupReal = timer.getRealTime(); //--- //--- solve //--- timer.start(); status = alpsModel.solve(); timer.stop(); timeSolveCpu = timer.getCpuTime(); timeSolveReal = timer.getRealTime(); //TODO: move doDirect solve into alpsModel so access // solution the same way? //--- //--- sanity check //--- cout << setiosflags(ios::fixed|ios::showpoint); cout << "Status= " << status << " BestLB= " << setw(10) << UtilDblToStr(alpsModel.getGlobalLB(),2) << " BestUB= " << setw(10) << UtilDblToStr(alpsModel.getGlobalUB(),2) << " Nodes= " << setw(6) << alpsModel.getNumNodesProcessed() << " SetupCPU= " << timeSetupCpu << " SolveCPU= " << timeSolveCpu << " TotalCPU= " << timeSetupCpu + timeSolveCpu << " SetupReal= " << timeSetupReal << " SolveReal= " << timeSolveReal << " TotalReal= " << timeSetupReal + timeSolveReal << endl; //--- //--- now, initialize direct solve with best //--- solution to PC //--- TODO: only useful if stop early on time or nodes //--- TODO: cbc currently doesn't use warm-start, only cpx //--- //DecompAlgo * algoC = new DecompAlgoC(&atm, &utilParam); //algoC->solveDirect(algo->getXhatIPBest()); //delete algoC; } //--- //--- free local memory //--- delete algo; } } catch(CoinError & ex){ cerr << "COIN Exception [ " << ex.message() << " ]" << " at " << ex.fileName() << ":L" << ex.lineNumber() << " in " << ex.className() << "::" << ex.methodName() << endl; } return 0; }
//===========================================================================// void ATM_Instance::generateRandom(const int nAtms, const int nDates, const int seed){ /* Data from original: \\ordsrv3\ormp\sas\ATM_Badshah\atm_20ATMS_3\atm_doc nDates=272, nAtms=20, nPairs=4730 (max=5440) proc means data=FTPLIB.amul_atms_dates; var withdrawal allocation NET_IMPACT_AVG NET_IMPACT_STD NORMAL_AVG NORMAL_STD TS1 TS2; run; The MEANS Procedure Variable Label Std Dev Mean ................................................................ WITHDRAWAL WITHDRAWAL 1456368.37 1457077.41 ALLOCATION ALLOCATION 1752334.72 2068196.66 NET_IMPACT_AVG NET_IMPACT_AVG 0.8990607 1.1961954 NET_IMPACT_STD NET_IMPACT_STD 1.8979644 1.4240460 NORMAL_AVG NORMAL_AVG 1352731.38 1440849.71 NORMAL_STD NORMAL_STD 352658.50 364123.38 TS1 TS1 1267244.80 1371637.24 S2 TS2 1246864.33 1361954.95 ................................................................ Variable Label Minimum Maximum ................................................................ WITHDRAWAL WITHDRAWAL 8000.00 7080400.00 ALLOCATION ALLOCATION 100000.00 7020000.00 NET_IMPACT_AVG NET_IMPACT_AVG 0.0053384 18.7119586 NET_IMPACT_STD NET_IMPACT_STD 0.0046809 54.0086478 NORMAL_AVG NORMAL_AVG 38864.52 4375539.71 NORMAL_STD NORMAL_STD 26833.85 1141006.06 TS1 TS1 25245.45 5250885.71 TS2 TS2 700.0000000 4182207.14 ................................................................ for{<a,d> in ATMS_DATES_THIS} do; CA[a,d] = (normal_avg[a,d] * net_impact_avg[a,d] - ts_period_2[a,d]); CB[a,d] = (ts_period_1[a,d] - ts_period_2[a,d]); CC[a,d] = (ts_period_2[a,d] - ts_period_1[a,d]); CD[a,d] = (normal_std[a,d] * net_impact_std[a,d]); CE[a,d] = (-actual_withdrawal[a,d] + ts_period_2[a,d]); end; These numbers are annoying big and causing lots of numerical round-off issues. So, Let's scale by 1000. */ #define STDD 0 #define MEAN 1 #define MIN 2 #define MAX 3 double s_withdrawal[4] = {1456368, 1457077, 8000, 7080400}; double s_allocation[4] = {1752334, 2068196, 100000, 7020000}; double s_netimpactAve[4] = {0.8990607, 1.1961954, 0.0053384, 18.7119586}; double s_netimpactStd[4] = {1.8979644, 1.4240460, 0.0046809, 54.0086478}; double s_normalAve[4] = {13527318, 1440849, 38864, 4375539.71}; double s_normalStd[4] = {352658, 364123, 26833, 1141006}; double s_ts1[4] = {1267244, 1371637, 25245, 5250885}; double s_ts2[4] = {1246864, 1361954, 700, 4182207}; double scale = 1000; int i; for(i = 0; i < 4; i++){ s_withdrawal[i] /= scale; s_allocation[i] /= scale; s_normalAve[i] /= scale; s_normalStd[i] /= scale; s_ts1[i] /= scale; s_ts2[i] /= scale; } int nAD = nAtms * nDates; double * withdrawal = new double[nAD]; double * allocation = new double[nAD]; double * netimpactAve = new double[nAD]; double * netimpactStd = new double[nAD]; double * normalAve = new double[nAD]; double * normalStd = new double[nAD]; double * ts1 = new double[nAD]; double * ts2 = new double[nAD]; assert(withdrawal && allocation && netimpactAve && netimpactStd && normalAve && normalStd && ts1 && ts2); string fileNameAD = "atm_randAD_"; fileNameAD += UtilIntToStr(nAtms) + "_"; fileNameAD += UtilIntToStr(nDates) + "_"; fileNameAD += UtilIntToStr(seed) + ".txt"; string fileNameA = "atm_randA_"; fileNameA += UtilIntToStr(nAtms) + "_"; fileNameA += UtilIntToStr(nDates) + "_"; fileNameA += UtilIntToStr(seed) + ".txt"; string fileNameD = "atm_randD_"; fileNameD += UtilIntToStr(nAtms) + "_"; fileNameD += UtilIntToStr(nDates) + "_"; fileNameD += UtilIntToStr(seed) + ".txt"; ofstream osAD, osA, osD; UtilOpenFile(osAD, fileNameAD.c_str()); UtilOpenFile(osA, fileNameA.c_str()); UtilOpenFile(osD, fileNameD.c_str()); int a, d; srand(seed); //--- //--- generate 'raw data' in N[mean,std-dev] //--- int index = 0;//a * nDates + d for(a = 0; a < nAtms; a++){ for(d = 0; d < nDates; d++){ do{ withdrawal[index] = UtilNormRand(s_withdrawal[MEAN] , s_withdrawal[STDD]); }while( withdrawal[index] < s_withdrawal[MIN] || withdrawal[index] > s_withdrawal[MAX]); do{ allocation[index] = UtilNormRand(s_allocation[MEAN] , s_allocation[STDD]); }while( allocation[index] < s_allocation[MIN] || allocation[index] > s_allocation[MAX]); do{ netimpactAve[index] = UtilNormRand(s_netimpactAve[MEAN], s_netimpactAve[STDD]); }while( netimpactAve[index] < s_netimpactAve[MIN] || netimpactAve[index] > s_netimpactAve[MAX]); do{ netimpactStd[index] = UtilNormRand(s_netimpactStd[MEAN], s_netimpactStd[STDD]); }while( netimpactStd[index] < s_netimpactStd[MIN] || netimpactStd[index] > s_netimpactStd[MAX]); do{ normalAve[index] = UtilNormRand(s_normalAve[MEAN] , s_normalAve[STDD]); }while( normalAve[index] < s_normalAve[MIN] || normalAve[index] > s_normalAve[MAX]); do{ normalStd[index] = UtilNormRand(s_normalStd[MEAN] , s_normalStd[STDD]); }while( normalStd[index] < s_normalStd[MIN] || normalStd[index] > s_normalStd[MAX]); do{ ts1[index] = UtilNormRand(s_ts1[MEAN] , s_ts1[STDD]); }while( ts1[index] < s_ts1[MIN] || ts1[index] > s_ts1[MAX]); do{ ts2[index] = UtilNormRand(s_ts2[MEAN] , s_ts2[STDD]); }while ( ts2[index] < s_ts2[MIN] || ts2[index] > s_ts2[MAX]); index++; } } //--- //--- generate coefficients //--- //CA[a,d] = (normal_avg[a,d] * net_impact_avg[a,d] - ts_period_2[a,d]); //CB[a,d] = (ts_period_1[a,d] - ts_period_2[a,d]); //CC[a,d] = (ts_period_2[a,d] - ts_period_1[a,d]); //CD[a,d] = (normal_std[a,d] * net_impact_std[a,d]); //CE[a,d] = (-actual_withdrawal[a,d] + ts_period_2[a,d]); double * ca = new double[nAD]; double * cb = new double[nAD]; double * cc = new double[nAD]; double * cd = new double[nAD]; double * ce = new double[nAD]; assert(ca && cb && cc && cd && ce); index = 0; osAD << "a\td\tCA\tCB\tCC\tCD\tCD\tCE\tCW\n"; for(a = 0; a < nAtms; a++){ for(d = 0; d < nDates; d++){ ca[index] = normalAve[index] * netimpactAve[index] - ts2[index]; cb[index] = ts1[index] - ts2[index]; cc[index] = -cb[index]; cd[index] = normalStd[index] * netimpactStd[index]; ce[index] = -withdrawal[index] + ts2[index]; osAD << "ATM" << UtilIntToStr(a) << "\t" << "DATE" << UtilIntToStr(d) << "\t" << setw(10) << UtilDblToStr(ca[index],0) << setw(10) << UtilDblToStr(cb[index],0) << setw(10) << UtilDblToStr(cc[index],0) << setw(10) << UtilDblToStr(cd[index],0) << setw(10) << UtilDblToStr(ce[index],0) << setw(10) << UtilDblToStr(withdrawal[index],0) << "\n"; index++; } } //--- //--- generate B and K //--- //--- f(a,d) = ca*x1[a] + cb*x2[a] + cc*x1[a]*x2[a] + cd*x3[a] + ce //--- x1,x2 in {0,1}, x3 >= 0 //--- //--- sum{a} f(a,d) <= B[d], for d //--- |{d in D | f(a,d) <= 0} <= K[a], for a //--- double x01, x1, x2, x3; double * f = new double[nAD]; assert(f); index = 0; for(a = 0; a < nAtms; a++){ x01 = UtilURand(0.0,1.0); x1 = x01 >= 0.5 ? 1 : 0; x01 = UtilURand(0.0,1.0); x2 = x01 >= 0.5 ? 1 : 0; x3 = UtilURand(0.0,1.0); printf("x1=%g x2=%g x3=%g\n", x1, x2, x3); for(d = 0; d < nDates; d++){ f[index] = ca[index] * x1; f[index] += cb[index] * x2; f[index] += cc[index] * x1 * x2; f[index] += cd[index] * x3; f[index] += ce[index]; index++; } } double * B = new double[nDates]; double maxB = -1e20; for(d = 0; d < nDates; d++){ B[d] = 0; for(a = 0; a < nAtms; a++){ B[d] += f[a * nDates + d]; } if(B[d] > maxB) maxB=B[d]; } //--- //--- B=budget for cash flow //--- if negative does not make sense //--- protect against this //--- osD << "d\tB\n"; for(d = 0; d < nDates; d++){ if(B[d] < 0) B[d] = maxB / 2.0; osD << "DATE" << UtilIntToStr(d) << "\t" << setw(10) << UtilDblToStr(B[d],0) << endl; } int * K = new int[nAtms]; int maxK = 0; index = 0; for(a = 0; a < nAtms; a++){ K[a] = 0; for(d = 0; d < nDates; d++){ K[a] += f[index] <= 0 ? 1 : 0; index++; } if(K[a] > maxK) maxK=K[a]; } //--- //--- randomize it (and tighten constraint) //--- osA << "a\tK\n"; for(a = 0; a < nAtms; a++){ //K[a] -= UtilURand(1, maxK/4); osA << "ATM" << UtilIntToStr(a) << "\t" << setw(10) << K[a] << endl; } osAD.close(); osA.close(); osD.close(); UTIL_DELARR(withdrawal); UTIL_DELARR(allocation); UTIL_DELARR(netimpactAve); UTIL_DELARR(netimpactStd); UTIL_DELARR(normalAve); UTIL_DELARR(normalStd); UTIL_DELARR(ts1); UTIL_DELARR(ts2); UTIL_DELARR(ca); UTIL_DELARR(cb); UTIL_DELARR(cc); UTIL_DELARR(cd); UTIL_DELARR(ce); UTIL_DELARR(f); UTIL_DELARR(B); UTIL_DELARR(K); }