/* $Id$ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #ifdef NDEBUG #undef NDEBUG #endif #include "ClpConfig.h" #include "CoinPragma.hpp" #include #include #include #include #include #include #include #include "CoinMpsIO.hpp" #include "CoinPackedMatrix.hpp" #include "CoinPackedVector.hpp" #include "CoinStructuredModel.hpp" #include "CoinHelperFunctions.hpp" #include "CoinTime.hpp" #include "CoinFloatEqual.hpp" #if CLP_HAS_ABC #include "CoinAbcCommon.hpp" #endif #ifdef ABC_INHERIT #include "CoinAbcFactorization.hpp" #endif #include "ClpFactorization.hpp" #include "ClpSimplex.hpp" #include "ClpSimplexOther.hpp" #include "ClpSimplexNonlinear.hpp" #include "ClpInterior.hpp" #include "ClpLinearObjective.hpp" #include "ClpDualRowSteepest.hpp" #include "ClpDualRowDantzig.hpp" #include "ClpPrimalColumnSteepest.hpp" #include "ClpPrimalColumnDantzig.hpp" #include "ClpParameters.hpp" #include "ClpNetworkMatrix.hpp" #include "ClpPlusMinusOneMatrix.hpp" #include "MyMessageHandler.hpp" #include "MyEventHandler.hpp" #include "ClpPresolve.hpp" #include "Idiot.hpp" #if FACTORIZATION_STATISTICS extern double ftranTwiddleFactor1X; extern double ftranTwiddleFactor2X; extern double ftranFTTwiddleFactor1X; extern double ftranFTTwiddleFactor2X; extern double btranTwiddleFactor1X; extern double btranTwiddleFactor2X; extern double ftranFullTwiddleFactor1X; extern double ftranFullTwiddleFactor2X; extern double btranFullTwiddleFactor1X; extern double btranFullTwiddleFactor2X; extern double denseThresholdX; extern double twoThresholdX; extern double minRowsSparse; extern double largeRowsSparse; extern double mediumRowsDivider; extern double mediumRowsMinCount; extern double largeRowsCount; #endif //############################################################################# // Function Prototypes. Function definitions is in this file. static void testingMessage(const char *const msg); #if defined(CLP_HAS_AMD) || defined(CLP_HAS_CHOLMOD) || defined(CLP_HAS_GLPK) static int barrierAvailable = 1; static std::string nameBarrier = "barrier-UFL"; #elif CLP_HAS_WSMP static int barrierAvailable = 2; static std::string nameBarrier = "barrier-WSSMP"; #elif defined(CLP_HAS_MUMPS) static int barrierAvailable = 3; static std::string nameBarrier = "barrier-MUMPS"; #else static int barrierAvailable = 0; static std::string nameBarrier = "barrier-slow"; #endif #define NUMBER_ALGORITHMS 12 // If you just want a subset then set some to 1 static int switchOff[NUMBER_ALGORITHMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // shortName - 0 no , 1 yes ClpSolve setupForSolve(int algorithm, std::string &nameAlgorithm, int shortName) { ClpSolve solveOptions; /* algorithms are 0 barrier 1 dual with volumne crash 2,3 dual with and without crash 4,5 primal with and without 6,7 automatic with and without 8,9 primal with idiot 1 and 5 10,11 primal with 70, dual with volume */ switch (algorithm) { case 0: if (shortName) nameAlgorithm = "ba"; else nameAlgorithm = "nameBarrier"; solveOptions.setSolveType(ClpSolve::useBarrier); if (barrierAvailable == 1) solveOptions.setSpecialOption(4, 4); else if (barrierAvailable == 2) solveOptions.setSpecialOption(4, 2); break; case 1: #ifdef COIN_HAS_VOL if (shortName) nameAlgorithm = "du-vol-50"; else nameAlgorithm = "dual-volume-50"; solveOptions.setSolveType(ClpSolve::useDual); solveOptions.setSpecialOption(0, 2, 50); // volume #else solveOptions.setSolveType(ClpSolve::notImplemented); #endif break; case 2: if (shortName) nameAlgorithm = "du-cr"; else nameAlgorithm = "dual-crash"; solveOptions.setSolveType(ClpSolve::useDual); solveOptions.setSpecialOption(0, 1); break; case 3: if (shortName) nameAlgorithm = "du"; else nameAlgorithm = "dual"; solveOptions.setSolveType(ClpSolve::useDual); break; case 4: if (shortName) nameAlgorithm = "pr-cr"; else nameAlgorithm = "primal-crash"; solveOptions.setSolveType(ClpSolve::usePrimal); solveOptions.setSpecialOption(1, 1); break; case 5: if (shortName) nameAlgorithm = "pr"; else nameAlgorithm = "primal"; solveOptions.setSolveType(ClpSolve::usePrimal); break; case 6: if (shortName) nameAlgorithm = "au-cr"; else nameAlgorithm = "either-crash"; solveOptions.setSolveType(ClpSolve::automatic); solveOptions.setSpecialOption(1, 1); break; case 7: if (shortName) nameAlgorithm = "au"; else nameAlgorithm = "either"; solveOptions.setSolveType(ClpSolve::automatic); break; case 8: if (shortName) nameAlgorithm = "pr-id-1"; else nameAlgorithm = "primal-idiot-1"; solveOptions.setSolveType(ClpSolve::usePrimalorSprint); solveOptions.setSpecialOption(1, 2, 1); // idiot break; case 9: if (shortName) nameAlgorithm = "pr-id-5"; else nameAlgorithm = "primal-idiot-5"; solveOptions.setSolveType(ClpSolve::usePrimalorSprint); solveOptions.setSpecialOption(1, 2, 5); // idiot break; case 10: if (shortName) nameAlgorithm = "pr-id-70"; else nameAlgorithm = "primal-idiot-70"; solveOptions.setSolveType(ClpSolve::usePrimalorSprint); solveOptions.setSpecialOption(1, 2, 70); // idiot break; case 11: #ifdef COIN_HAS_VOL if (shortName) nameAlgorithm = "du-vol"; else nameAlgorithm = "dual-volume"; solveOptions.setSolveType(ClpSolve::useDual); solveOptions.setSpecialOption(0, 2, 3000); // volume #else solveOptions.setSolveType(ClpSolve::notImplemented); #endif break; default: abort(); } if (shortName) { // can switch off if (switchOff[algorithm]) solveOptions.setSolveType(ClpSolve::notImplemented); } return solveOptions; } static void printSol(ClpSimplex &model) { int numberRows = model.numberRows(); int numberColumns = model.numberColumns(); double *rowPrimal = model.primalRowSolution(); double *rowDual = model.dualRowSolution(); double *rowLower = model.rowLower(); double *rowUpper = model.rowUpper(); int iRow; double objValue = model.getObjValue(); printf("Objvalue %g Rows (%d)\n", objValue, numberRows); for (iRow = 0; iRow < numberRows; iRow++) { printf("%d primal %g dual %g low %g up %g\n", iRow, rowPrimal[iRow], rowDual[iRow], rowLower[iRow], rowUpper[iRow]); } double *columnPrimal = model.primalColumnSolution(); double *columnDual = model.dualColumnSolution(); double *columnLower = model.columnLower(); double *columnUpper = model.columnUpper(); double offset; //const double * gradient = model.objectiveAsObject()->gradient(&model, // columnPrimal,offset,true,1); const double *gradient = model.objective(columnPrimal, offset); int iColumn; objValue = -offset - model.objectiveOffset(); printf("offset %g (%g)\n", offset, model.objectiveOffset()); printf("Columns (%d)\n", numberColumns); for (iColumn = 0; iColumn < numberColumns; iColumn++) { printf("%d primal %g dual %g low %g up %g\n", iColumn, columnPrimal[iColumn], columnDual[iColumn], columnLower[iColumn], columnUpper[iColumn]); objValue += columnPrimal[iColumn] * gradient[iColumn]; if (fabs(columnPrimal[iColumn] * gradient[iColumn]) > 1.0e-8) printf("obj -> %g gradient %g\n", objValue, gradient[iColumn]); } printf("Computed objective %g\n", objValue); } void usage(const std::string &key) { std::cerr << "Undefined parameter \"" << key << "\".\n" << "Correct usage: \n" << " clp [-dirSample=V1] [-dirNetlib=V2] [-netlib]\n" << " where:\n" << " -dirSample: directory containing mps test files\n" << " Default value V1=\"../../Data/Sample\"\n" << " -dirNetlib: directory containing netlib files\"\n" << " Default value V2=\"../../Data/Netlib\"\n" << " -netlib\n" << " If specified, then netlib testset run as well as the nitTest.\n"; } #if FACTORIZATION_STATISTICS int loSizeX = -1; int hiSizeX = 1000000; #endif //---------------------------------------------------------------- #ifndef ABC_INHERIT #define AnySimplex ClpSimplex #else #include "AbcSimplex.hpp" #define AnySimplex AbcSimplex #endif int mainTest(int argc, const char *argv[], int algorithm, AnySimplex empty, ClpSolve solveOptionsIn, int switchOffValue, bool doVector) { int i; if (switchOffValue > 0) { // switch off some int iTest; for (iTest = 0; iTest < NUMBER_ALGORITHMS; iTest++) { #ifndef NDEBUG int bottom = switchOffValue % 10; assert(bottom == 0 || bottom == 1); #endif switchOffValue /= 10; switchOff[iTest] = 0; } } int numberFailures = 0; // define valid parameter keywords std::set< std::string > definedKeyWords; definedKeyWords.insert("-dirSample"); definedKeyWords.insert("-dirNetlib"); definedKeyWords.insert("-netlib"); // Create a map of parameter keys and associated data std::map< std::string, std::string > parms; for (i = 1; i < argc; i++) { std::string parm(argv[i]); std::string key, value; std::string::size_type eqPos = parm.find('='); // Does parm contain and '=' if (eqPos == std::string::npos) { //Parm does not contain '=' key = parm; } else { key = parm.substr(0, eqPos); value = parm.substr(eqPos + 1); } // Is specifed key valid? if (definedKeyWords.find(key) == definedKeyWords.end()) { // invalid key word. // Write help text usage(key); return 1; } parms[key] = value; } const char dirsep = CoinFindDirSeparator(); // Set directory containing mps data files. std::string dirSample; if (parms.find("-dirSample") != parms.end()) dirSample = parms["-dirSample"]; else dirSample = dirsep == '/' ? "../../Data/Sample/" : "..\\..\\Data\\Sample\\"; // Set directory containing netlib data files. std::string dirNetlib; if (parms.find("-dirNetlib") != parms.end()) dirNetlib = parms["-dirNetlib"]; else dirNetlib = dirsep == '/' ? "../../Data/Netlib/" : "..\\..\\Data\\Netlib\\"; #if FACTORIZATION_STATISTICS == 0 if (!empty.numberRows()) { testingMessage("Testing ClpSimplex\n"); ClpSimplexUnitTest(dirSample); } #endif if (parms.find("-netlib") != parms.end() || empty.numberRows()) { unsigned int m; std::string sizeLoHi; #if FACTORIZATION_STATISTICS double ftranTwiddleFactor1XChoice[3] = { 0.9, 1.0, 1.1 }; double ftranTwiddleFactor2XChoice[3] = { 0.9, 1.0, 1.1 }; double ftranFTTwiddleFactor1XChoice[3] = { 0.9, 1.0, 1.1 }; double ftranFTTwiddleFactor2XChoice[3] = { 0.9, 1.0, 1.1 }; double btranTwiddleFactor1XChoice[3] = { 0.9, 1.0, 1.1 }; double btranTwiddleFactor2XChoice[3] = { 0.9, 1.0, 1.1 }; double ftranFullTwiddleFactor1XChoice[3] = { 0.9, 1.0, 1.1 }; double ftranFullTwiddleFactor2XChoice[3] = { 0.9, 1.0, 1.1 }; double btranFullTwiddleFactor1XChoice[3] = { 0.9, 1.0, 1.1 }; double btranFullTwiddleFactor2XChoice[3] = { 0.9, 1.0, 1.1 }; double denseThresholdXChoice[3] = { 2, 20, 40 }; double twoThresholdXChoice[3] = { 800, 1000, 1200 }; double minRowsSparseChoice[3] = { 250, 300, 350 }; double largeRowsSparseChoice[3] = { 8000, 10000, 12000 }; double mediumRowsDividerChoice[3] = { 5, 6, 7 }; double mediumRowsMinCountChoice[3] = { 300, 500, 600 }; double largeRowsCountChoice[3] = { 700, 1000, 1300 }; double times[3 * 3 * 3 * 3 * 3]; memset(times, 0, sizeof(times)); #define whichParam(za, zname) \ const char *choice##za = #zname; \ const double *use##za = zname##Choice; \ double *external##za = &zname whichParam(A, denseThresholdX); whichParam(B, twoThresholdX); whichParam(C, minRowsSparse); whichParam(D, mediumRowsDivider); whichParam(E, mediumRowsMinCount); #endif // Define test problems: // mps names, // maximization or minimization, // Number of rows and columns in problem, and // objective function value std::vector< std::string > mpsName; std::vector< bool > min; std::vector< int > nRows; std::vector< int > nCols; std::vector< double > objValue; std::vector< double > objValueTol; // 100 added means no presolve std::vector< int > bestStrategy; if (empty.numberRows()) { std::string alg; for (int iTest = 0; iTest < NUMBER_ALGORITHMS; iTest++) { ClpSolve solveOptions = setupForSolve(iTest, alg, 0); printf("%d %s ", iTest, alg.c_str()); if (switchOff[iTest]) printf("skipped by user\n"); else if (solveOptions.getSolveType() == ClpSolve::notImplemented) printf("skipped as not available\n"); else printf("will be tested\n"); } } if (!empty.numberRows()) { mpsName.push_back("25fv47"); min.push_back(true); nRows.push_back(822); nCols.push_back(1571); objValueTol.push_back(1.e-8); objValue.push_back(5.5018458883E+03); bestStrategy.push_back(0); mpsName.push_back("80bau3b"); min.push_back(true); nRows.push_back(2263); nCols.push_back(9799); objValueTol.push_back(1.e-8); objValue.push_back(9.8722419241E+05); bestStrategy.push_back(3); mpsName.push_back("blend"); min.push_back(true); nRows.push_back(75); nCols.push_back(83); objValueTol.push_back(1.e-8); objValue.push_back(-3.0812149846e+01); bestStrategy.push_back(3); mpsName.push_back("pilotnov"); min.push_back(true); nRows.push_back(976); nCols.push_back(2172); objValueTol.push_back(1.e-8); objValue.push_back(-4.4972761882e+03); bestStrategy.push_back(3); mpsName.push_back("maros-r7"); min.push_back(true); nRows.push_back(3137); nCols.push_back(9408); objValueTol.push_back(1.e-8); objValue.push_back(1.4971851665e+06); bestStrategy.push_back(2); mpsName.push_back("pilot"); min.push_back(true); nRows.push_back(1442); nCols.push_back(3652); objValueTol.push_back(1.e-5); objValue.push_back(/*-5.5740430007e+02*/ -557.48972927292); bestStrategy.push_back(3); mpsName.push_back("pilot4"); min.push_back(true); nRows.push_back(411); nCols.push_back(1000); objValueTol.push_back(5.e-5); objValue.push_back(-2.5811392641e+03); bestStrategy.push_back(3); mpsName.push_back("pilot87"); min.push_back(true); nRows.push_back(2031); nCols.push_back(4883); objValueTol.push_back(1.e-4); objValue.push_back(3.0171072827e+02); bestStrategy.push_back(0); mpsName.push_back("adlittle"); min.push_back(true); nRows.push_back(57); nCols.push_back(97); objValueTol.push_back(1.e-8); objValue.push_back(2.2549496316e+05); bestStrategy.push_back(3); mpsName.push_back("afiro"); min.push_back(true); nRows.push_back(28); nCols.push_back(32); objValueTol.push_back(1.e-8); objValue.push_back(-4.6475314286e+02); bestStrategy.push_back(3); mpsName.push_back("agg"); min.push_back(true); nRows.push_back(489); nCols.push_back(163); objValueTol.push_back(1.e-8); objValue.push_back(-3.5991767287e+07); bestStrategy.push_back(3); mpsName.push_back("agg2"); min.push_back(true); nRows.push_back(517); nCols.push_back(302); objValueTol.push_back(1.e-8); objValue.push_back(-2.0239252356e+07); bestStrategy.push_back(3); mpsName.push_back("agg3"); min.push_back(true); nRows.push_back(517); nCols.push_back(302); objValueTol.push_back(1.e-8); objValue.push_back(1.0312115935e+07); bestStrategy.push_back(4); mpsName.push_back("bandm"); min.push_back(true); nRows.push_back(306); nCols.push_back(472); objValueTol.push_back(1.e-8); objValue.push_back(-1.5862801845e+02); bestStrategy.push_back(2); mpsName.push_back("beaconfd"); min.push_back(true); nRows.push_back(174); nCols.push_back(262); objValueTol.push_back(1.e-8); objValue.push_back(3.3592485807e+04); bestStrategy.push_back(0); mpsName.push_back("bnl1"); min.push_back(true); nRows.push_back(644); nCols.push_back(1175); objValueTol.push_back(1.e-8); objValue.push_back(1.9776295615E+03); bestStrategy.push_back(3); mpsName.push_back("bnl2"); min.push_back(true); nRows.push_back(2325); nCols.push_back(3489); objValueTol.push_back(1.e-8); objValue.push_back(1.8112365404e+03); bestStrategy.push_back(3); mpsName.push_back("boeing1"); min.push_back(true); nRows.push_back(/*351*/ 352); nCols.push_back(384); objValueTol.push_back(1.e-8); objValue.push_back(-3.3521356751e+02); bestStrategy.push_back(3); mpsName.push_back("boeing2"); min.push_back(true); nRows.push_back(167); nCols.push_back(143); objValueTol.push_back(1.e-8); objValue.push_back(-3.1501872802e+02); bestStrategy.push_back(3); mpsName.push_back("bore3d"); min.push_back(true); nRows.push_back(234); nCols.push_back(315); objValueTol.push_back(1.e-8); objValue.push_back(1.3730803942e+03); bestStrategy.push_back(3); mpsName.push_back("brandy"); min.push_back(true); nRows.push_back(221); nCols.push_back(249); objValueTol.push_back(1.e-8); objValue.push_back(1.5185098965e+03); bestStrategy.push_back(3); mpsName.push_back("capri"); min.push_back(true); nRows.push_back(272); nCols.push_back(353); objValueTol.push_back(1.e-8); objValue.push_back(2.6900129138e+03); bestStrategy.push_back(3); mpsName.push_back("cycle"); min.push_back(true); nRows.push_back(1904); nCols.push_back(2857); objValueTol.push_back(1.e-9); objValue.push_back(-5.2263930249e+00); bestStrategy.push_back(3); mpsName.push_back("czprob"); min.push_back(true); nRows.push_back(930); nCols.push_back(3523); objValueTol.push_back(1.e-8); objValue.push_back(2.1851966989e+06); bestStrategy.push_back(3); mpsName.push_back("d2q06c"); min.push_back(true); nRows.push_back(2172); nCols.push_back(5167); objValueTol.push_back(1.e-7); objValue.push_back(122784.21557456); bestStrategy.push_back(0); mpsName.push_back("d6cube"); min.push_back(true); nRows.push_back(416); nCols.push_back(6184); objValueTol.push_back(1.e-7); objValue.push_back(3.1549166667e+02); bestStrategy.push_back(3); mpsName.push_back("degen2"); min.push_back(true); nRows.push_back(445); nCols.push_back(534); objValueTol.push_back(1.e-8); objValue.push_back(-1.4351780000e+03); bestStrategy.push_back(3); mpsName.push_back("degen3"); min.push_back(true); nRows.push_back(1504); nCols.push_back(1818); objValueTol.push_back(1.e-8); objValue.push_back(-9.8729400000e+02); bestStrategy.push_back(2); mpsName.push_back("dfl001"); min.push_back(true); nRows.push_back(6072); nCols.push_back(12230); objValueTol.push_back(1.e-5); objValue.push_back(1.1266396047E+07); bestStrategy.push_back(5); mpsName.push_back("e226"); min.push_back(true); nRows.push_back(224); nCols.push_back(282); objValueTol.push_back(1.e-8); objValue.push_back(-1.8751929066e+01 + 7.113); bestStrategy.push_back(3); // The correct answer includes -7.113 term. This is a constant in the objective function. See line 1683 of the mps file. mpsName.push_back("etamacro"); min.push_back(true); nRows.push_back(401); nCols.push_back(688); objValueTol.push_back(1.e-6); objValue.push_back(-7.5571521774e+02); bestStrategy.push_back(3); mpsName.push_back("fffff800"); min.push_back(true); nRows.push_back(525); nCols.push_back(854); objValueTol.push_back(1.e-6); objValue.push_back(5.5567961165e+05); bestStrategy.push_back(3); mpsName.push_back("finnis"); min.push_back(true); nRows.push_back(498); nCols.push_back(614); objValueTol.push_back(1.e-6); objValue.push_back(1.7279096547e+05); bestStrategy.push_back(3); mpsName.push_back("fit1d"); min.push_back(true); nRows.push_back(25); nCols.push_back(1026); objValueTol.push_back(1.e-8); objValue.push_back(-9.1463780924e+03); bestStrategy.push_back(3 + 100); mpsName.push_back("fit1p"); min.push_back(true); nRows.push_back(628); nCols.push_back(1677); objValueTol.push_back(1.e-8); objValue.push_back(9.1463780924e+03); bestStrategy.push_back(5 + 100); mpsName.push_back("fit2d"); min.push_back(true); nRows.push_back(26); nCols.push_back(10500); objValueTol.push_back(1.e-8); objValue.push_back(-6.8464293294e+04); bestStrategy.push_back(3 + 100); mpsName.push_back("fit2p"); min.push_back(true); nRows.push_back(3001); nCols.push_back(13525); objValueTol.push_back(1.e-9); objValue.push_back(6.8464293232e+04); bestStrategy.push_back(5 + 100); mpsName.push_back("forplan"); min.push_back(true); nRows.push_back(162); nCols.push_back(421); objValueTol.push_back(1.e-6); objValue.push_back(-6.6421873953e+02); bestStrategy.push_back(3); mpsName.push_back("ganges"); min.push_back(true); nRows.push_back(1310); nCols.push_back(1681); objValueTol.push_back(1.e-5); objValue.push_back(-1.0958636356e+05); bestStrategy.push_back(3); mpsName.push_back("gfrd-pnc"); min.push_back(true); nRows.push_back(617); nCols.push_back(1092); objValueTol.push_back(1.e-8); objValue.push_back(6.9022359995e+06); bestStrategy.push_back(3); mpsName.push_back("greenbea"); min.push_back(true); nRows.push_back(2393); nCols.push_back(5405); objValueTol.push_back(1.e-8); objValue.push_back(/*-7.2462405908e+07*/ -72555248.129846); bestStrategy.push_back(3); mpsName.push_back("greenbeb"); min.push_back(true); nRows.push_back(2393); nCols.push_back(5405); objValueTol.push_back(1.e-8); objValue.push_back(/*-4.3021476065e+06*/ -4302260.2612066); bestStrategy.push_back(3); mpsName.push_back("grow15"); min.push_back(true); nRows.push_back(301); nCols.push_back(645); objValueTol.push_back(1.e-8); objValue.push_back(-1.0687094129e+08); bestStrategy.push_back(4 + 100); mpsName.push_back("grow22"); min.push_back(true); nRows.push_back(441); nCols.push_back(946); objValueTol.push_back(1.e-8); objValue.push_back(-1.6083433648e+08); bestStrategy.push_back(4 + 100); mpsName.push_back("grow7"); min.push_back(true); nRows.push_back(141); nCols.push_back(301); objValueTol.push_back(1.e-8); objValue.push_back(-4.7787811815e+07); bestStrategy.push_back(4 + 100); mpsName.push_back("israel"); min.push_back(true); nRows.push_back(175); nCols.push_back(142); objValueTol.push_back(1.e-8); objValue.push_back(-8.9664482186e+05); bestStrategy.push_back(2); mpsName.push_back("kb2"); min.push_back(true); nRows.push_back(44); nCols.push_back(41); objValueTol.push_back(1.e-8); objValue.push_back(-1.7499001299e+03); bestStrategy.push_back(3); mpsName.push_back("lotfi"); min.push_back(true); nRows.push_back(154); nCols.push_back(308); objValueTol.push_back(1.e-8); objValue.push_back(-2.5264706062e+01); bestStrategy.push_back(3); mpsName.push_back("maros"); min.push_back(true); nRows.push_back(847); nCols.push_back(1443); objValueTol.push_back(1.e-8); objValue.push_back(-5.8063743701e+04); bestStrategy.push_back(3); mpsName.push_back("modszk1"); min.push_back(true); nRows.push_back(688); nCols.push_back(1620); objValueTol.push_back(1.e-8); objValue.push_back(3.2061972906e+02); bestStrategy.push_back(3); mpsName.push_back("nesm"); min.push_back(true); nRows.push_back(663); nCols.push_back(2923); objValueTol.push_back(1.e-5); objValue.push_back(1.4076073035e+07); bestStrategy.push_back(2); mpsName.push_back("perold"); min.push_back(true); nRows.push_back(626); nCols.push_back(1376); objValueTol.push_back(1.e-6); objValue.push_back(-9.3807580773e+03); bestStrategy.push_back(3); //mpsName.push_back("qap12");min.push_back(true);nRows.push_back(3193);nCols.push_back(8856);objValueTol.push_back(1.e-6);objValue.push_back(5.2289435056e+02);bestStrategy.push_back(3); //mpsName.push_back("qap15");min.push_back(true);nRows.push_back(6331);nCols.push_back(22275);objValueTol.push_back(1.e-8);objValue.push_back(1.0409940410e+03);bestStrategy.push_back(3); mpsName.push_back("recipe"); min.push_back(true); nRows.push_back(92); nCols.push_back(180); objValueTol.push_back(1.e-8); objValue.push_back(-2.6661600000e+02); bestStrategy.push_back(3); mpsName.push_back("sc105"); min.push_back(true); nRows.push_back(106); nCols.push_back(103); objValueTol.push_back(1.e-8); objValue.push_back(-5.2202061212e+01); bestStrategy.push_back(3); mpsName.push_back("sc205"); min.push_back(true); nRows.push_back(206); nCols.push_back(203); objValueTol.push_back(1.e-8); objValue.push_back(-5.2202061212e+01); bestStrategy.push_back(3); mpsName.push_back("sc50a"); min.push_back(true); nRows.push_back(51); nCols.push_back(48); objValueTol.push_back(1.e-8); objValue.push_back(-6.4575077059e+01); bestStrategy.push_back(3); mpsName.push_back("sc50b"); min.push_back(true); nRows.push_back(51); nCols.push_back(48); objValueTol.push_back(1.e-8); objValue.push_back(-7.0000000000e+01); bestStrategy.push_back(3); mpsName.push_back("scagr25"); min.push_back(true); nRows.push_back(472); nCols.push_back(500); objValueTol.push_back(1.e-8); objValue.push_back(-1.4753433061e+07); bestStrategy.push_back(3); mpsName.push_back("scagr7"); min.push_back(true); nRows.push_back(130); nCols.push_back(140); objValueTol.push_back(1.e-6); objValue.push_back(-2.3313892548e+06); bestStrategy.push_back(3); mpsName.push_back("scfxm1"); min.push_back(true); nRows.push_back(331); nCols.push_back(457); objValueTol.push_back(1.e-8); objValue.push_back(1.8416759028e+04); bestStrategy.push_back(3); mpsName.push_back("scfxm2"); min.push_back(true); nRows.push_back(661); nCols.push_back(914); objValueTol.push_back(1.e-8); objValue.push_back(3.6660261565e+04); bestStrategy.push_back(3); mpsName.push_back("scfxm3"); min.push_back(true); nRows.push_back(991); nCols.push_back(1371); objValueTol.push_back(1.e-8); objValue.push_back(5.4901254550e+04); bestStrategy.push_back(3); mpsName.push_back("scorpion"); min.push_back(true); nRows.push_back(389); nCols.push_back(358); objValueTol.push_back(1.e-8); objValue.push_back(1.8781248227e+03); bestStrategy.push_back(3); mpsName.push_back("scrs8"); min.push_back(true); nRows.push_back(491); nCols.push_back(1169); objValueTol.push_back(1.e-5); objValue.push_back(9.0429998619e+02); bestStrategy.push_back(2); mpsName.push_back("scsd1"); min.push_back(true); nRows.push_back(78); nCols.push_back(760); objValueTol.push_back(1.e-8); objValue.push_back(8.6666666743e+00); bestStrategy.push_back(3 + 100); mpsName.push_back("scsd6"); min.push_back(true); nRows.push_back(148); nCols.push_back(1350); objValueTol.push_back(1.e-8); objValue.push_back(5.0500000078e+01); bestStrategy.push_back(3 + 100); mpsName.push_back("scsd8"); min.push_back(true); nRows.push_back(398); nCols.push_back(2750); objValueTol.push_back(1.e-7); objValue.push_back(9.0499999993e+02); bestStrategy.push_back(1 + 100); mpsName.push_back("sctap1"); min.push_back(true); nRows.push_back(301); nCols.push_back(480); objValueTol.push_back(1.e-8); objValue.push_back(1.4122500000e+03); bestStrategy.push_back(3); mpsName.push_back("sctap2"); min.push_back(true); nRows.push_back(1091); nCols.push_back(1880); objValueTol.push_back(1.e-8); objValue.push_back(1.7248071429e+03); bestStrategy.push_back(3); mpsName.push_back("sctap3"); min.push_back(true); nRows.push_back(1481); nCols.push_back(2480); objValueTol.push_back(1.e-8); objValue.push_back(1.4240000000e+03); bestStrategy.push_back(3); mpsName.push_back("seba"); min.push_back(true); nRows.push_back(516); nCols.push_back(1028); objValueTol.push_back(1.e-8); objValue.push_back(1.5711600000e+04); bestStrategy.push_back(3); mpsName.push_back("share1b"); min.push_back(true); nRows.push_back(118); nCols.push_back(225); objValueTol.push_back(1.e-8); objValue.push_back(-7.6589318579e+04); bestStrategy.push_back(3); mpsName.push_back("share2b"); min.push_back(true); nRows.push_back(97); nCols.push_back(79); objValueTol.push_back(1.e-8); objValue.push_back(-4.1573224074e+02); bestStrategy.push_back(3); mpsName.push_back("shell"); min.push_back(true); nRows.push_back(537); nCols.push_back(1775); objValueTol.push_back(1.e-8); objValue.push_back(1.2088253460e+09); bestStrategy.push_back(3); mpsName.push_back("ship04l"); min.push_back(true); nRows.push_back(403); nCols.push_back(2118); objValueTol.push_back(1.e-8); objValue.push_back(1.7933245380e+06); bestStrategy.push_back(3); mpsName.push_back("ship04s"); min.push_back(true); nRows.push_back(403); nCols.push_back(1458); objValueTol.push_back(1.e-8); objValue.push_back(1.7987147004e+06); bestStrategy.push_back(3); mpsName.push_back("ship08l"); min.push_back(true); nRows.push_back(779); nCols.push_back(4283); objValueTol.push_back(1.e-8); objValue.push_back(1.9090552114e+06); bestStrategy.push_back(3); mpsName.push_back("ship08s"); min.push_back(true); nRows.push_back(779); nCols.push_back(2387); objValueTol.push_back(1.e-8); objValue.push_back(1.9200982105e+06); bestStrategy.push_back(2); mpsName.push_back("ship12l"); min.push_back(true); nRows.push_back(1152); nCols.push_back(5427); objValueTol.push_back(1.e-8); objValue.push_back(1.4701879193e+06); bestStrategy.push_back(3); mpsName.push_back("ship12s"); min.push_back(true); nRows.push_back(1152); nCols.push_back(2763); objValueTol.push_back(1.e-8); objValue.push_back(1.4892361344e+06); bestStrategy.push_back(2); mpsName.push_back("sierra"); min.push_back(true); nRows.push_back(1228); nCols.push_back(2036); objValueTol.push_back(1.e-8); objValue.push_back(1.5394362184e+07); bestStrategy.push_back(3); mpsName.push_back("stair"); min.push_back(true); nRows.push_back(357); nCols.push_back(467); objValueTol.push_back(1.e-8); objValue.push_back(-2.5126695119e+02); bestStrategy.push_back(3); mpsName.push_back("standata"); min.push_back(true); nRows.push_back(360); nCols.push_back(1075); objValueTol.push_back(1.e-8); objValue.push_back(1.2576995000e+03); bestStrategy.push_back(3); //mpsName.push_back("standgub");min.push_back(true);nRows.push_back(362);nCols.push_back(1184);objValueTol.push_back(1.e-8);objValue.push_back(1257.6995); bestStrategy.push_back(3); mpsName.push_back("standmps"); min.push_back(true); nRows.push_back(468); nCols.push_back(1075); objValueTol.push_back(1.e-8); objValue.push_back(1.4060175000E+03); bestStrategy.push_back(3); mpsName.push_back("stocfor1"); min.push_back(true); nRows.push_back(118); nCols.push_back(111); objValueTol.push_back(1.e-8); objValue.push_back(-4.1131976219E+04); bestStrategy.push_back(3); mpsName.push_back("stocfor2"); min.push_back(true); nRows.push_back(2158); nCols.push_back(2031); objValueTol.push_back(1.e-8); objValue.push_back(-3.9024408538e+04); bestStrategy.push_back(3); //mpsName.push_back("stocfor3");min.push_back(true);nRows.push_back(16676);nCols.push_back(15695);objValueTol.push_back(1.e-8);objValue.push_back(-3.9976661576e+04);bestStrategy.push_back(3); //mpsName.push_back("truss");min.push_back(true);nRows.push_back(1001);nCols.push_back(8806);objValueTol.push_back(1.e-8);objValue.push_back(4.5881584719e+05);bestStrategy.push_back(3); mpsName.push_back("tuff"); min.push_back(true); nRows.push_back(334); nCols.push_back(587); objValueTol.push_back(1.e-8); objValue.push_back(2.9214776509e-01); bestStrategy.push_back(3); mpsName.push_back("vtpbase"); min.push_back(true); nRows.push_back(199); nCols.push_back(203); objValueTol.push_back(1.e-8); objValue.push_back(1.2983146246e+05); bestStrategy.push_back(3); mpsName.push_back("wood1p"); min.push_back(true); nRows.push_back(245); nCols.push_back(2594); objValueTol.push_back(5.e-5); objValue.push_back(1.4429024116e+00); bestStrategy.push_back(3); mpsName.push_back("woodw"); min.push_back(true); nRows.push_back(1099); nCols.push_back(8405); objValueTol.push_back(1.e-8); objValue.push_back(1.3044763331E+00); bestStrategy.push_back(3); } else { // Just testing one mpsName.push_back(empty.problemName()); min.push_back(true); nRows.push_back(-1); nCols.push_back(-1); objValueTol.push_back(1.e-8); objValue.push_back(0.0); bestStrategy.push_back(0); int iTest; std::string alg; for (iTest = 0; iTest < NUMBER_ALGORITHMS; iTest++) { ClpSolve solveOptions = setupForSolve(iTest, alg, 0); printf("%d %s ", iTest, alg.c_str()); if (switchOff[iTest]) printf("skipped by user\n"); else if (solveOptions.getSolveType() == ClpSolve::notImplemented) printf("skipped as not available\n"); else printf("will be tested\n"); } } double timeTaken = 0.0; if (!barrierAvailable) switchOff[0] = 1; // Loop once for each Mps File for (m = 0; m < mpsName.size(); m++) { #if FACTORIZATION_STATISTICS if (nRows[m] < loSizeX || nRows[m] >= hiSizeX) { std::cerr << " skipping mps file: " << mpsName[m] << " as " << nRows[m] << " (" << m + 1 << " out of " << mpsName.size() << ")" << std::endl; continue; } #endif std::cerr << " processing mps file: " << mpsName[m] << " (" << m + 1 << " out of " << mpsName.size() << ")" << std::endl; AnySimplex solutionBase = empty; std::string fn = dirNetlib + mpsName[m]; if (!empty.numberRows() || algorithm < 6) { // Read data mps file, CoinMpsIO mps; int nerrors = mps.readMps(fn.c_str(), "mps"); if (nerrors) { std::cerr << "Error " << nerrors << " when reading model from " << fn.c_str() << "! Aborting tests.\n"; return 1; } solutionBase.loadProblem(*mps.getMatrixByCol(), mps.getColLower(), mps.getColUpper(), mps.getObjCoefficients(), mps.getRowLower(), mps.getRowUpper()); solutionBase.setDblParam(ClpObjOffset, mps.objectiveOffset()); } // Runs through strategies if (algorithm == 6 || algorithm == 7) { // algorithms tested are at top of file double testTime[NUMBER_ALGORITHMS]; std::string alg[NUMBER_ALGORITHMS]; int iTest; for (iTest = 0; iTest < NUMBER_ALGORITHMS; iTest++) { ClpSolve solveOptions = setupForSolve(iTest, alg[iTest], 1); if (solveOptions.getSolveType() != ClpSolve::notImplemented) { double time1 = CoinCpuTime(); ClpSimplex solution = solutionBase; if (solution.maximumSeconds() < 0.0) solution.setMaximumSeconds(120.0); if (doVector) { ClpMatrixBase *matrix = solution.clpMatrix(); if (dynamic_cast< ClpPackedMatrix * >(matrix)) { ClpPackedMatrix *clpMatrix = dynamic_cast< ClpPackedMatrix * >(matrix); clpMatrix->makeSpecialColumnCopy(); } } solution.initialSolve(solveOptions); double time2 = CoinCpuTime() - time1; testTime[iTest] = time2; printf("Finished %s Took %g seconds (%d iterations) - status %d\n", mpsName[m].c_str(), time2, solution.problemStatus(), solution.numberIterations()); if (solution.problemStatus()) testTime[iTest] = 1.0e20; } else { testTime[iTest] = 1.0e30; } } int iBest = -1; double dBest = 1.0e10; printf("%s", fn.c_str()); for (iTest = 0; iTest < NUMBER_ALGORITHMS; iTest++) { if (testTime[iTest] < 1.0e30) { printf(" %s %g", alg[iTest].c_str(), testTime[iTest]); if (testTime[iTest] < dBest) { dBest = testTime[iTest]; iBest = iTest; } } } printf("\n"); if (iBest >= 0) printf("Best strategy for %s is %s (%d) which takes %g seconds\n", fn.c_str(), alg[iBest].c_str(), iBest, testTime[iBest]); else printf("No strategy finished in time limit\n"); continue; } double time1 = CoinCpuTime(); AnySimplex solution = solutionBase; #if 0 solution.setOptimizationDirection(-1); { int j; double * obj = solution.objective(); int n = solution.numberColumns(); for (j = 0; j < n; j++) obj[j] *= -1.0; } #endif ClpSolve::SolveType method; ClpSolve solveOptions = solveOptionsIn; std::string nameAlgorithm; if (algorithm != 5) { if (algorithm == 0) { method = ClpSolve::useDual; nameAlgorithm = "dual"; } else if (algorithm == 1) { method = ClpSolve::usePrimalorSprint; nameAlgorithm = "primal"; } else if (algorithm == 3) { method = ClpSolve::automatic; nameAlgorithm = "either"; } else { nameAlgorithm = "barrier-slow"; #if defined(CLP_HAS_AMD) || defined(CLP_HAS_CHOLMOD) || defined(CLP_HAS_GLPK) solveOptions.setSpecialOption(4, 4); nameAlgorithm = "barrier-UFL"; #endif #ifdef CLP_HAS_WSMP solveOptions.setSpecialOption(4, 2); nameAlgorithm = "barrier-WSSMP"; #endif #ifdef CLP_HAS_MUMPS solveOptions.setSpecialOption(4, 6); nameAlgorithm = "barrier-MUMPS"; #endif method = ClpSolve::useBarrier; } solveOptions.setSolveType(method); } else { int iAlg = bestStrategy[m]; int presolveOff = iAlg / 100; iAlg = iAlg % 100; if (!barrierAvailable && iAlg == 0) { if (nRows[m] != 2172) iAlg = 5; // try primal else iAlg = 3; // d2q06c } solveOptions = setupForSolve(iAlg, nameAlgorithm, 0); if (presolveOff) solveOptions.setPresolveType(ClpSolve::presolveOff); } if (doVector) { ClpMatrixBase *matrix = solution.clpMatrix(); if (dynamic_cast< ClpPackedMatrix * >(matrix)) { ClpPackedMatrix *clpMatrix = dynamic_cast< ClpPackedMatrix * >(matrix); clpMatrix->makeSpecialColumnCopy(); } } #if FACTORIZATION_STATISTICS double timesOne[3 * 3 * 3 * 3 * 3]; memset(timesOne, 0, sizeof(timesOne)); int iterationsOne[3 * 3 * 3 * 3 * 3]; memset(iterationsOne, 0, sizeof(iterationsOne)); AnySimplex saveModel(solution); double time2; #if 0 solution.initialSolve(solveOptions); time2 = CoinCpuTime() - time1; timeTaken += time2; printf("%s took %g seconds using algorithm %s\n", fn.c_str(), time2, nameAlgorithm.c_str()); #endif #define loA 1 #define loB 0 #define loC 0 #define loD 1 #define loE 1 #define hiA 2 #define hiB 1 #define hiC 1 #define hiD 2 #define hiE 2 time2 = CoinCpuTime(); for (int iA = loA; iA < hiA; iA++) { *externalA = useA[iA]; for (int iB = loB; iB < hiB; iB++) { *externalB = useB[iB]; for (int iC = loC; iC < hiC; iC++) { *externalC = useC[iC]; for (int iD = loD; iD < hiD; iD++) { *externalD = useD[iD]; for (int iE = loE; iE < hiE; iE++) { *externalE = useE[iE]; solution = saveModel; solution.initialSolve(solveOptions); double time3 = CoinCpuTime(); printf("Finished %s Took %g seconds (%d iterations) - status %d\n", mpsName[m].c_str(), time3 - time2, solution.numberIterations(), solution.problemStatus()); iterationsOne[iA + 3 * iB + 9 * iC + 27 * iD + 81 * iE] = solution.numberIterations(); timesOne[iA + 3 * iB + 9 * iC + 27 * iD + 81 * iE] = time3 - time2; times[iA + 3 * iB + 9 * iC + 27 * iD + 81 * iE] += time3 - time2; time2 = time3; } } } } } double bestTime = 1.0e100; int iBestTime = -1; double bestTimePer = 1.0e100; int iBestTimePer = -1; int bestIterations = 1000000; int iBestIterations = -1; printf("TTimes "); for (int i = 0; i < 3 * 3 * 3 * 3 * 3; i++) { // skip if not done if (!iterationsOne[i]) continue; double average = timesOne[i] / static_cast< double >(iterationsOne[i]); if (timesOne[i] < bestTime) { bestTime = timesOne[i]; iBestTime = i; } if (average < bestTimePer) { bestTimePer = average; iBestTimePer = i; } if (iterationsOne[i] < bestIterations) { bestIterations = iterationsOne[i]; iBestIterations = i; } printf("%.2f ", timesOne[i]); } printf("\n"); int iA, iB, iC, iD, iE; iA = iBestTime; iE = iA / 81; iA -= 81 * iE; iD = iA / 27; iA -= 27 * iD; iC = iA / 9; iA -= 9 * iC; iB = iA / 3; iA -= 3 * iB; printf("Best time %.2f %s=%g %s=%g %s=%g %s=%g %s=%g\n", bestTime, choiceA, useA[iA], choiceB, useB[iB], choiceC, useC[iC], choiceD, useD[iD], choiceE, useE[iE]); iA = iBestTimePer; iE = iA / 81; iA -= 81 * iE; iD = iA / 27; iA -= 27 * iD; iC = iA / 9; iA -= 9 * iC; iB = iA / 3; iA -= 3 * iB; printf("Best time per iteration %g %s=%g %s=%g %s=%g %s=%g %s=%g\n", bestTimePer, choiceA, useA[iA], choiceB, useB[iB], choiceC, useC[iC], choiceD, useD[iD], choiceE, useE[iE]); iA = iBestIterations; iE = iA / 81; iA -= 81 * iE; iD = iA / 27; iA -= 27 * iD; iC = iA / 9; iA -= 9 * iC; iB = iA / 3; iA -= 3 * iB; printf("Best iterations %d %s=%g %s=%g %s=%g %s=%g %s=%g\n", bestIterations, choiceA, useA[iA], choiceB, useB[iB], choiceC, useC[iC], choiceD, useD[iD], choiceE, useE[iE]); #else solution.initialSolve(solveOptions); double time2 = CoinCpuTime() - time1; timeTaken += time2; printf("%s took %g seconds using algorithm %s\n", fn.c_str(), time2, nameAlgorithm.c_str()); #endif // Test objective solution value { if (!solution.isProvenOptimal()) { std::cerr << "** NOT OPTIMAL "; numberFailures++; } double soln = solution.objectiveValue(); CoinRelFltEq eq(objValueTol[m]); std::cerr << soln << ", " << objValue[m] << " diff " << soln - objValue[m] << std::endl; if (!eq(soln, objValue[m])) { printf("** difference fails\n"); numberFailures++; } } } printf("Total time %g seconds\n", timeTaken); #if FACTORIZATION_STATISTICS double bestTime = 1.0e100; int iBestTime = -1; for (int i = 0; i < 3 * 3 * 3 * 3 * 3; i++) { if (times[i] && times[i] < bestTime) { bestTime = times[i]; iBestTime = i; } } for (int iA = 0; iA < hiA; iA++) { for (int iB = 0; iB < hiB; iB++) { for (int iC = 0; iC < hiC; iC++) { for (int iD = loD; iD < hiD; iD++) { for (int iE = loE; iE < hiE; iE++) { int k = iA + 3 * iB + 9 * iC + 27 * iD + 81 * iE; double thisTime = times[k]; if (thisTime) { if (k == iBestTime) printf("** "); printf("%s=%g %s=%g %s=%g %s=%g %s=%g - time %.2f\n", choiceA, useA[iA], choiceB, useB[iB], choiceC, useC[iC], choiceD, useD[iD], choiceE, useE[iE], thisTime); } } } } } } //exit(0); #endif } else { testingMessage("***Skipped Testing on netlib ***\n"); testingMessage("***use -netlib to test class***\n"); } if (!numberFailures) testingMessage("All tests completed successfully\n"); else testingMessage("Some tests failed\n"); return 0; } // Display message on stdout and stderr static void testingMessage(const char *const msg) { std::cerr << msg; //cout <setDetailMessage(1, 102); model.setFactorizationFrequency(10); model.primal(); model.primal(0, 3); model.setObjCoeff(3, -2.9473684210526314); model.primal(0, 3); // Write saved solutions int nc = model.getNumCols(); size_t s; std::deque< StdVectorDouble > fep = messageHandler.getFeasibleExtremePoints(); size_t numSavedSolutions = fep.size(); for (s = 0; s < numSavedSolutions; ++s) { const StdVectorDouble &solnVec = fep[s]; for (int c = 0; c < nc; ++c) { if (fabs(solnVec[c]) > 1.0e-8) std::cout << "Saved Solution: " << s << " ColNum: " << c << " Value: " << solnVec[c] << std::endl; } } // Solve again without scaling // and maximize then minimize messageHandler.clearFeasibleExtremePoints(); model.scaling(0); model.setOptimizationDirection(-1); model.primal(); model.setOptimizationDirection(1); model.primal(); fep = messageHandler.getFeasibleExtremePoints(); numSavedSolutions = fep.size(); for (s = 0; s < numSavedSolutions; ++s) { const StdVectorDouble &solnVec = fep[s]; for (int c = 0; c < nc; ++c) { if (fabs(solnVec[c]) > 1.0e-8) std::cout << "Saved Solution: " << s << " ColNum: " << c << " Value: " << solnVec[c] << std::endl; } } } else { std::cerr << "Error reading exmip1 from sample data. Skipping test." << std::endl; } } #endif // Test dual ranging { CoinMpsIO m; std::string fn = dirSample + "exmip1"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex model; model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); model.primal(); int which[13] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; double costIncrease[13]; int sequenceIncrease[13]; double costDecrease[13]; int sequenceDecrease[13]; // ranging model.dualRanging(13, which, costIncrease, sequenceIncrease, costDecrease, sequenceDecrease); int i; for (i = 0; i < 13; i++) printf("%d increase %g %d, decrease %g %d\n", i, costIncrease[i], sequenceIncrease[i], costDecrease[i], sequenceDecrease[i]); assert(fabs(costDecrease[3]) < 1.0e-4); assert(fabs(costIncrease[7] - 1.0) < 1.0e-4); model.setOptimizationDirection(-1); { int j; double *obj = model.objective(); int n = model.numberColumns(); for (j = 0; j < n; j++) obj[j] *= -1.0; } double costIncrease2[13]; int sequenceIncrease2[13]; double costDecrease2[13]; int sequenceDecrease2[13]; // ranging model.dualRanging(13, which, costIncrease2, sequenceIncrease2, costDecrease2, sequenceDecrease2); for (i = 0; i < 13; i++) { assert(fabs(costIncrease[i] - costDecrease2[i]) < 1.0e-6); assert(fabs(costDecrease[i] - costIncrease2[i]) < 1.0e-6); assert(sequenceIncrease[i] == sequenceDecrease2[i]); assert(sequenceDecrease[i] == sequenceIncrease2[i]); } // Now delete all rows and see what happens model.deleteRows(model.numberRows(), which); model.primal(); // ranging if (!model.dualRanging(8, which, costIncrease, sequenceIncrease, costDecrease, sequenceDecrease)) { for (i = 0; i < 8; i++) { printf("%d increase %g %d, decrease %g %d\n", i, costIncrease[i], sequenceIncrease[i], costDecrease[i], sequenceDecrease[i]); } } } else { std::cerr << "Error reading exmip1 from sample data. Skipping test." << std::endl; } } // Test primal ranging { CoinMpsIO m; std::string fn = dirSample + "exmip1"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex model; model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); model.primal(); int which[13] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; double valueIncrease[13]; int sequenceIncrease[13]; double valueDecrease[13]; int sequenceDecrease[13]; // ranging model.primalRanging(13, which, valueIncrease, sequenceIncrease, valueDecrease, sequenceDecrease); int i; for (i = 0; i < 13; i++) printf("%d increase %g %d, decrease %g %d\n", i, valueIncrease[i], sequenceIncrease[i], valueDecrease[i], sequenceDecrease[i]); assert(fabs(valueIncrease[3] - 0.642857) < 1.0e-4); assert(fabs(valueIncrease[8] - 2.95113) < 1.0e-4); } else { std::cerr << "Error reading exmip1 from sample data. Skipping test." << std::endl; } #if 0 // out until I find optimization bug // Test parametrics ClpSimplexOther * model2 = (ClpSimplexOther *) (&model); double rhs[] = { 1.0, 2.0, 3.0, 4.0, 5.0}; double endingTheta = 1.0; model2->scaling(0); model2->setLogLevel(63); model2->parametrics(0.0, endingTheta, 0.1, NULL, NULL, rhs, rhs, NULL); #endif } // Test binv etc { /* Wolsey : Page 130 max 4x1 - x2 7x1 - 2x2 <= 14 x2 <= 3 2x1 - 2x2 <= 3 x1 in Z+, x2 >= 0 note slacks are -1 in Clp so signs may be different */ int n_cols = 2; int n_rows = 3; double obj[2] = { -4.0, 1.0 }; double collb[2] = { 0.0, 0.0 }; double colub[2] = { COIN_DBL_MAX, COIN_DBL_MAX }; double rowlb[3] = { -COIN_DBL_MAX, -COIN_DBL_MAX, -COIN_DBL_MAX }; double rowub[3] = { 14.0, 3.0, 3.0 }; int rowIndices[5] = { 0, 2, 0, 1, 2 }; int colIndices[5] = { 0, 0, 1, 1, 1 }; double elements[5] = { 7.0, 2.0, -2.0, 1.0, -2.0 }; CoinPackedMatrix M(true, rowIndices, colIndices, elements, 5); ClpSimplex model; model.loadProblem(M, collb, colub, obj, rowlb, rowub); model.dual(0, 1); // keep factorization //check that the tableau matches wolsey (B-1 A) // slacks in second part of binvA double *binvA = reinterpret_cast< double * >(malloc((n_cols + n_rows) * sizeof(double))); printf("B-1 A by row\n"); int i; for (i = 0; i < n_rows; i++) { model.getBInvARow(i, binvA, binvA + n_cols); printf("row: %d -> ", i); for (int j = 0; j < n_cols + n_rows; j++) { printf("%g, ", binvA[j]); } printf("\n"); } // See if can re-use factorization AND arrays model.primal(0, 3 + 4); // keep factorization // And do by column printf("B-1 A by column\n"); for (i = 0; i < n_rows + n_cols; i++) { model.getBInvACol(i, binvA); printf("column: %d -> ", i); for (int j = 0; j < n_rows; j++) { printf("%g, ", binvA[j]); } printf("\n"); } /* Do twice - without and with scaling */ // set scaling off model.scaling(0); for (int iPass = 0; iPass < 2; iPass++) { model.primal(0, 3 + 4); // keep factorization const double *rowScale = model.rowScale(); const double *columnScale = model.columnScale(); if (!iPass) assert(!rowScale); else assert(rowScale); // only true for this example /* has to be exactly correct as in OsiClpsolverInterface.cpp (also redo each pass as may change */ printf("B-1 A"); for (i = 0; i < n_rows; i++) { model.getBInvARow(i, binvA, binvA + n_cols); printf("\nrow: %d -> ", i); int j; // First columns for (j = 0; j < n_cols; j++) { if (binvA[j]) { printf("(%d %g), ", j, binvA[j]); } } // now rows for (j = 0; j < n_rows; j++) { if (binvA[j + n_cols]) { printf("(%d %g), ", j + n_cols, binvA[j + n_cols]); } } } printf("\n"); printf("And by column (trickier)"); const int *pivotVariable = model.pivotVariable(); for (i = 0; i < n_cols + n_rows; i++) { model.getBInvACol(i, binvA); printf("\ncolumn: %d -> ", i); for (int j = 0; j < n_rows; j++) { if (binvA[j]) { // need to know pivot variable for +1/-1 (slack) and row/column scaling int pivot = pivotVariable[j]; if (pivot < n_cols) { // scaled coding is in just in case if (!columnScale) { printf("(%d %g), ", j, binvA[j]); } else { printf("(%d %g), ", j, binvA[j] * columnScale[pivot]); } } else { if (!rowScale) { printf("(%d %g), ", j, binvA[j]); } else { printf("(%d %g), ", j, binvA[j] / rowScale[pivot - n_cols]); } } } } } printf("\n"); printf("binvrow"); for (i = 0; i < n_rows; i++) { model.getBInvRow(i, binvA); printf("\nrow: %d -> ", i); int j; for (j = 0; j < n_rows; j++) { if (binvA[j]) printf("(%d %g), ", j, binvA[j]); } } printf("\n"); printf("And by column "); for (i = 0; i < n_rows; i++) { model.getBInvCol(i, binvA); printf("\ncol: %d -> ", i); int j; for (j = 0; j < n_rows; j++) { if (binvA[j]) printf("(%d %g), ", j, binvA[j]); } } printf("\n"); // now deal with next pass if (!iPass) { // get scaling for testing model.scaling(1); } } free(binvA); model.setColUpper(1, 2.0); model.dual(0, 2 + 4); // use factorization and arrays model.dual(0, 2); // hopefully will not use factorization model.primal(0, 3 + 4); // keep factorization // but say basis has changed model.setWhatsChanged(model.whatsChanged() & (~512)); model.dual(0, 2); // hopefully will not use factorization } // test steepest edge { CoinMpsIO m; std::string fn = dirSample + "finnis"; int returnCode = m.readMps(fn.c_str(), "mps"); if (returnCode) { // probable cause is that gz not there fprintf(stderr, "Unable to open finnis.mps in %s\n", dirSample.c_str()); fprintf(stderr, "Most probable cause is that sample data is not available, or finnis.mps is gzipped i.e. finnis.mps.gz and libz has not been activated\n"); fprintf(stderr, "Either gunzip files or edit Makefiles/Makefile.location to get libz\n"); } else { ClpModel model; model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); ClpSimplex solution(model); solution.scaling(1); solution.setDualBound(1.0e8); //solution.factorization()->maximumPivots(1); //solution.setLogLevel(3); solution.setDualTolerance(1.0e-7); // set objective sense, ClpDualRowSteepest steep; solution.setDualRowPivotAlgorithm(steep); solution.setDblParam(ClpObjOffset, m.objectiveOffset()); solution.dual(); } } // test normal solution { CoinMpsIO m; std::string fn = dirSample + "afiro"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex solution; ClpModel model; // do twice - without and with scaling int iPass; for (iPass = 0; iPass < 2; iPass++) { // explicit row objective for testing int nr = m.getNumRows(); double *rowObj = new double[nr]; CoinFillN(rowObj, nr, 0.0); model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper(), rowObj); delete[] rowObj; solution = ClpSimplex(model); if (iPass) { solution.scaling(); } solution.dual(); solution.dual(); // test optimal assert(solution.status() == 0); int numberColumns = solution.numberColumns(); int numberRows = solution.numberRows(); CoinPackedVector colsol(numberColumns, solution.primalColumnSolution()); double *objective = solution.objective(); #ifndef NDEBUG double objValue = colsol.dotProduct(objective); #endif CoinRelFltEq eq(1.0e-8); assert(eq(objValue, -4.6475314286e+02)); solution.dual(); assert(eq(solution.objectiveValue(), -4.6475314286e+02)); double *lower = solution.columnLower(); double *upper = solution.columnUpper(); double *sol = solution.primalColumnSolution(); double *result = new double[numberColumns]; CoinFillN(result, numberColumns, 0.0); solution.matrix()->transposeTimes(solution.dualRowSolution(), result); int iRow, iColumn; // see if feasible and dual feasible for (iColumn = 0; iColumn < numberColumns; iColumn++) { double value = sol[iColumn]; assert(value < upper[iColumn] + 1.0e-8); assert(value > lower[iColumn] - 1.0e-8); value = objective[iColumn] - result[iColumn]; assert(value > -1.0e-5); if (sol[iColumn] > 1.0e-5) assert(value < 1.0e-5); } delete[] result; result = new double[numberRows]; CoinFillN(result, numberRows, 0.0); solution.matrix()->times(colsol, result); lower = solution.rowLower(); upper = solution.rowUpper(); sol = solution.primalRowSolution(); #ifndef NDEBUG for (iRow = 0; iRow < numberRows; iRow++) { double value = result[iRow]; assert(eq(value, sol[iRow])); assert(value < upper[iRow] + 1.0e-8); assert(value > lower[iRow] - 1.0e-8); } #endif delete[] result; // test row objective double *rowObjective = solution.rowObjective(); CoinDisjointCopyN(solution.dualRowSolution(), numberRows, rowObjective); CoinDisjointCopyN(solution.dualColumnSolution(), numberColumns, objective); // this sets up all slack basis solution.createStatus(); solution.dual(); CoinFillN(rowObjective, numberRows, 0.0); CoinDisjointCopyN(m.getObjCoefficients(), numberColumns, objective); solution.dual(); } } else { std::cerr << "Error reading afiro from sample data. Skipping test." << std::endl; } } // test unbounded { CoinMpsIO m; std::string fn = dirSample + "brandy"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex solution; // do twice - without and with scaling int iPass; for (iPass = 0; iPass < 2; iPass++) { solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); if (iPass) solution.scaling(); solution.setOptimizationDirection(-1); // test unbounded and ray #ifdef DUAL solution.setDualBound(100.0); solution.dual(); #else solution.primal(); #endif assert(solution.status() == 2); int numberColumns = solution.numberColumns(); int numberRows = solution.numberRows(); double *lower = solution.columnLower(); double *upper = solution.columnUpper(); double *sol = solution.primalColumnSolution(); double *ray = solution.unboundedRay(); double *objective = solution.objective(); double objChange = 0.0; int iRow, iColumn; // make sure feasible and columns form ray for (iColumn = 0; iColumn < numberColumns; iColumn++) { double value = sol[iColumn]; assert(value < upper[iColumn] + 1.0e-8); assert(value > lower[iColumn] - 1.0e-8); value = ray[iColumn]; if (value > 0.0) assert(upper[iColumn] > 1.0e30); else if (value < 0.0) assert(lower[iColumn] < -1.0e30); objChange += value * objective[iColumn]; } // make sure increasing objective assert(objChange > 0.0); double *result = new double[numberRows]; CoinFillN(result, numberRows, 0.0); solution.matrix()->times(sol, result); lower = solution.rowLower(); upper = solution.rowUpper(); sol = solution.primalRowSolution(); #ifndef NDEBUG for (iRow = 0; iRow < numberRows; iRow++) { double value = result[iRow]; assert(eq(value, sol[iRow])); assert(value < upper[iRow] + 2.0e-8); assert(value > lower[iRow] - 2.0e-8); } #endif CoinFillN(result, numberRows, 0.0); solution.matrix()->times(ray, result); // there may be small differences (especially if scaled) for (iRow = 0; iRow < numberRows; iRow++) { double value = result[iRow]; if (value > 1.0e-8) assert(upper[iRow] > 1.0e30); else if (value < -1.0e-8) assert(lower[iRow] < -1.0e30); } delete[] result; delete[] ray; } } else { std::cerr << "Error reading brandy from sample data. Skipping test." << std::endl; } } // test infeasible { CoinMpsIO m; std::string fn = dirSample + "brandy"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex solution; // do twice - without and with scaling int iPass; for (iPass = 0; iPass < 2; iPass++) { solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); if (iPass) solution.scaling(); // test infeasible and ray solution.columnUpper()[0] = 0.0; #if 1 //def DUAL solution.setDualBound(100.0); solution.dual(); #else solution.primal(); #endif assert(solution.status() == 1); int numberColumns = solution.numberColumns(); int numberRows = solution.numberRows(); double *lower = solution.rowLower(); double *upper = solution.rowUpper(); double *ray = solution.infeasibilityRay(); assert(ray); // construct proof of infeasibility int iRow, iColumn; double lo = 0.0, up = 0.0; int nl = 0, nu = 0; for (iRow = 0; iRow < numberRows; iRow++) { if (lower[iRow] > -1.0e20) { lo += ray[iRow] * lower[iRow]; } else { if (ray[iRow] > 1.0e-8) nl++; } if (upper[iRow] < 1.0e20) { up += ray[iRow] * upper[iRow]; } else { if (ray[iRow] > 1.0e-8) nu++; } } if (nl) lo = -1.0e100; if (nu) up = 1.0e100; double *result = new double[numberColumns]; double lo2 = 0.0, up2 = 0.0; CoinFillN(result, numberColumns, 0.0); solution.matrix()->transposeTimes(ray, result); lower = solution.columnLower(); upper = solution.columnUpper(); nl = nu = 0; for (iColumn = 0; iColumn < numberColumns; iColumn++) { if (result[iColumn] > 1.0e-8) { if (lower[iColumn] > -1.0e20) lo2 += result[iColumn] * lower[iColumn]; else nl++; if (upper[iColumn] < 1.0e20) up2 += result[iColumn] * upper[iColumn]; else nu++; } else if (result[iColumn] < -1.0e-8) { if (lower[iColumn] > -1.0e20) up2 += result[iColumn] * lower[iColumn]; else nu++; if (upper[iColumn] < 1.0e20) lo2 += result[iColumn] * upper[iColumn]; else nl++; } } if (nl) lo2 = -1.0e100; if (nu) up2 = 1.0e100; // make sure inconsistency assert(lo2 > up || up2 < lo); delete[] result; delete[] ray; } } else { std::cerr << "Error reading brandy from sample data. Skipping test." << std::endl; } } // test delete and add { CoinMpsIO m; std::string fn = dirSample + "brandy"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex solution; solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); solution.dual(); CoinRelFltEq eq(1.0e-8); assert(eq(solution.objectiveValue(), 1.5185098965e+03)); int numberColumns = solution.numberColumns(); int numberRows = solution.numberRows(); double *saveObj = new double[numberColumns]; double *saveLower = new double[numberRows + numberColumns]; double *saveUpper = new double[numberRows + numberColumns]; int *which = new int[numberRows + numberColumns]; CoinBigIndex numberElements = m.getMatrixByCol()->getNumElements(); CoinBigIndex *starts = new CoinBigIndex[numberRows + numberColumns]; int *index = new int[numberElements]; double *element = new double[numberElements]; const CoinBigIndex *startM; const int *lengthM; const int *indexM; const double *elementM; int n, nel; // delete non basic columns n = 0; nel = 0; int iRow, iColumn; const double *lower = m.getColLower(); const double *upper = m.getColUpper(); const double *objective = m.getObjCoefficients(); startM = m.getMatrixByCol()->getVectorStarts(); lengthM = m.getMatrixByCol()->getVectorLengths(); indexM = m.getMatrixByCol()->getIndices(); elementM = m.getMatrixByCol()->getElements(); starts[0] = 0; for (iColumn = 0; iColumn < numberColumns; iColumn++) { if (solution.getColumnStatus(iColumn) != ClpSimplex::basic) { saveObj[n] = objective[iColumn]; saveLower[n] = lower[iColumn]; saveUpper[n] = upper[iColumn]; CoinBigIndex j; for (j = startM[iColumn]; j < startM[iColumn] + lengthM[iColumn]; j++) { index[nel] = indexM[j]; element[nel++] = elementM[j]; } which[n++] = iColumn; starts[n] = nel; } } solution.deleteColumns(n, which); solution.dual(); // Put back solution.addColumns(n, saveLower, saveUpper, saveObj, starts, index, element); solution.dual(); assert(eq(solution.objectiveValue(), 1.5185098965e+03)); // Delete all columns and add back n = 0; nel = 0; starts[0] = 0; lower = m.getColLower(); upper = m.getColUpper(); objective = m.getObjCoefficients(); for (iColumn = 0; iColumn < numberColumns; iColumn++) { saveObj[n] = objective[iColumn]; saveLower[n] = lower[iColumn]; saveUpper[n] = upper[iColumn]; CoinBigIndex j; for (j = startM[iColumn]; j < startM[iColumn] + lengthM[iColumn]; j++) { index[nel] = indexM[j]; element[nel++] = elementM[j]; } which[n++] = iColumn; starts[n] = nel; } solution.deleteColumns(n, which); solution.dual(); // Put back solution.addColumns(n, saveLower, saveUpper, saveObj, starts, index, element); solution.dual(); assert(eq(solution.objectiveValue(), 1.5185098965e+03)); // reload with original solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); // delete half rows n = 0; nel = 0; lower = m.getRowLower(); upper = m.getRowUpper(); startM = m.getMatrixByRow()->getVectorStarts(); lengthM = m.getMatrixByRow()->getVectorLengths(); indexM = m.getMatrixByRow()->getIndices(); elementM = m.getMatrixByRow()->getElements(); starts[0] = 0; for (iRow = 0; iRow < numberRows; iRow++) { if ((iRow & 1) == 0) { saveLower[n] = lower[iRow]; saveUpper[n] = upper[iRow]; CoinBigIndex j; for (j = startM[iRow]; j < startM[iRow] + lengthM[iRow]; j++) { index[nel] = indexM[j]; element[nel++] = elementM[j]; } which[n++] = iRow; starts[n] = nel; } } solution.deleteRows(n, which); solution.dual(); // Put back solution.addRows(n, saveLower, saveUpper, starts, index, element); solution.dual(); assert(eq(solution.objectiveValue(), 1.5185098965e+03)); solution.writeMps("yy.mps"); // Delete all rows n = 0; nel = 0; lower = m.getRowLower(); upper = m.getRowUpper(); starts[0] = 0; for (iRow = 0; iRow < numberRows; iRow++) { saveLower[n] = lower[iRow]; saveUpper[n] = upper[iRow]; CoinBigIndex j; for (j = startM[iRow]; j < startM[iRow] + lengthM[iRow]; j++) { index[nel] = indexM[j]; element[nel++] = elementM[j]; } which[n++] = iRow; starts[n] = nel; } solution.deleteRows(n, which); solution.dual(); // Put back solution.addRows(n, saveLower, saveUpper, starts, index, element); solution.dual(); solution.writeMps("xx.mps"); assert(eq(solution.objectiveValue(), 1.5185098965e+03)); // Zero out status array to give some interest memset(solution.statusArray() + numberColumns, 0, numberRows); solution.primal(1); assert(eq(solution.objectiveValue(), 1.5185098965e+03)); // Delete all columns and rows n = 0; for (iColumn = 0; iColumn < numberColumns; iColumn++) { which[n++] = iColumn; starts[n] = nel; } solution.deleteColumns(n, which); n = 0; for (iRow = 0; iRow < numberRows; iRow++) { which[n++] = iRow; starts[n] = nel; } solution.deleteRows(n, which); delete[] saveObj; delete[] saveLower; delete[] saveUpper; delete[] which; delete[] starts; delete[] index; delete[] element; } else { std::cerr << "Error reading brandy from sample data. Skipping test." << std::endl; } } #if 1 // Test barrier { CoinMpsIO m; std::string fn = dirSample + "exmip1"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpInterior solution; solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); solution.primalDual(); } else { std::cerr << "Error reading exmip1 from sample data. Skipping test." << std::endl; } } #endif #if COINUTILS_BIGINDEX_IS_INT // test network #define QUADRATIC if (1) { std::string fn = dirSample + "input.130"; int numberColumns; int numberRows; FILE *fp = fopen(fn.c_str(), "r"); if (!fp) { // Try in Data/Sample fn = "Data/Sample/input.130"; fp = fopen(fn.c_str(), "r"); } if (!fp) { fprintf(stderr, "Unable to open file input.130 in dirSample or Data/Sample directory\n"); } else { int problem; char temp[100]; // read and skip int x = fscanf(fp, "%s", temp); if (x < 0) throw("bad fscanf"); assert(!strcmp(temp, "BEGIN")); x = fscanf(fp, "%*s %*s %d %d %*s %*s %d %*s", &problem, &numberRows, &numberColumns); if (x < 0) throw("bad fscanf"); // scan down to SUPPLY while (fgets(temp, 100, fp)) { if (!strncmp(temp, "SUPPLY", 6)) break; } if (strncmp(temp, "SUPPLY", 6)) { fprintf(stderr, "Unable to find SUPPLY\n"); exit(2); } // get space for rhs double *lower = new double[numberRows]; double *upper = new double[numberRows]; int i; for (i = 0; i < numberRows; i++) { lower[i] = 0.0; upper[i] = 0.0; } // ***** Remember to convert to C notation while (fgets(temp, 100, fp)) { int row; int value; if (!strncmp(temp, "ARCS", 4)) break; sscanf(temp, "%d %d", &row, &value); upper[row - 1] = -value; lower[row - 1] = -value; } if (strncmp(temp, "ARCS", 4)) { fprintf(stderr, "Unable to find ARCS\n"); exit(2); } // number of columns may be underestimate int *head = new int[2 * numberColumns]; int *tail = new int[2 * numberColumns]; int *ub = new int[2 * numberColumns]; int *cost = new int[2 * numberColumns]; // ***** Remember to convert to C notation numberColumns = 0; while (fgets(temp, 100, fp)) { int iHead; int iTail; int iUb; int iCost; if (!strncmp(temp, "DEMAND", 6)) break; sscanf(temp, "%d %d %d %d", &iHead, &iTail, &iCost, &iUb); iHead--; iTail--; head[numberColumns] = iHead; tail[numberColumns] = iTail; ub[numberColumns] = iUb; cost[numberColumns] = iCost; numberColumns++; } if (strncmp(temp, "DEMAND", 6)) { fprintf(stderr, "Unable to find DEMAND\n"); exit(2); } // ***** Remember to convert to C notation while (fgets(temp, 100, fp)) { int row; int value; if (!strncmp(temp, "END", 3)) break; sscanf(temp, "%d %d", &row, &value); upper[row - 1] = value; lower[row - 1] = value; } if (strncmp(temp, "END", 3)) { fprintf(stderr, "Unable to find END\n"); exit(2); } printf("Problem %d has %d rows and %d columns\n", problem, numberRows, numberColumns); fclose(fp); ClpSimplex model; // now build model double *objective = new double[numberColumns]; double *lowerColumn = new double[numberColumns]; double *upperColumn = new double[numberColumns]; double *element = new double[2 * numberColumns]; CoinBigIndex *start = new CoinBigIndex[numberColumns + 1]; int *row = new int[2 * numberColumns]; start[numberColumns] = 2 * numberColumns; for (i = 0; i < numberColumns; i++) { start[i] = 2 * i; element[2 * i] = -1.0; element[2 * i + 1] = 1.0; row[2 * i] = head[i]; row[2 * i + 1] = tail[i]; lowerColumn[i] = 0.0; upperColumn[i] = ub[i]; objective[i] = cost[i]; } // Create Packed Matrix CoinPackedMatrix matrix; int *lengths = NULL; matrix.assignMatrix(true, numberRows, numberColumns, 2 * numberColumns, element, row, start, lengths); // load model model.loadProblem(matrix, lowerColumn, upperColumn, objective, lower, upper); model.factorization()->maximumPivots(200 + model.numberRows() / 100); model.createStatus(); double time1 = CoinCpuTime(); model.dual(); std::cout << "Network problem, ClpPackedMatrix took " << CoinCpuTime() - time1 << " seconds" << std::endl; ClpPlusMinusOneMatrix *plusMinus = new ClpPlusMinusOneMatrix(matrix); assert(plusMinus->getIndices()); // would be zero if not +- one //ClpPlusMinusOneMatrix *plusminus_matrix; //plusminus_matrix = new ClpPlusMinusOneMatrix; //plusminus_matrix->passInCopy(numberRows, numberColumns, true, plusMinus->getMutableIndices(), // plusMinus->startPositive(),plusMinus->startNegative()); model.loadProblem(*plusMinus, lowerColumn, upperColumn, objective, lower, upper); //model.replaceMatrix( plusminus_matrix , true); delete plusMinus; //model.createStatus(); //model.initialSolve(); //model.writeMps("xx.mps"); model.factorization()->maximumPivots(200 + model.numberRows() / 100); model.createStatus(); time1 = CoinCpuTime(); model.dual(); std::cout << "Network problem, ClpPlusMinusOneMatrix took " << CoinCpuTime() - time1 << " seconds" << std::endl; ClpNetworkMatrix network(numberColumns, head, tail); model.loadProblem(network, lowerColumn, upperColumn, objective, lower, upper); model.factorization()->maximumPivots(200 + model.numberRows() / 100); model.createStatus(); time1 = CoinCpuTime(); model.dual(); std::cout << "Network problem, ClpNetworkMatrix took " << CoinCpuTime() - time1 << " seconds" << std::endl; delete[] lower; delete[] upper; delete[] head; delete[] tail; delete[] ub; delete[] cost; delete[] objective; delete[] lowerColumn; delete[] upperColumn; } } #ifdef QUADRATIC // Test quadratic to solve linear if (1) { CoinMpsIO m; std::string fn = dirSample + "exmip1"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex solution; solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); //solution.dual(); // get quadratic part int numberColumns = solution.numberColumns(); int *start = new int[numberColumns + 1]; int *column = new int[numberColumns]; double *element = new double[numberColumns]; int i; start[0] = 0; int n = 0; int kk = numberColumns - 1; int kk2 = numberColumns - 1; for (i = 0; i < numberColumns; i++) { if (i >= kk) { column[n] = i; if (i >= kk2) element[n] = 1.0e-1; else element[n] = 0.0; n++; } start[i + 1] = n; } // Load up objective solution.loadQuadraticObjective(numberColumns, start, column, element); delete[] start; delete[] column; delete[] element; //solution.quadraticSLP(50,1.0e-4); CoinRelFltEq eq(1.0e-4); //assert(eq(objValue,820.0)); //solution.setLogLevel(63); solution.primal(); printSol(solution); //assert(eq(objValue,3.2368421)); //exit(77); } else { std::cerr << "Error reading exmip1 from sample data. Skipping test." << std::endl; } } // Test quadratic if (1) { CoinMpsIO m; std::string fn = dirSample + "share2qp"; //fn = "share2qpb"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex model; model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); model.dual(); // get quadratic part int *start = NULL; int *column = NULL; double *element = NULL; m.readQuadraticMps(NULL, start, column, element, 2); int column2[200]; double element2[200]; int start2[80]; int j; start2[0] = 0; int nel = 0; bool good = false; for (j = 0; j < 79; j++) { if (start[j] == start[j + 1]) { column2[nel] = j; element2[nel] = 0.0; nel++; } else { int i; for (i = start[j]; i < start[j + 1]; i++) { column2[nel] = column[i]; element2[nel++] = element[i]; } } start2[j + 1] = nel; } // Load up objective if (good) model.loadQuadraticObjective(model.numberColumns(), start2, column2, element2); else model.loadQuadraticObjective(model.numberColumns(), start, column, element); delete[] start; delete[] column; delete[] element; int numberColumns = model.numberColumns(); model.scaling(0); #if 0 model.nonlinearSLP(50, 1.0e-4); #else // Get feasible ClpObjective *saveObjective = model.objectiveAsObject()->clone(); ClpLinearObjective zeroObjective(NULL, numberColumns); model.setObjective(&zeroObjective); model.dual(); model.setObjective(saveObjective); delete saveObjective; #endif //model.setLogLevel(63); //exit(77); model.setFactorizationFrequency(10); model.primal(); printSol(model); #ifndef NDEBUG double objValue = model.getObjValue(); #endif CoinRelFltEq eq(1.0e-4); assert(eq(objValue, -400.92)); // and again for barrier model.barrier(false); //printSol(model); model.allSlackBasis(); model.primal(); //printSol(model); } else { std::cerr << "Error reading share2qp from sample data. Skipping test." << std::endl; } } if (0) { CoinMpsIO m; std::string fn = "./beale"; //fn = "./jensen"; if (m.readMps(fn.c_str(), "mps") == 0) { ClpSimplex solution; solution.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(), m.getObjCoefficients(), m.getRowLower(), m.getRowUpper()); solution.setDblParam(ClpObjOffset, m.objectiveOffset()); solution.dual(); // get quadratic part int *start = NULL; int *column = NULL; double *element = NULL; m.readQuadraticMps(NULL, start, column, element, 2); // Load up objective solution.loadQuadraticObjective(solution.numberColumns(), start, column, element); delete[] start; delete[] column; delete[] element; solution.primal(1); solution.nonlinearSLP(50, 1.0e-4); double objValue = solution.getObjValue(); CoinRelFltEq eq(1.0e-4); assert(eq(objValue, 0.5)); solution.primal(); objValue = solution.getObjValue(); assert(eq(objValue, 0.5)); } else { std::cerr << "Error reading beale.mps. Skipping test." << std::endl; } } #endif // Test CoinStructuredModel { // Sub block CoinModel sub; { // matrix data //deliberate hiccup of 2 between 0 and 1 CoinBigIndex start[5] = { 0, 4, 7, 8, 9 }; int length[5] = { 2, 3, 1, 1, 1 }; int rows[11] = { 0, 2, -1, -1, 0, 1, 2, 0, 1, 2 }; double elements[11] = { 7.0, 2.0, 1.0e10, 1.0e10, -2.0, 1.0, -2.0, 1, 1, 1 }; CoinPackedMatrix matrix(true, 3, 5, 8, elements, rows, start, length); // by row matrix.reverseOrdering(); const double *element = matrix.getElements(); const int *column = matrix.getIndices(); const CoinBigIndex *rowStart = matrix.getVectorStarts(); const int *rowLength = matrix.getVectorLengths(); // rim data //double objective[5]={-4.0,1.0,0.0,0.0,0.0}; double rowLower[3] = { 14.0, 3.0, 3.0 }; double rowUpper[3] = { 14.0, 3.0, 3.0 }; //double columnLower[5]={0.0,0.0,0.0,0.0,0.0}; //double columnUpper[5]={100.0,100.0,100.0,100.0,100.0}; for (int i = 0; i < 3; i++) { sub.addRow(rowLength[i], column + rowStart[i], element + rowStart[i], rowLower[i], rowUpper[i]); } //for (int i=0;i<5;i++) { //sub.setColumnBounds(i,columnLower[i],columnUpper[i]); //sub.setColumnObjective(i,objective[i]); //} sub.convertMatrix(); } // Top CoinModel top; { // matrix data CoinBigIndex start[5] = { 0, 2, 4, 6, 8 }; int length[5] = { 2, 2, 2, 2, 2 }; int rows[10] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; double elements[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; CoinPackedMatrix matrix(true, 2, 5, 8, elements, rows, start, length); // by row matrix.reverseOrdering(); const double *element = matrix.getElements(); const int *column = matrix.getIndices(); const CoinBigIndex *rowStart = matrix.getVectorStarts(); const int *rowLength = matrix.getVectorLengths(); // rim data double objective[5] = { -4.0, 1.0, 0.0, 0.0, 0.0 }; //double rowLower[3]={14.0,3.0,3.0}; //double rowUpper[3]={14.0,3.0,3.0}; double columnLower[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; double columnUpper[5] = { 100.0, 100.0, 100.0, 100.0, 100.0 }; for (int i = 0; i < 2; i++) { top.addRow(rowLength[i], column + rowStart[i], element + rowStart[i], -COIN_DBL_MAX, COIN_DBL_MAX); } for (int i = 0; i < 5; i++) { top.setColumnBounds(i, columnLower[i], columnUpper[i]); top.setColumnObjective(i, objective[i]); } top.convertMatrix(); } // Create a structured model CoinStructuredModel structured; int numberBlocks = 5; for (int i = 0; i < numberBlocks; i++) { std::string topName = "row_master"; std::string blockName = "block_"; char bName = static_cast< char >('a' + static_cast< char >(i)); blockName.append(1, bName); structured.addBlock(topName, blockName, top); structured.addBlock(blockName, blockName, sub); } // Set rhs on first block CoinModel *first = structured.coinBlock(0); for (int i = 0; i < 2; i++) { first->setRowLower(i, 0.0); first->setRowUpper(i, 100.0); } // Refresh whats set structured.refresh(0); // Could perturb stuff, but for first go don't bother ClpSimplex fullModel; // There is no original stuff set - think fullModel.loadProblem(structured, false); fullModel.dual(); fullModel.dropNames(); fullModel.writeMps("test.mps"); // Make up very simple nested model - not realistic // Create a structured model CoinStructuredModel structured2; numberBlocks = 3; for (int i = 0; i < numberBlocks; i++) { std::string blockName = "block_"; char bName = static_cast< char >('a' + static_cast< char >(i)); blockName.append(1, bName); structured2.addBlock(blockName, blockName, structured); } fullModel.loadProblem(structured2, false); fullModel.dual(); fullModel.dropNames(); fullModel.writeMps("test2.mps"); } #endif } /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 */