Changes from stable/2.8/Cbc/src/CbcNode.cpp at r2098 to trunk/Cbc/src/CbcNode.cpp at r2103
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

trunk/Cbc/src/CbcNode.cpp
r2098 r2103 7 7 // Turn off compiler warning about long names 8 8 # pragma warning(disable:4786) 9 #include <windows.h> // for Sleep() 10 #ifdef small 11 #undef small 12 #endif 13 #else 14 #include <unistd.h> // for usleep() 9 15 #endif 10 16 11 17 #include "CbcConfig.h" 18 #ifdef COIN_HAS_NTY 19 #include "CbcSymmetry.hpp" 20 #endif 12 21 //#define DEBUG_SOLUTION 13 22 #ifdef DEBUG_SOLUTION … … 43 52 #include "OsiClpSolverInterface.hpp" 44 53 #include "ClpSimplexOther.hpp" 54 #include "ClpSolve.hpp" 55 #include "ClpDualRowSteepest.hpp" 56 #include "ClpPrimalColumnPivot.hpp" 45 57 #endif 46 58 using namespace std; … … 60 72 { 61 73 #ifdef CHECK_NODE 62 printf("CbcNode % xConstructor\n", this);74 printf("CbcNode %p Constructor\n", this); 63 75 #endif 64 76 } … … 83 95 { 84 96 #ifdef CHECK_NODE 85 printf("CbcNode % xConstructor from model\n", this);97 printf("CbcNode %p Constructor from model\n", this); 86 98 #endif 87 99 model>setObjectiveValue(this, lastNode); … … 882 894 } 883 895 } 896 //if (!model>parentModel()) 897 //solver>writeMps("query"); 884 898 // If we have hit max time don't do strong branching 885 899 bool hitMaxTime = (model>getCurrentSeconds() > … … 1540 1554 // Set guessed solution value 1541 1555 guessedObjectiveValue_ = objectiveValue_ + estimatedDegradation; 1556 //printf ("Node %d depth %d unsatisfied %d sum %g obj %g guess %g\n", 1557 // model>getNodeCount(),depth_,numberUnsatisfied_, 1558 // sumInfeasibilities_,objectiveValue_,guessedObjectiveValue_); 1542 1559 /* 1543 1560 Cleanup, then we're outta here. … … 1611 1628 branch_ = NULL; 1612 1629 OsiSolverInterface * solver = model>solver(); 1630 //#define CHECK_DEBUGGER_PATH 1631 #ifdef CHECK_DEBUGGER_PATH 1632 bool onOptimalPath=false; 1633 if ((model>specialOptions()&1) != 0) { 1634 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 1635 if (debugger) { 1636 onOptimalPath = true; 1637 } 1638 } 1639 #endif 1613 1640 // get information on solver type 1614 1641 const OsiAuxInfo * auxInfo = solver>getAuxiliaryInfo(); … … 1954 1981 choice.possibleBranch = choiceObject; 1955 1982 numberPassesLeft = CoinMax(numberPassesLeft, 2); 1983 /* How dogged to be in strong branching 1984 0  default 1985 1  go to end on first time 1986 2  always go to end 1987 */ 1988 int goToEndInStrongBranching = (model>moreSpecialOptions2()&(3*8192))>>13; 1989 #ifdef COIN_HAS_NTY 1990 // 1 after, 2 strong, 3 until depth 5 1991 int orbitOption = (model>moreSpecialOptions2()&(128256))>>7; 1992 #endif 1956 1993 //#define DEBUG_SOLUTION 1957 1994 #ifdef DEBUG_SOLUTION … … 2620 2657 solver>unmarkHotStart(); 2621 2658 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 2659 #ifdef CHECK_DEBUGGER_PATH 2660 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 2661 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 2662 if (!debugger) { 2663 printf("Strong branching down on %d went off optimal path\n",iObject); 2664 abort(); 2665 } 2666 } 2667 #endif 2622 2668 double newObjValue = solver>getObjSense()*solver>getObjValue(); 2623 2669 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 2802 2848 } 2803 2849 #endif 2850 #ifdef COIN_HAS_NTY 2851 const int * orbits = NULL; 2852 #endif 2853 #ifdef COIN_HAS_NTY 2854 if (orbitOption==2 /* was >1*/) { 2855 CbcSymmetry * symmetryInfo = model>symmetryInfo(); 2856 CbcNodeInfo * infoX = lastNode ? lastNode>nodeInfo() : NULL; 2857 bool worthTrying = false; 2858 if (infoX) { 2859 CbcNodeInfo * info = infoX; 2860 for (int i=0;i<NTY_BAD_DEPTH;i++) { 2861 if (!info>parent()) { 2862 worthTrying = true; 2863 break; 2864 } 2865 info = info>parent(); 2866 if (info>symmetryWorked()) { 2867 worthTrying = true; 2868 break; 2869 } 2870 } 2871 } else { 2872 worthTrying=true; 2873 } 2874 if (symmetryInfo && worthTrying) { 2875 symmetryInfo>ChangeBounds(solver>getColLower(), 2876 solver>getColUpper(), 2877 solver>getNumCols(),false); 2878 symmetryInfo>Compute_Symmetry(); 2879 symmetryInfo>fillOrbits(); 2880 orbits = symmetryInfo>whichOrbit(); 2881 int iColumn=1; 2882 if (orbits && symmetryInfo>numberUsefulOrbits()) { 2883 bool doBranch=true; 2884 int numberUsefulOrbits = symmetryInfo>numberUsefulOrbits(); 2885 if (numberUsefulOrbits<2) { 2886 assert (numberUsefulOrbits); 2887 double largest=1.0; 2888 for (int i=0;i<numberColumns;i++) { 2889 if (orbits[i]>=0) { 2890 if (saveSolution[i]>largest) { 2891 largest=saveSolution[i]; 2892 iColumn=i; 2893 } 2894 } 2895 } 2896 } else { 2897 #if COIN_HAS_NTY2 == 1 2898 // take largest 2899 int iOrbit=symmetryInfo>largestOrbit(solver>getColLower(), 2900 solver>getColUpper()); 2901 double largest=1.0; 2902 for (int i=0;i<numberColumns;i++) { 2903 if (orbits[i]==iOrbit) { 2904 if (saveSolution[i]>largest) { 2905 largest=saveSolution[i]; 2906 iColumn=i; 2907 } 2908 } 2909 } 2910 #endif 2911 if (orbitOption==2) { 2912 // strong 2913 int nDo=0; 2914 const double * lower = solver>getColLower(); 2915 const double * upper = solver>getColUpper(); 2916 const int * integerVariable = model>integerVariable(); 2917 for (int iOrbit = 0; iOrbit < numberUsefulOrbits; iOrbit++) { 2918 double distance=1.0; 2919 int iColumn = 1; 2920 int numberIntegers = model>numberIntegers(); 2921 for (int j=0;j<numberIntegers;j++) { 2922 int i=integerVariable[j]; 2923 if (orbits[i]==iOrbit &&lower[i]==0.0&&upper[i]==1.0) { 2924 double away = fabs(saveSolution[i]0.5); 2925 if (away<distance&&away<0.4999) { 2926 distance=away; 2927 iColumn=j; 2928 } 2929 } 2930 } 2931 if (iColumn>=0) 2932 whichObject[nDo++]=iColumn; 2933 } 2934 if (nDo) 2935 numberToDo=nDo; 2936 doBranch=false; 2937 } else if (orbitOption==3) { 2938 // subset 2939 int nDo=0; 2940 for (int iDo = 0; iDo < numberToDo; iDo++) { 2941 int iObject = whichObject[iDo]; 2942 OsiObject * object = model>modifiableObject(iObject); 2943 CbcSimpleIntegerDynamicPseudoCost * dynamicObject = 2944 dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ; 2945 int iColumn = dynamicObject ? dynamicObject>columnNumber() : 1; 2946 if (iColumn<0orbits[iColumn]>=0) 2947 whichObject[nDo++]=whichObject[iDo]; 2948 } 2949 assert(nDo); 2950 //printf("nDo %d\n",nDo); 2951 numberToDo=nDo; 2952 doBranch=false; 2953 /* need NULL as if two in same orbit and strong branching fixes 2954 then we may be in trouble. 2955 Strong option should be OK as only one in set done. 2956 */ 2957 orbits=NULL; 2958 } 2959 } 2960 if(doBranch) { 2961 orbitOption=0; 2962 branch_ = new CbcOrbitalBranchingObject(model,iColumn,1,0,NULL); 2963 if (infoX) 2964 infoX>setSymmetryWorked(); 2965 numberToDo=0; 2966 } 2967 } 2968 } 2969 } 2970 #endif 2804 2971 for ( iDo = 0; iDo < numberToDo; iDo++) { 2805 2972 int iObject = whichObject[iDo]; … … 2810 2977 int preferredWay; 2811 2978 double infeasibility = object>infeasibility(&usefulInfo, preferredWay); 2979 bool feasibleSolution=false; 2812 2980 double predictedChange=0.0; 2813 2981 // may have become feasible … … 2848 3016 choice.downMovement = 0.1; 2849 3017 } 2850 2851 3018 assert (choice.upMovement >= 0.0); 3019 assert (choice.downMovement >= 0.0); 2852 3020 choice.fix = 0; // say not fixed 2853 3021 // see if can skip strong branching … … 2892 3060 double newObjectiveValue = 1.0e100; 2893 3061 int j; 3062 #ifdef COIN_HAS_CLP 3063 int saveMaxHotIts=0; 3064 int saveOsiClpOptions=0; 3065 if (osiclp && goToEndInStrongBranching) { 3066 /* How dogged to be in strong branching 3067 0  default 3068 1  go to end on first time 3069 2  always go to end 3070 */ 3071 osiclp>getIntParam(OsiMaxNumIterationHotStart, saveMaxHotIts); 3072 saveOsiClpOptions=osiclp>specialOptions(); 3073 if (goToEndInStrongBranching==2  3074 dynamicObject>numberTimesBranched()==0) { 3075 osiclp>setIntParam(OsiMaxNumIterationHotStart, 3076 10*(osiclp>getNumRows()+numberColumns)); 3077 osiclp>setSpecialOptions(saveOsiClpOptions & (~32)); 3078 } 3079 } 3080 #endif 2894 3081 // status is 0 finished, 1 infeasible and other 2895 3082 int iStatus; … … 2902 3089 choice.possibleBranch>way(1) ; 2903 3090 predictedChange = choice.possibleBranch>branch() ; 3091 #ifdef COIN_HAS_NTY 3092 if (orbits) { 3093 // can fix all in orbit 3094 int fixOrbit = orbits[iObject]; 3095 if (fixOrbit>=0) { 3096 //printf("fixing all in orbit %d for column %d\n",fixOrbit,iObject); 3097 for (int i=0;i<numberColumns;i++) { 3098 if (orbits[i]==fixOrbit) 3099 solver>setColUpper(i,0.0); 3100 } 3101 } 3102 } 3103 #endif 2904 3104 solver>solveFromHotStart() ; 2905 3105 bool needHotStartUpdate = false; … … 2921 3121 iStatus = 1; // infeasible 2922 3122 #ifdef CONFLICT_CUTS 3123 #undef CONFLICT_CUTS 3124 //#define CONFLICT_CUTS 2 3125 #endif 3126 #ifdef CONFLICT_CUTS 2923 3127 # ifdef COIN_HAS_CLP 2924 3128 if (osiclp&&(model>moreSpecialOptions()&4194304)!=0) { … … 2926 3130 model>topOfTree(); 2927 3131 if (topOfTree) { 3132 #if CONFLICT_CUTS==2 2928 3133 OsiRowCut * cut = osiclp>smallModelCut(topOfTree>lower(), 2929 3134 topOfTree>upper(), 2930 3135 model>numberRowsAtContinuous(), 2931 3136 model>whichGenerator()); 3137 #else 3138 OsiRowCut * cut = osiclp>modelCut(topOfTree>lower(), 3139 topOfTree>upper(), 3140 model>numberRowsAtContinuous(), 3141 model>whichGenerator(),0); 3142 #endif 2932 3143 if (cut) { 2933 printf("XXXXXX found conflict cut in strong branching\n"); 3144 if (model>messageHandler()>logLevel() > 1) 3145 printf("Conflict cut found in strong branching (%d elements)\n", 3146 cut>row().getNumElements()); 2934 3147 //cut>print(); 2935 3148 if ((model>specialOptions()&1) != 0) { … … 2998 3211 #endif 2999 3212 // See if integer solution 3000 if (model>feasibleSolution(choice.numIntInfeasDown, 3001 choice.numObjInfeasDown) 3213 feasibleSolution = 3214 model>feasibleSolution(choice.numIntInfeasDown, 3215 choice.numObjInfeasDown); 3216 if (feasibleSolution 3002 3217 && model>problemFeasibility()>feasible(model, 1) >= 0) { 3003 3218 if (auxiliaryInfo>solutionAddsCuts()) { … … 3046 3261 needHotStartUpdate = false; 3047 3262 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 3263 #ifdef CHECK_DEBUGGER_PATH 3264 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3265 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3266 if (!debugger) { 3267 printf("Strong branching down on %d went off optimal path\n",iObject); 3268 model>solver()>writeMps("query"); 3269 abort(); 3270 } 3271 } 3272 #endif 3048 3273 double newObjValue = solver>getObjSense()*solver>getObjValue(); 3049 3274 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 3092 3317 predictedChange=choice.possibleBranch>branch(); 3093 3318 solver>solveFromHotStart() ; 3319 #ifdef COIN_HAS_CLP 3320 if (osiclp && goToEndInStrongBranching) { 3321 osiclp>setIntParam(OsiMaxNumIterationHotStart, saveMaxHotIts); 3322 osiclp>setSpecialOptions(saveOsiClpOptions); 3323 } 3324 #endif 3094 3325 numberStrongDone++; 3095 3326 numberStrongIterations += solver>getIterationCount(); … … 3114 3345 model>topOfTree(); 3115 3346 if (topOfTree) { 3347 #if CONFLICT_CUTS==2 3116 3348 OsiRowCut * cut = osiclp>smallModelCut(topOfTree>lower(), 3117 3349 topOfTree>upper(), 3118 3350 model>numberRowsAtContinuous(), 3119 3351 model>whichGenerator()); 3352 #else 3353 OsiRowCut * cut = osiclp>modelCut(topOfTree>lower(), 3354 topOfTree>upper(), 3355 model>numberRowsAtContinuous(), 3356 model>whichGenerator(),0); 3357 #endif 3120 3358 if (cut) { 3121 printf("XXXXXX found conflict cut in strong branching\n");3359 //printf("XXXXXX found conflict cut in strong branching\n"); 3122 3360 //cut>print(); 3123 3361 if ((model>specialOptions()&1) != 0) { … … 3185 3423 #endif 3186 3424 // See if integer solution 3187 if (model>feasibleSolution(choice.numIntInfeasUp, 3188 choice.numObjInfeasUp) 3425 feasibleSolution = 3426 model>feasibleSolution(choice.numIntInfeasUp, 3427 choice.numObjInfeasUp); 3428 if (feasibleSolution 3189 3429 && model>problemFeasibility()>feasible(model, 1) >= 0) { 3190 3430 #ifdef BONMIN … … 3213 3453 if (needHotStartUpdate) { 3214 3454 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 3455 #ifdef CHECK_DEBUGGER_PATH 3456 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3457 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3458 if (!debugger) { 3459 printf("Strong branching up on %d went off optimal path\n",iObject); 3460 abort(); 3461 } 3462 } 3463 #endif 3215 3464 newObjectiveValue = solver>getObjSense() * solver>getObjValue(); 3216 3465 objectiveValue_ = CoinMax(objectiveValue_,newObjectiveValue); … … 3248 3497 needHotStartUpdate = false; 3249 3498 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 3499 #ifdef CHECK_DEBUGGER_PATH 3500 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3501 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3502 if (!debugger) { 3503 printf("Strong branching up on %d went off optimal path\n",iObject); 3504 abort(); 3505 } 3506 } 3507 #endif 3250 3508 double newObjValue = solver>getObjSense()*solver>getObjValue(); 3251 3509 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 3262 3520 solver>getColSolution()) ; 3263 3521 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 3522 #ifdef CHECK_DEBUGGER_PATH 3523 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3524 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3525 if (!debugger) { 3526 printf("Strong branching up on %d went off optimal path\n",iObject); 3527 abort(); 3528 } 3529 } 3530 #endif 3264 3531 double newObjValue = solver>getObjSense()*solver>getObjValue(); 3265 3532 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 3417 3684 solver>unmarkHotStart(); 3418 3685 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 3686 #ifdef CHECK_DEBUGGER_PATH 3687 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3688 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3689 if (!debugger) { 3690 printf("Strong branching down on %d went off optimal path\n",iObject); 3691 abort(); 3692 } 3693 } 3694 #endif 3419 3695 double newObjValue = solver>getObjSense()*solver>getObjValue(); 3420 3696 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 3469 3745 solver>unmarkHotStart(); 3470 3746 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper); 3747 #ifdef CHECK_DEBUGGER_PATH 3748 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3749 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3750 if (!debugger) { 3751 printf("Strong branching down on %d went off optimal path\n",iObject); 3752 solver>writeMps("query"); 3753 abort(); 3754 } 3755 } 3756 #endif 3471 3757 double newObjValue = solver>getObjSense()*solver>getObjValue(); 3472 3758 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 3562 3848 solver>setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ; 3563 3849 model>resolve(NULL, 11, saveSolution, saveLower, saveUpper) ; 3850 #ifdef CHECK_DEBUGGER_PATH 3851 if ((model>specialOptions()&1) != 0 && onOptimalPath) { 3852 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 3853 if (!debugger) { 3854 printf("Strong branching went off optimal path\n"); 3855 abort(); 3856 } 3857 } 3858 #endif 3564 3859 double newObjValue = solver>getObjSense()*solver>getObjValue(); 3565 3860 objectiveValue_ = CoinMax(objectiveValue_,newObjValue); … … 3668 3963 // Set guessed solution value 3669 3964 guessedObjectiveValue_ = objectiveValue_ + estimatedDegradation; 3965 int kColumn=1; 3966 if (branch_) { 3967 CbcObject * obj = (dynamic_cast<CbcBranchingObject *>(branch_))>object(); 3968 CbcSimpleInteger * branchObj = 3969 dynamic_cast <CbcSimpleInteger *>(obj) ; 3970 if (branchObj) { 3971 kColumn=branchObj>columnNumber(); 3972 } 3973 } 3974 #ifdef COIN_HAS_NTY 3975 if (orbitOption&&kColumn>=0) { 3976 CbcSymmetry * symmetryInfo = model>symmetryInfo(); 3977 CbcNodeInfo * infoX = lastNode ? lastNode>nodeInfo() : NULL; 3978 bool worthTrying = false; 3979 if (infoX) { 3980 CbcNodeInfo * info = infoX; 3981 for (int i=0;i<NTY_BAD_DEPTH;i++) { 3982 if (!info>parent()) { 3983 worthTrying = true; 3984 break; 3985 } 3986 info = info>parent(); 3987 if (info>symmetryWorked()) { 3988 worthTrying = true; 3989 break; 3990 } 3991 } 3992 } else { 3993 worthTrying=true; 3994 } 3995 if (orbitOption==3&&depth_>5) 3996 worthTrying=false; 3997 if (symmetryInfo && worthTrying) { 3998 if ((orbitOption&1)==1) { 3999 symmetryInfo>ChangeBounds(solver>getColLower(), 4000 solver>getColUpper(), 4001 solver>getNumCols(),false); 4002 symmetryInfo>Compute_Symmetry(); 4003 symmetryInfo>fillOrbits(); 4004 } 4005 const int * orbits = symmetryInfo>whichOrbit(); 4006 if (orbits && orbits[kColumn]>=0) { 4007 int numberUsefulOrbits = symmetryInfo>numberUsefulOrbits(); 4008 if (solver>messageHandler()>logLevel() > 1) 4009 printf("Orbital Branching on %d  way %d n %d\n",kColumn,way(),numberUsefulOrbits); 4010 if (numberUsefulOrbits<1000orbitOption==3) { 4011 delete branch_; 4012 branch_ = new CbcOrbitalBranchingObject(model,kColumn,1,0,NULL); 4013 if (infoX) 4014 infoX>setSymmetryWorked(); 4015 } 4016 } 4017 } 4018 } 4019 #endif 4020 if (model>logLevel()>1) 4021 printf ("Node %d depth %d unsatisfied %d sum %g obj %g guess %g branching on %d\n", 4022 model>getNodeCount(),depth_,numberUnsatisfied_, 4023 sumInfeasibilities_,objectiveValue_,guessedObjectiveValue_, 4024 kColumn); 3670 4025 #ifdef DO_ALL_AT_ROOT 3671 4026 if (strongType) { … … 3732 4087 return anyAction; 3733 4088 } 4089 // 0 is down, 1 is up 4090 typedef struct { 4091 double initialValue; // initial value 4092 double upLowerBound; // Lower bound when going up 4093 double downUpperBound; // Upper bound when going down 4094 double movement[2]; // cost (and initial away from feasible) 4095 double sumModified[2]; // Sum of integer changes 4096 int modified[2]; // Number integers changed 4097 int numIntInfeas[2]; // without odd ones 4098 int numObjInfeas[2]; // just odd ones 4099 bool finished[2]; // true if solver finished 4100 int numIters[2]; // number of iterations in solver (1 if never solved) 4101 double * integerSolution; // output if thinks integer solution 4102 # ifdef COIN_HAS_CLP 4103 ClpDualRowSteepest * steepest; 4104 #endif 4105 int columnNumber; // Which column it is 4106 } StrongInfo; 4107 typedef struct { 4108 double integerTolerance; 4109 double * originalSolution; 4110 CoinWarmStart * ws; 4111 double * newObjective; 4112 # ifdef COIN_HAS_CLP 4113 ClpDualRowSteepest * dualRowPivot; 4114 ClpPrimalColumnPivot * primalColumnPivot; 4115 # endif 4116 int * back; 4117 int solveType; 4118 } StrongStaticInfo; 4119 typedef struct { 4120 StrongStaticInfo *staticInfo; 4121 StrongInfo * choice; 4122 OsiSolverInterface * solver; 4123 double * tempSolution; 4124 CoinWarmStart * tempBasis; 4125 int whichChoice; 4126 } StrongBundle; 4127 /* return 1 if possible solution (for solveType 100 if infeasible) 4128 2 set if down was infeasible 4129 4 set if up was infeasible 4130 */ 4131 int solveAnalyze(void * info) { 4132 StrongBundle * bundle = reinterpret_cast<StrongBundle *>(info); 4133 StrongInfo * choice = bundle>choice; 4134 StrongStaticInfo * staticInfo = bundle>staticInfo; 4135 OsiSolverInterface * solver = bundle>solver; 4136 int solveType = staticInfo>solveType; 4137 if (solveType==77) { 4138 return 0; 4139 } 4140 const double * saveSolution = staticInfo>originalSolution; 4141 int iColumn = choice>columnNumber; 4142 const int * back = staticInfo>back; 4143 double newObjectiveValue = 1.0e100; 4144 double integerTolerance = staticInfo>integerTolerance; 4145 double bestSolutionValue=COIN_DBL_MAX; 4146 int returnStatus=0; 4147 // status is 0 finished, 1 infeasible and other 4148 int iStatus; 4149 /* 4150 Try the down direction first. (Specify the initial branching alternative as 4151 down with a call to way(1). Each subsequent call to branch() performs the 4152 specified branch and advances the branch object state to the next branch 4153 alternative.) 4154 */ 4155 for (int iWay=0;iWay<2;iWay++) { 4156 if (choice>numIters[iWay]==0) { 4157 int numberColumns=solver>getNumCols(); 4158 if (solveType!=100) { 4159 double saveBound; 4160 if (iWay==0) { 4161 saveBound = solver>getColUpper()[iColumn]; 4162 solver>setColUpper(iColumn,choice>downUpperBound); 4163 } else { 4164 saveBound = solver>getColLower()[iColumn]; 4165 solver>setColLower(iColumn,choice>upLowerBound); 4166 } 4167 if ((solveType&2)==0) { 4168 solver>solveFromHotStart() ; 4169 } else { 4170 // restore basis 4171 solver>setWarmStart(staticInfo>ws); 4172 # ifdef COIN_HAS_CLP 4173 if (staticInfo>dualRowPivot) { 4174 OsiClpSolverInterface * osiclp = dynamic_cast<OsiClpSolverInterface *>(solver); 4175 ClpSimplex * simplex = osiclp>getModelPtr(); 4176 simplex>setDualRowPivotAlgorithm(*staticInfo>dualRowPivot); 4177 //simplex>dualRowPivot()>saveWeights(simplex,4); 4178 simplex>setWhatsChanged(ALL_SAME_EXCEPT_COLUMN_BOUNDS); 4179 simplex>dual(0,5); 4180 } else { 4181 #endif 4182 solver>resolve(); 4183 # ifdef COIN_HAS_CLP 4184 } 4185 #endif 4186 } 4187 if (iWay==0) 4188 solver>setColUpper(iColumn,saveBound); 4189 else 4190 solver>setColLower(iColumn,saveBound); 4191 /* 4192 We now have an estimate of objective degradation that we can use for strong 4193 branching. If we're over the cutoff, the variable is monotone up. 4194 If we actually made it to optimality, check for a solution, and if we have 4195 a good one, call setBestSolution to process it. Note that this may reduce the 4196 cutoff, so we check again to see if we can declare this variable monotone. 4197 */ 4198 if (solver>isProvenOptimal()) { 4199 iStatus = 0; // optimal 4200 } else if (solver>isIterationLimitReached() 4201 && !solver>isDualObjectiveLimitReached()) { 4202 iStatus = 2; // unknown 4203 } else { 4204 iStatus = 1; // infeasible 4205 } 4206 newObjectiveValue = solver>getObjSense() * solver>getObjValue(); 4207 choice>numIters[iWay] = solver>getIterationCount(); 4208 // Look at interaction 4209 const double * thisSolution = solver>getColSolution(); 4210 int numberModified=0; 4211 double sumModified=0.0; 4212 int numberInfeas=0; 4213 for (int i=0;i<numberColumns;i++) { 4214 if (back[i]>=0) { 4215 double value = thisSolution[i]; 4216 if (iColumn!=i) { 4217 double difference = fabs(saveSolution[i]value); 4218 if (difference>integerTolerance) { 4219 numberModified++; 4220 sumModified += difference; 4221 } 4222 } 4223 if (fabs(valuefloor(value+0.5))>integerTolerance) 4224 numberInfeas++;; 4225 } 4226 } 4227 choice>numIntInfeas[iWay]=numberInfeas; 4228 choice>sumModified[iWay] = sumModified; 4229 choice>modified[iWay] = numberModified; 4230 if (!iStatus) { 4231 choice>finished[iWay] = true ; 4232 if (!numberInfeas) { 4233 returnStatus=1; 4234 if (!choice>integerSolution) { 4235 bestSolutionValue=newObjectiveValue; 4236 choice>integerSolution=CoinCopyOfArray(thisSolution,numberColumns);; 4237 } else if (bestSolutionValue>newObjectiveValue) { 4238 memcpy(choice>integerSolution,thisSolution,numberColumns*sizeof(double)); 4239 } 4240 } 4241 } else if (iStatus == 1) { 4242 newObjectiveValue = 1.0e100 ; 4243 } else { 4244 // Can't say much as we did not finish 4245 choice>finished[iWay] = false ; 4246 } 4247 choice>movement[iWay] = newObjectiveValue ; 4248 } else { 4249 # ifdef COIN_HAS_CLP 4250 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); 4251 ClpSimplex * simplex = osiclp ? osiclp>getModelPtr() : NULL; 4252 #endif 4253 // doing continuous and general integer 4254 solver>setColSolution(staticInfo>originalSolution); 4255 solver>setWarmStart(staticInfo>ws); 4256 double saveBound; 4257 double newBound; 4258 if (iWay==0) { 4259 saveBound=solver>getColUpper()[iColumn]; 4260 solver>setColUpper(iColumn,choice>downUpperBound); 4261 newBound=choice>downUpperBound; 4262 } else { 4263 saveBound=solver>getColLower()[iColumn]; 4264 solver>setColLower(iColumn,choice>upLowerBound); 4265 newBound=choice>upLowerBound; 4266 } 4267 # if 0 //def COIN_HAS_CLP 4268 if (simplex) { 4269 // set solution to new bound (if basic will be recomputed) 4270 simplex>primalColumnSolution()[iColumn]=newBound; 4271 } 4272 #endif 4273 solver>setHintParam(OsiDoDualInResolve, true, OsiHintDo) ; 4274 #define PRINT_ANALYZE 0 4275 #if PRINT_ANALYZE>0 4276 osiclp>getModelPtr()>setLogLevel(1); 4277 solver>setHintParam(OsiDoReducePrint, false, OsiHintTry); 4278 #endif 4279 solver>resolve(); 4280 if (iWay==0) { 4281 #if PRINT_ANALYZE>0 4282 printf("column %d down original %g <= %g <= %g upper now %g  result %s\n", 4283 iColumn,solver>getColLower()[iColumn], 4284 staticInfo>originalSolution[iColumn],saveBound, 4285 newBound,solver>isProvenOptimal() ? "ok" : "infeas"); 4286 #endif 4287 solver>setColUpper(iColumn,saveBound); 4288 } else { 4289 #if PRINT_ANALYZE>0 4290 printf("column %d up original %g <= %g <= %g lower now %g  result %s\n", 4291 iColumn,saveBound,staticInfo>originalSolution[iColumn], 4292 solver>getColUpper()[iColumn], 4293 newBound,solver>isProvenOptimal() ? "ok" : "infeas"); 4294 #endif 4295 solver>setColLower(iColumn,saveBound); 4296 } 4297 choice>numIters[iWay] = solver>getIterationCount(); 4298 if (solver>isProvenOptimal()) { 4299 //printf("Way %d  all way %d iterations  column %d\n", 4300 // iWay,solver>getIterationCount(),iColumn); 4301 // can go all way 4302 choice>movement[iWay] = newBound; 4303 } else { 4304 // zero objective 4305 double offset; 4306 solver>getDblParam(OsiObjOffset,offset); 4307 solver>setDblParam(OsiObjOffset, 0.0); 4308 solver>setObjective(staticInfo>newObjective+numberColumns); 4309 if (iWay==0) { 4310 solver>setObjCoeff(iColumn,1.0); 4311 } else { 4312 solver>setObjCoeff(iColumn,1.0); 4313 } 4314 solver>setColSolution(staticInfo>originalSolution); 4315 solver>setWarmStart(staticInfo>ws); 4316 solver>setHintParam(OsiDoDualInResolve, false, OsiHintDo) ; 4317 solver>resolve(); 4318 //printf("Way %d  first solve %d iterations, second %d  column %d\n", 4319 // iWay,choice>numIters[iWay],solver>getIterationCount(),iColumn); 4320 choice>movement[iWay] = solver>getColSolution()[iColumn]; 4321 choice>numIters[iWay] += solver>getIterationCount(); 4322 #if PRINT_ANALYZE>0 4323 if (iWay==0) { 4324 printf("column %d down can get to %g  result %s\n", 4325 iColumn,solver>getColSolution()[iColumn],solver>isProvenOptimal() ? "ok" : "infeas"); 4326 } else { 4327 printf("column %d up can get to %g  result %s\n", 4328 iColumn,solver>getColSolution()[iColumn],solver>isProvenOptimal() ? "ok" : "infeas"); 4329 } 4330 #endif 4331 // reset objective 4332 solver>setDblParam(OsiObjOffset, offset); 4333 solver>setObjective(staticInfo>newObjective); 4334 if (!solver>isProvenOptimal()) { 4335 # ifdef COIN_HAS_CLP 4336 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); 4337 ClpSimplex * simplex = osiclp>getModelPtr(); 4338 double sum = simplex>sumPrimalInfeasibilities(); 4339 sum /= static_cast<double>(simplex>numberPrimalInfeasibilities()); 4340 if (sum>1.0e3) { 4341 #endif 4342 choice>modified[0]=1; 4343 returnStatus=1; 4344 solver>writeMps("bad","mps"); 4345 abort(); 4346 # ifdef COIN_HAS_CLP 4347 } 4348 #endif 4349 } 4350 } 4351 //solver>setObjCoeff(iColumn,0.0); 4352 } 4353 } 4354 } 4355 return returnStatus; 4356 } 4357 #ifdef THREADS_IN_ANALYZE 4358 void * cbc_parallelManager(void * stuff) 4359 { 4360 CoinPthreadStuff * driver = reinterpret_cast<CoinPthreadStuff *>(stuff); 4361 int whichThread=driver>whichThread(); 4362 CoinThreadInfo * threadInfo = driver>threadInfoPointer(whichThread); 4363 threadInfo>status=1; 4364 int * which = threadInfo>stuff; 4365 pthread_barrier_wait(driver>barrierPointer()); 4366 #if 0 4367 int status=1; 4368 while (status!=100) 4369 status=timedWait(driver,1000,2); 4370 pthread_cond_signal(driver>conditionPointer(1)); 4371 pthread_mutex_unlock(driver>mutexPointer(1,whichThread)); 4372 #endif 4373 // so now mutex_ is locked 4374 int whichLocked=0; 4375 while (true) { 4376 pthread_mutex_t * mutexPointer = driver>mutexPointer(whichLocked,whichThread); 4377 // wait 4378 //printf("Child waiting for %d  status %d %d %d\n", 4379 // whichLocked,lockedX[0],lockedX[1],lockedX[2]); 4380 #ifdef DETAIL_THREAD 4381 printf("thread %d about to lock mutex %d\n",whichThread,whichLocked); 4382 #endif 4383 pthread_mutex_lock (mutexPointer); 4384 whichLocked++; 4385 if (whichLocked==3) 4386 whichLocked=0; 4387 int unLock=whichLocked+1; 4388 if (unLock==3) 4389 unLock=0; 4390 //printf("child pointer %p status %d\n",threadInfo,threadInfo>status); 4391 assert(threadInfo>status>=0); 4392 if (threadInfo>status==1000) 4393 pthread_exit(NULL); 4394 int type=threadInfo>status; 4395 int & returnCode=which[0]; 4396 int iPass=which[1]; 4397 //CoinIndexedVector * array; 4398 //double dummy; 4399 switch(type) { 4400 // dummy 4401 case 0: 4402 break; 4403 case 1: 4404 returnCode=solveAnalyze(threadInfo>extraInfo); 4405 threadInfo>stuff[3]=0; 4406 break; 4407 case 100: 4408 // initialization 4409 break; 4410 } 4411 threadInfo>status= (type!=1) ? 1 : 2; 4412 #ifdef DETAIL_THREAD 4413 printf("thread %d about to unlock mutex %d\n",whichThread,unLock); 4414 #endif 4415 pthread_mutex_unlock (driver>mutexPointer(unLock,whichThread)); 4416 } 4417 } 4418 #endif 3734 4419 int CbcNode::analyze (CbcModel *model, double * results) 3735 4420 { 3736 int i; 3737 int numberIterationsAllowed = model>numberAnalyzeIterations(); 3738 OsiSolverInterface * solver = model>solver(); 3739 objectiveValue_ = solver>getObjSense() * solver>getObjValue(); 3740 double cutoff = model>getCutoff(); 4421 #define COIN_DETAIL 4422 int i; 4423 int numberIterationsAllowed = model>numberAnalyzeIterations(); 4424 int numberColumns = model>getNumCols(); 4425 int numberRows = model>getNumRows(); 4426 int numberObjects = model>numberObjects(); 4427 int numberIntegers = model>numberIntegers(); 4428 int numberLookIntegers=0; 4429 int highestPriority=COIN_INT_MAX; 4430 int * back = new int[numberColumns]; 4431 const int * integerVariable = model>integerVariable(); 4432 for (i = 0; i < numberIntegers; i++) { 4433 highestPriority = CoinMin(highestPriority,model>modifiableObject(i)>priority()); 4434 } 4435 for (i = 0; i < numberColumns; i++) 4436 back[i] = 1; 4437 for (i = 0; i < numberIntegers; i++) { 4438 int iColumn = integerVariable[i]; 4439 back[iColumn] = i; 4440 if (model>modifiableObject(i)>priority()==highestPriority) { 4441 numberLookIntegers++; 4442 } else { 4443 back[iColumn] = i+numberColumns; 4444 } 4445 } 4446 /* 4447 0  just look 4448 0 (1) bit  use to set priorities 4449 1 (2) bit  look at bounds on all variables and more iterations 4450 2 (4) bit  do threaded (if parallelMode()==1 then not repeatable if any fixed) 4451 3 (8) bit  4452 4 (16) bit  do even if m*n>1,000,000 4453 5 (32) bit  printing time 4454 6 (64) bit  save mps file 4455 */ 4456 int solveType; 4457 char general[200]; 4458 if (numberIterationsAllowed>0) { 4459 solveType = 0; 4460 } else { 4461 solveType =  numberIterationsAllowed; 4462 if ((solveType&16)==0) { 4463 double size=numberRows; 4464 size*=numberLookIntegers; 4465 if (size>1000000) { 4466 if ((solveType&32)!=0) 4467 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4468 << "Skipping analyze as problem too large" 4469 << CoinMessageEol; 4470 return 0; 4471 } 4472 } 4473 sprintf(general,"Analyze options %d",solveType); 4474 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4475 << general 4476 << CoinMessageEol; 4477 if ((solveType&1)!=0) 4478 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4479 << "Using to set priorities (probably bad idea)" 4480 << CoinMessageEol; 4481 if ((solveType&2)!=0) 4482 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4483 << "Use more iterations and look at continuous/general integer variables" 4484 << CoinMessageEol; 4485 if ((solveType&4)!=0) 4486 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4487 << "Use threads" 4488 << CoinMessageEol; 4489 if ((solveType&32)!=0) 4490 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4491 << "32 switches on more printing, (16 bit allows large problems)" 4492 << CoinMessageEol; 4493 } 4494 OsiSolverInterface * solver = model>solver(); 4495 objectiveValue_ = solver>getObjSense() * solver>getObjValue(); 4496 const double * lower = solver>getColLower(); 4497 const double * upper = solver>getColUpper(); 4498 const double * dj = solver>getReducedCost(); 4499 // What results is 4500 double * newLower = results; 4501 double * objLower = newLower + numberIntegers; 4502 double * newUpper = objLower + numberIntegers; 4503 double * objUpper = newUpper + numberIntegers; 4504 double * interAction = objUpper + numberIntegers; 4505 for (i = 0; i < numberIntegers; i++) { 4506 int iColumn = integerVariable[i]; 4507 newLower[i] = lower[iColumn]; 4508 objLower[i] = COIN_DBL_MAX; 4509 newUpper[i] = upper[iColumn]; 4510 objUpper[i] = COIN_DBL_MAX; 4511 interAction[i] = 0.0; 4512 } 4513 double * objMovement=new double[2*numberIntegers]; 4514 memset(objMovement,0,2*numberIntegers*sizeof(double)); 4515 double * saveUpper = new double[numberColumns]; 4516 double * saveLower = new double[numberColumns]; 4517 // Save solution in case heuristics need good solution later 4518 4519 double * saveSolution = new double[numberColumns]; 4520 memcpy(saveSolution, solver>getColSolution(), numberColumns*sizeof(double)); 4521 model>reserveCurrentSolution(saveSolution); 4522 for (i = 0; i < numberColumns; i++) { 4523 saveLower[i] = lower[i]; 4524 saveUpper[i] = upper[i]; 4525 } 4526 // Get arrays to sort 4527 double * sort = new double[numberObjects]; 4528 int * whichObject = new int[numberObjects]; 4529 int numberToFix = 0; 4530 int numberToDo = 0; 4531 double integerTolerance = 4532 model>getDblParam(CbcModel::CbcIntegerTolerance); 4533 // point to useful information 4534 OsiBranchingInformation usefulInfo = model>usefulInformation(); 4535 // and modify 4536 usefulInfo.depth_ = depth_; 4537 4538 // compute current state 4539 int numberObjectInfeasibilities; // just odd ones 4540 int numberIntegerInfeasibilities; 4541 model>feasibleSolution( 4542 numberIntegerInfeasibilities, 4543 numberObjectInfeasibilities); 4544 if (solveType) { 4545 if ((solveType&2)==0) 4546 numberIterationsAllowed=200*numberIntegerInfeasibilities; 4547 else 4548 numberIterationsAllowed=COIN_INT_MAX; 4549 } 4550 int saveAllowed=numberIterationsAllowed; 4551 # ifdef COIN_HAS_CLP 4552 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); 4553 int saveClpOptions = 0; 4554 bool fastIterations = (model>specialOptions() & 8) != 0; 4555 if (osiclp) { 4556 saveClpOptions = osiclp>specialOptions(); 4557 // for faster hot start 4558 if (fastIterations) 4559 osiclp>setSpecialOptions(saveClpOptions  8192); 4560 else 4561 osiclp>setSpecialOptions(saveClpOptions  2048); // switch off crunch 4562 } 4563 # else 4564 bool fastIterations = false ; 4565 # endif 4566 /* 4567 Scan for branching objects that indicate infeasibility. 4568 4569 The algorithm is to fill the array with a set of good candidates (by 4570 infeasibility). 4571 4572 */ 4573 numberToDo = 0; 4574 for (i = 0; i < numberObjects; i++) { 4575 OsiObject * object = model>modifiableObject(i); 4576 CbcSimpleIntegerDynamicPseudoCost * dynamicObject = 4577 dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ; 4578 if (!dynamicObject) 4579 continue; 4580 if (dynamicObject>priority()!=highestPriority) 4581 continue; 4582 double infeasibility = object>checkInfeasibility(&usefulInfo); 4583 int iColumn = dynamicObject>columnNumber(); 4584 if (saveUpper[iColumn] == saveLower[iColumn]) 4585 continue; 4586 if (infeasibility) 4587 sort[numberToDo] = 1.0e10  infeasibility; 4588 else 4589 sort[numberToDo] = fabs(dj[iColumn]); 4590 whichObject[numberToDo++] = i; 4591 } 4592 // Save basis 4593 CoinWarmStart * ws = solver>getWarmStart(); 4594 int saveLimit; 4595 solver>getIntParam(OsiMaxNumIterationHotStart, saveLimit); 4596 int targetIterations = CoinMax(500, numberIterationsAllowed / numberObjects); 4597 if (saveLimit < targetIterations) 4598 solver>setIntParam(OsiMaxNumIterationHotStart, targetIterations); 4599 if ((solveType&2)==0) { 4600 // Mark hot start 4601 solver>markHotStart(); 4602 } 4603 solver>setHintParam(OsiDoDualInResolve, true, OsiHintDo) ; 4604 // Sort 4605 CoinSort_2(sort, sort + numberToDo, whichObject); 4606 double * currentSolution = model>currentSolution(); 4607 double objMin = 1.0e50; 4608 double objMax = 1.0e50; 4609 bool needResolve = false; 4610 int maxChoices=1; 4611 int currentChoice=0; 4612 int numberThreads=0; 4613 bool doAtEnd=false; 4614 if (model>parallelMode() && (solveType&4)!=0) { 4615 numberThreads=model>getNumberThreads(); 4616 sprintf(general,"Using %d threads in analysis\n",numberThreads); 4617 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4618 << general 4619 << CoinMessageEol; 4620 if (model>parallelMode()==1) { 4621 maxChoices=numberThreads; 4622 } else { 4623 maxChoices = numberToDo; 4624 if ((solveType&2)!=0) 4625 maxChoices = numberColumns; 4626 doAtEnd=true; 4627 } 4628 } 4629 StrongInfo * choices = new StrongInfo[maxChoices]; 4630 StrongStaticInfo staticInfo; 4631 int numberBundles = CoinMax(1,numberThreads); 4632 StrongBundle * bundles = new StrongBundle[numberBundles]; 4633 /* 4634 0  available  no need to look at results 4635 1  not available 4636 2  available  need to look at results 4637 */ 4638 #ifndef NUMBER_THREADS 4639 #define NUMBER_THREADS 4 4640 #endif 4641 int status[NUMBER_THREADS]; 4642 memset(status,0,sizeof(status)); 4643 memset(&staticInfo,0,sizeof(staticInfo)); 4644 staticInfo.solveType = solveType; 4645 staticInfo.originalSolution=saveSolution; 4646 staticInfo.back=back; 4647 staticInfo.ws=ws; 4648 staticInfo.integerTolerance=integerTolerance; 4649 double time1 = model>getCurrentSeconds(); 4650 #define DO_STEEPEST_SERIAL 1 4651 # ifdef COIN_HAS_CLP 4652 if (osiclp&&(solveType&2)!=0&&(!numberThreadsDO_STEEPEST_SERIAL)) { 4653 ClpSimplex * simplex = osiclp>getModelPtr(); 4654 simplex>setLogLevel(0); 4655 simplex>dual(0,1); 4656 ClpDualRowPivot * dualRowPivot=simplex>dualRowPivot(); 4657 ClpDualRowSteepest * steep = dynamic_cast<ClpDualRowSteepest *>(dualRowPivot); 4658 if (steep) { 4659 staticInfo.dualRowPivot=new ClpDualRowSteepest (*steep); 4660 staticInfo.dualRowPivot>setMode(1); // full steepest edge 4661 simplex>spareIntArray_[0]=0; 4662 simplex>spareIntArray_[1]=numberRows; 4663 staticInfo.dualRowPivot>saveWeights(simplex,7); 4664 } 4665 } 4666 #endif 4667 for (int i=0;i<numberBundles;i++) { 4668 memset(bundles+i,0,sizeof(StrongBundle)); 4669 bundles[i].staticInfo=&staticInfo; 4670 } 4671 #if defined (THREADS_IN_ANALYZE) && defined (COIN_HAS_CLP) 4672 #define USE_STRONG_THREADS 4673 CoinPthreadStuff threadInfo(numberThreads,cbc_parallelManager); 4674 int threadNeedsRefreshing[NUMBER_THREADS]; 4675 for (int i=0;i<numberThreads;i++) { 4676 threadInfo.threadInfo_[i].extraInfo2 = solver>clone(); 4677 threadNeedsRefreshing[i]=0; 4678 } 4679 # ifdef COIN_HAS_CLP 4680 int numberSteepThreads=0; 4681 int step=numberThreads ? (numberRows+numberThreads1)/numberThreads : 0; 4682 int first=0; 4683 for (int i=0;i<numberThreads;i++) { 4684 if (osiclp&&(solveType&2)!=0&&!DO_STEEPEST_SERIAL) { 4685 OsiSolverInterface * solver= 4686 reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[i].extraInfo2); 4687 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); 4688 ClpSimplex * simplex = osiclp>getModelPtr(); 4689 simplex>setLogLevel(0); 4690 simplex>dual(0,1); 4691 ClpDualRowPivot * dualRowPivot=simplex>dualRowPivot(); 4692 ClpDualRowSteepest * steep = dynamic_cast<ClpDualRowSteepest *>(dualRowPivot); 4693 if (steep) { 4694 numberSteepThreads=numberThreads; 4695 ClpDualRowSteepest * dualRowPivot=new ClpDualRowSteepest (*steep); 4696 dualRowPivot>setMode(1); // full steepest edge 4697 simplex>spareIntArray_[0]=0; 4698 simplex>spareIntArray_[1]=numberRows; 4699 simplex>spareIntArray_[0]=first; 4700 simplex>spareIntArray_[1]=CoinMin(first+step,numberRows); 4701 first += step; 4702 if (i==0) 4703 staticInfo.dualRowPivot=dualRowPivot; 4704 choices[i].steepest=dualRowPivot; 4705 dualRowPivot>saveWeights(simplex,7); 4706 } 4707 } 4708 } 4709 if (numberSteepThreads&&false) { 4710 int numberDone=0; 4711 int iDo=0; 4712 staticInfo.solveType = 200; 4713 while (numberDone<numberSteepThreads) { 4714 int iThread; 4715 threadInfo.waitParallelTask(1,iThread,iDo<numberToDo); 4716 int threadStatus = 1+threadInfo.threadInfo_[iThread].status; 4717 iThread=iThread; 4718 if (threadStatus==0&&iDo<numberSteepThreads) { 4719 StrongInfo & choice = choices[iThread]; 4720 StrongBundle & bundle = bundles[iThread]; 4721 bundle.whichChoice=iThread; 4722 memset(&choice,0,sizeof(StrongInfo)); 4723 iDo++; //started this one 4724 bundle.choice=&choice; 4725 bundle.solver = solver; 4726 bundle.solver=reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 4727 threadStatus=0; 4728 #ifdef DETAIL_THREAD 4729 printf("Starting steep task on thread %d\n", 4730 choice.iThread); 4731 #endif 4732 threadInfo.startParallelTask(1,iThread,&bundle); 4733 } 4734 if (!threadStatus) { 4735 #ifdef _MSC_VER 4736 Sleep(1); 4737 #else 4738 usleep(1000); 4739 #endif 4740 continue; 4741 } 4742 if (threadStatus) { 4743 numberDone++; 4744 // say available 4745 threadInfo.sayIdle(iThread); 4746 } 4747 staticInfo.solveType = solveType; 4748 } 4749 OsiSolverInterface * solver0= 4750 reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[0].extraInfo2); 4751 CoinIndexedVector * savedWeights0 = staticInfo.dualRowPivot>savedWeights(); 4752 int * index0 = savedWeights0>getIndices(); 4753 double * weight0 = savedWeights0>denseVector(); 4754 int step=(numberRows+numberSteepThreads1)/numberSteepThreads; 4755 int first=step; 4756 //memset(weight0+first,0,(numberRowsfirst)*sizeof(double)); 4757 for (int i=1;i<numberSteepThreads;i++) { 4758 int n=CoinMin(step,numberRowsfirst); 4759 CoinIndexedVector * savedWeights = choices[i].steepest>savedWeights(); 4760 int * index = savedWeights>getIndices(); 4761 double * weight = savedWeights>denseVector(); 4762 memcpy(index0+first,index+first,n*sizeof(int)); 4763 memcpy(weight0+first,weight+first,n*sizeof(double)); 4764 first += step; 4765 delete choices[i].steepest; 4766 choices[i].steepest=NULL; 4767 } 4768 //for (int j=0;j<numberRows;j++) 4769 //weight0[j]=1.0; 4770 } 4771 #endif 4772 #endif 4773 double bestSolutionValue = model>getMinimizationObjValue(); 4774 double * bestSolution = NULL; 4775 double cutoff; 4776 solver>getDblParam(OsiDualObjectiveLimit,cutoff); 4777 double maxMovement = 2.0*(cutoffobjectiveValue_)+1.0e6; 4778 /* 4779 Now calculate the cost forcing the variable up and down. 4780 */ 4781 int iDo=0; 4782 int iDone=1; 4783 int numberDone=0; 4784 int iThread=0; 4785 int threadStatus=0; 4786 int whenPrint = (numberToDo+9)/10; 4787 while (numberDone<numberToDo) { 4788 if ((solveType&32)!=0&&numberDone==whenPrint) { 4789 whenPrint += (numberToDo+9)/10; 4790 sprintf(general,"%d variables looked at  %d changed by initial strong branching (%.2f seconds  %d iterations)",numberDone,numberToFix,model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 4791 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 4792 << general 4793 << CoinMessageEol; 4794 } 4795 #ifdef USE_STRONG_THREADS 4796 if (numberThreads) { 4797 threadInfo.waitParallelTask(1,iThread,iDo<numberToDo); 4798 threadStatus = 1+threadInfo.threadInfo_[iThread].status; 4799 if (!doAtEnd) 4800 currentChoice=iThread; 4801 if (threadNeedsRefreshing[iThread]) { 4802 OsiSolverInterface * solver= 4803 reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 4804 if ((threadNeedsRefreshing[iThread]&1)!=0) 4805 solver>setColLower(saveLower); 4806 if ((threadNeedsRefreshing[iThread]&2)!=0) 4807 solver>setColUpper(saveUpper); 4808 threadNeedsRefreshing[iThread]=0; 4809 } 4810 } 4811 #endif 4812 if (threadStatus==0&&iDo<numberToDo) { 4813 StrongInfo & choice = choices[currentChoice]; 4814 StrongBundle & bundle = bundles[iThread]; 4815 bundle.whichChoice=currentChoice; 4816 memset(&choice,0,sizeof(StrongInfo)); 4817 int iObject = whichObject[iDo]; 4818 iDo++; //started this one 4819 OsiObject * object = model>modifiableObject(iObject); 4820 CbcSimpleIntegerDynamicPseudoCost * dynamicObject = 4821 dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ; 4822 int iColumn = dynamicObject>columnNumber(); 4823 double value = currentSolution[iColumn]; 4824 double nearest = floor(value + 0.5); 4825 double lowerValue = floor(value); 4826 bool satisfied = false; 4827 if (fabs(value  nearest) <= integerTolerance  4828 value < saveLower[iColumn]  value > saveUpper[iColumn]) { 4829 satisfied = true; 4830 if (nearest < saveUpper[iColumn]) { 4831 lowerValue = nearest; 4832 } else { 4833 lowerValue = nearest  1; 4834 } 4835 } 4836 double upperValue = lowerValue + 1.0; 4837 // Save which object it was 4838 choice.columnNumber = iColumn; 4839 choice.initialValue=value; 4840 choice.upLowerBound=upperValue; 4841 choice.downUpperBound=lowerValue; 4842 choice.numIntInfeas[1] = numberUnsatisfied_; 4843 choice.numIntInfeas[0] = numberUnsatisfied_; 4844 choice.movement[0] = 0.0; 4845 choice.movement[1] = 0.0; 4846 choice.numIters[0] = 0; 4847 choice.numIters[1] = 0; 4848 if (fabs(value  lowerValue) <= integerTolerance) 4849 choice.numIters[0]=1; // mark as not done 4850 if (fabs(value  upperValue) <= integerTolerance) 4851 choice.numIters[1]=1; // mark as not done 4852 bundle.choice=&choice; 4853 bundle.solver = solver; 4854 #ifdef USE_STRONG_THREADS 4855 if (numberThreads) { 4856 bundle.solver=reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 4857 threadStatus=0; 4858 #ifdef DETAIL_THREAD 4859 printf("Starting task for column %d on thread %d\n", 4860 choice.columnNumber,iThread); 4861 #endif 4862 threadInfo.startParallelTask(1,iThread,&bundle); 4863 } else { 4864 #endif 4865 threadStatus=2; 4866 solveAnalyze(&bundle); 4867 #ifdef USE_STRONG_THREADS 4868 } 4869 #endif 4870 } 4871 if (!threadStatus) { 4872 #ifdef _MSC_VER 4873 Sleep(1); 4874 #else 4875 usleep(1000); 4876 #endif 4877 continue; 4878 } 4879 if (threadStatus) { 4880 int whichChoice = bundles[iThread].whichChoice; 4881 StrongInfo & choice = choices[whichChoice]; 4882 int iColumn=choice.columnNumber; 4883 if (choice.integerSolution) { 4884 double * foundSolution = choice.integerSolution; 4885 solver>setColSolution(foundSolution); 4886 // See if integer solution 4887 int numberInfeas=0; 4888 int numberOddInfeas=0; 4889 if (model>feasibleSolution(numberInfeas,numberOddInfeas) 4890 && model>problemFeasibility()>feasible(model, 1) >= 0) { 4891 double newObjectiveValue; 4892 solver>getDblParam(OsiObjOffset,newObjectiveValue); 4893 newObjectiveValue=newObjectiveValue; 4894 const double * cost = solver>getObjCoefficients(); 4895 for ( int i = 0 ; i < numberColumns ; i++ ) 4896 newObjectiveValue += cost[i] * foundSolution[i]; 4897 if (newObjectiveValue<bestSolutionValue) { 4898 if (doAtEnd) { 4899 if (!bestSolution) 4900 bestSolution = CoinCopyOfArray(foundSolution,numberColumns); 4901 else 4902 memcpy(bestSolution,foundSolution,numberColumns*sizeof(double)); 4903 bestSolutionValue=newObjectiveValue; 4904 } else { 4905 model>setBestSolution(CBC_STRONGSOL, 4906 newObjectiveValue, 4907 foundSolution) ; 4908 model>setLastHeuristic(NULL); 4909 model>incrementUsed(solver>getColSolution()); 4910 bestSolutionValue = model>getMinimizationObjValue(); 4911 } 4912 } 4913 } 4914 delete [] foundSolution; 4915 } 4916 for (int iWay=0;iWay<2;iWay++) { 4917 numberIterationsAllowed = choice.numIters[iWay]; 4918 choice.movement[iWay] = objectiveValue_; 4919 } 4920 // If objective goes above certain amount we can set bound 4921 int jInt = back[iColumn]; 4922 OsiObject * object = model>modifiableObject(jInt); 4923 CbcSimpleIntegerDynamicPseudoCost * dynamicObject = 4924 dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ; 4925 if (dynamicObject) { 4926 if (choice.numIters[0]>=0) { 4927 dynamicObject>addToSumDownCost(CoinMin(choice.movement[0],maxMovement)); 4928 dynamicObject>addToSumDownChange(choice.initialValuechoice.downUpperBound); 4929 } 4930 if (choice.numIters[1]>=0) { 4931 dynamicObject>addToSumUpCost(CoinMin(choice.movement[1],maxMovement)); 4932 dynamicObject>addToSumUpChange(choice.upLowerBoundchoice.initialValue); 4933 } 4934 } 4935 newLower[jInt] = choice.upLowerBound; 4936 if (choice.finished[0]) 4937 objLower[jInt] = choice.movement[0] + objectiveValue_; 4938 else 4939 objLower[jInt] = objectiveValue_; 4940 newUpper[jInt] = choice.downUpperBound; 4941 if (choice.finished[1]) 4942 objUpper[jInt] = choice.movement[1] + objectiveValue_; 4943 else 4944 objUpper[jInt] = objectiveValue_; 4945 objMin = CoinMin(CoinMin(objLower[jInt], objUpper[jInt]), objMin); 4946 objMovement[2*jInt]=choice.movement[0]; 4947 objMovement[2*jInt+1]=choice.movement[1]; 4948 double sumModified = choice.modified[0] + choice.modified[1] + 4949 1.0e15*(choice.sumModified[0]+choice.sumModified[1]); 4950 if (choice.numIters[0]>=0&&choice.numIters[1]>=0) 4951 sumModified *= 0.6; 4952 interAction[jInt] = sumModified; 4953 /* 4954 End of evaluation for this candidate variable. Possibilities are: 4955 * Both sides below cutoff; this variable is a candidate for branching. 4956 * Both sides infeasible or above the objective cutoff: no further action 4957 here. Break from the evaluation loop and assume the node will be purged 4958 by the caller. 4959 * One side below cutoff: Install the branch (i.e., fix the variable). Break 4960 from the evaluation loop and assume the node will be reoptimised by the 4961 caller. 4962 */ 4963 threadStatus=0; 4964 currentChoice++; 4965 numberDone++; 4966 #ifdef USE_STRONG_THREADS 4967 // say available 4968 if (numberThreads) { 4969 threadInfo.sayIdle(iThread); 4970 } 4971 #endif 4972 if (doAtEnd) 4973 continue; 4974 if (choice.movement[1] < 1.0e100) { 4975 if (choice.movement[0] < 1.0e100) { 4976 objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax); 4977 // In case solution coming in was odd 4978 choice.movement[1] = CoinMax(0.0, choice.movement[1]); 4979 choice.movement[0] = CoinMax(0.0, choice.movement[0]); 4980 // feasible  4981 model>messageHandler()>message(CBC_STRONG, *model>messagesPointer()) 4982 << iColumn << iColumn 4983 << choice.movement[0] << choice.numIntInfeas[0] 4984 << choice.movement[1] << choice.numIntInfeas[1] 4985 << choice.initialValue 4986 << CoinMessageEol; 4987 } else { 4988 // up feasible, down infeasible 4989 needResolve = true; 4990 numberToFix++; 4991 saveLower[iColumn] = choice.upLowerBound; 4992 solver>setColLower(iColumn, choice.upLowerBound); 4993 #ifdef USE_STRONG_THREADS 4994 for (int i=0;i<numberThreads;i++) { 4995 threadNeedsRefreshing[i] = 1; 4996 } 4997 #endif 4998 } 4999 } else { 5000 if (choice.movement[0] < 1.0e100) { 5001 // down feasible, up infeasible 5002 needResolve = true; 5003 numberToFix++; 5004 saveUpper[iColumn] = choice.downUpperBound; 5005 solver>setColUpper(iColumn, choice.downUpperBound); 5006 #ifdef USE_STRONG_THREADS 5007 for (int i=0;i<numberThreads;i++) { 5008 threadNeedsRefreshing[i] = 2; 5009 } 5010 #endif 5011 } else { 5012 // neither side feasible 5013 COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i, 5014 model>object(choice.objectNumber)>columnNumber())); 5015 //solver>writeMps("bad"); 5016 numberToFix = 1; 5017 break; 5018 } 5019 } 5020 if (numberIterationsAllowed <= 0) 5021 break; 5022 if (currentChoice==maxChoices) 5023 currentChoice=0; 5024 } 5025 //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn, 5026 // choice.downMovement,choice.upMovement,value); 5027 } 5028 // Do at end if deterministic 5029 if (doAtEnd) { 5030 if (bestSolution) { 5031 model>setBestSolution(CBC_STRONGSOL, 5032 bestSolutionValue, 5033 bestSolution) ; 5034 model>setLastHeuristic(NULL); 5035 model>incrementUsed(solver>getColSolution()); 5036 delete [] bestSolution; 5037 } 5038 for (int iDo = 0; iDo < numberLookIntegers; iDo++) { 5039 StrongInfo & choice = choices[iDo]; 5040 int iColumn = choice.columnNumber; 5041 int iObject = iColumn; 5042 int jInt = back[iColumn]; 5043 double value = choice.initialValue; 5044 double lowerValue = choice.downUpperBound; 5045 double upperValue = choice.upLowerBound; 5046 if (choice.movement[1] < 1.0e100) { 5047 if (choice.movement[0] < 1.0e100) { 5048 objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax); 5049 // In case solution coming in was odd 5050 choice.movement[1] = CoinMax(0.0, choice.movement[1]); 5051 choice.movement[0] = CoinMax(0.0, choice.movement[0]); 5052 // feasible  5053 model>messageHandler()>message(CBC_STRONG, *model>messagesPointer()) 5054 << iObject << iColumn 5055 << choice.movement[0] << choice.numIntInfeas[0] 5056 << choice.movement[1] << choice.numIntInfeas[1] 5057 << value 5058 << CoinMessageEol; 5059 } else { 5060 // up feasible, down infeasible 5061 numberToFix++; 5062 saveLower[iColumn] = upperValue; 5063 solver>setColLower(iColumn, upperValue); 5064 } 5065 } else { 5066 if (choice.movement[0] < 1.0e100) { 5067 // down feasible, up infeasible 5068 needResolve = true; 5069 numberToFix++; 5070 saveUpper[iColumn] = lowerValue; 5071 solver>setColUpper(iColumn, lowerValue); 5072 } else { 5073 // neither side feasible 5074 COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i, 5075 model>object(choice.objectNumber)>columnNumber())); 5076 //solver>writeMps("bad"); 5077 numberToFix = 1; 5078 break; 5079 } 5080 } 5081 } 5082 } 5083 if (false) { 3741 5084 const double * lower = solver>getColLower(); 3742 5085 const double * upper = solver>getColUpper(); 3743 const double * dj = solver>getReducedCost(); 3744 int numberObjects = model>numberObjects(); 3745 int numberColumns = model>getNumCols(); 3746 // Initialize arrays 3747 int numberIntegers = model>numberIntegers(); 3748 int * back = new int[numberColumns]; 3749 const int * integerVariable = model>integerVariable(); 3750 for (i = 0; i < numberColumns; i++) 3751 back[i] = 1; 3752 // What results is 3753 double * newLower = results; 3754 double * objLower = newLower + numberIntegers; 3755 double * newUpper = objLower + numberIntegers; 3756 double * objUpper = newUpper + numberIntegers; 3757 for (i = 0; i < numberIntegers; i++) { 3758 int iColumn = integerVariable[i]; 3759 back[iColumn] = i; 3760 newLower[i] = 0.0; 3761 objLower[i] = COIN_DBL_MAX; 3762 newUpper[i] = 0.0; 3763 objUpper[i] = COIN_DBL_MAX; 3764 } 3765 double * saveUpper = new double[numberColumns]; 3766 double * saveLower = new double[numberColumns]; 3767 // Save solution in case heuristics need good solution later 3768 3769 double * saveSolution = new double[numberColumns]; 3770 memcpy(saveSolution, solver>getColSolution(), numberColumns*sizeof(double)); 3771 model>reserveCurrentSolution(saveSolution); 3772 for (i = 0; i < numberColumns; i++) { 3773 saveLower[i] = lower[i]; 3774 saveUpper[i] = upper[i]; 3775 } 3776 // Get arrays to sort 3777 double * sort = new double[numberObjects]; 3778 int * whichObject = new int[numberObjects]; 3779 int numberToFix = 0; 3780 int numberToDo = 0; 3781 double integerTolerance = 3782 model>getDblParam(CbcModel::CbcIntegerTolerance); 3783 // point to useful information 3784 OsiBranchingInformation usefulInfo = model>usefulInformation(); 3785 // and modify 3786 usefulInfo.depth_ = depth_; 3787 3788 // compute current state 3789 int numberObjectInfeasibilities; // just odd ones 3790 int numberIntegerInfeasibilities; 3791 model>feasibleSolution( 3792 numberIntegerInfeasibilities, 3793 numberObjectInfeasibilities); 3794 # ifdef COIN_HAS_CLP 3795 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); 3796 int saveClpOptions = 0; 3797 bool fastIterations = (model>specialOptions() & 8) != 0; 3798 if (osiclp && fastIterations) { 3799 // for faster hot start 3800 saveClpOptions = osiclp>specialOptions(); 3801 osiclp>setSpecialOptions(saveClpOptions  8192); 3802 } 3803 # else 3804 bool fastIterations = false ; 3805 # endif 3806 /* 3807 Scan for branching objects that indicate infeasibility. Choose candidates 3808 using priority as the first criteria, then integer infeasibility. 3809 3810 The algorithm is to fill the array with a set of good candidates (by 3811 infeasibility) with priority bestPriority. Finding a candidate with 3812 priority better (less) than bestPriority flushes the choice array. (This 3813 serves as initialization when the first candidate is found.) 3814 3815 */ 3816 numberToDo = 0; 3817 for (i = 0; i < numberObjects; i++) { 3818 OsiObject * object = model>modifiableObject(i); 3819 CbcSimpleIntegerDynamicPseudoCost * dynamicObject = 3820 dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ; 3821 if (!dynamicObject) 3822 continue; 3823 double infeasibility = object>checkInfeasibility(&usefulInfo); 3824 int iColumn = dynamicObject>columnNumber(); 3825 if (saveUpper[iColumn] == saveLower[iColumn]) 3826 continue; 3827 if (infeasibility) 3828 sort[numberToDo] = 1.0e10  infeasibility; 3829 else 3830 sort[numberToDo] = fabs(dj[iColumn]); 3831 whichObject[numberToDo++] = i; 3832 } 3833 // Save basis 3834 CoinWarmStart * ws = solver>getWarmStart(); 3835 int saveLimit; 3836 solver>getIntParam(OsiMaxNumIterationHotStart, saveLimit); 3837 int targetIterations = CoinMax(500, numberIterationsAllowed / numberObjects); 3838 if (saveLimit < targetIterations) 3839 solver>setIntParam(OsiMaxNumIterationHotStart, targetIterations); 3840 // Mark hot start 3841 solver>markHotStart(); 3842 // Sort 3843 CoinSort_2(sort, sort + numberToDo, whichObject); 3844 double * currentSolution = model>currentSolution(); 3845 double objMin = 1.0e50; 3846 double objMax = 1.0e50; 3847 bool needResolve = false; 3848 /* 3849 Now calculate the cost forcing the variable up and down. 3850 */ 3851 int iDo; 3852 for (iDo = 0; iDo < numberToDo; iDo++) { 3853 CbcStrongInfo choice; 3854 int iObject = whichObject[iDo]; 3855 OsiObject * object = model>modifiableObject(iObject); 3856 CbcSimpleIntegerDynamicPseudoCost * dynamicObject = 3857 dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ; 3858 if (!dynamicObject) 3859 continue; 3860 int iColumn = dynamicObject>columnNumber(); 3861 int preferredWay; 3862 /* 3863 Update the information held in the object. 3864 */ 3865 object>infeasibility(&usefulInfo, preferredWay); 3866 double value = currentSolution[iColumn]; 3867 double nearest = floor(value + 0.5); 3868 double lowerValue = floor(value); 3869 bool satisfied = false; 3870 if (fabs(value  nearest) <= integerTolerance  value < saveLower[iColumn]  value > saveUpper[iColumn]) { 3871 satisfied = true; 3872 double newValue; 3873 if (nearest < saveUpper[iColumn]) { 3874 newValue = nearest + 1.0001 * integerTolerance; 3875 lowerValue = nearest; 3876 } else { 3877 newValue = nearest  1.0001 * integerTolerance; 3878 lowerValue = nearest  1; 3879 } 3880 currentSolution[iColumn] = newValue; 3881 } 3882 double upperValue = lowerValue + 1.0; 3883 //CbcSimpleInteger * obj = 3884 //dynamic_cast <CbcSimpleInteger *>(object) ; 3885 //if (obj) { 3886 //choice.possibleBranch=obj>createCbcBranch(solver,&usefulInfo,preferredWay); 3887 //} else { 3888 CbcObject * obj = 3889 dynamic_cast <CbcObject *>(object) ; 3890 assert (obj); 3891 choice.possibleBranch = obj>createCbcBranch(solver, &usefulInfo, preferredWay); 3892 //} 3893 currentSolution[iColumn] = value; 3894 // Save which object it was 3895 choice.objectNumber = iObject; 3896 choice.numIntInfeasUp = numberUnsatisfied_; 3897 choice.numIntInfeasDown = numberUnsatisfied_; 3898 choice.downMovement = 0.0; 3899 choice.upMovement = 0.0; 3900 choice.numItersDown = 0; 3901 choice.numItersUp = 0; 3902 choice.fix = 0; // say not fixed 3903 double objectiveChange ; 3904 double newObjectiveValue = 1.0e100; 3905 int j; 3906 // status is 0 finished, 1 infeasible and other 3907 int iStatus; 3908 /* 3909 Try the down direction first. (Specify the initial branching alternative as 3910 down with a call to way(1). Each subsequent call to branch() performs the 3911 specified branch and advances the branch object state to the next branch 3912 alternative.) 3913 */ 3914 choice.possibleBranch>way(1) ; 3915 choice.possibleBranch>branch() ; 3916 if (fabs(value  lowerValue) > integerTolerance) { 3917 solver>solveFromHotStart() ; 3918 /* 3919 We now have an estimate of objective degradation that we can use for strong 3920 branching. If we're over the cutoff, the variable is monotone up. 3921 If we actually made it to optimality, check for a solution, and if we have 3922 a good one, call setBestSolution to process it. Note that this may reduce the 3923 cutoff, so we check again to see if we can declare this variable monotone. 3924 */ 3925 if (solver>isProvenOptimal()) 3926 iStatus = 0; // optimal 3927 else if (solver>isIterationLimitReached() 3928 && !solver>isDualObjectiveLimitReached()) 3929 iStatus = 2; // unknown 3930 else 3931 iStatus = 1; // infeasible 3932 newObjectiveValue = solver>getObjSense() * solver>getObjValue(); 3933 choice.numItersDown = solver>getIterationCount(); 3934 numberIterationsAllowed = choice.numItersDown; 3935 objectiveChange = newObjectiveValue  objectiveValue_; 3936 if (!iStatus) { 3937 choice.finishedDown = true ; 3938 if (newObjectiveValue >= cutoff) { 3939 objectiveChange = 1.0e100; // say infeasible 3940 } else { 3941 // See if integer solution 3942 if (model>feasibleSolution(choice.numIntInfeasDown, 3943 choice.numObjInfeasDown) 3944 && model>problemFeasibility()>feasible(model, 1) >= 0) { 3945 model>setBestSolution(CBC_STRONGSOL, 3946 newObjectiveValue, 3947 solver>getColSolution()) ; 3948 model>setLastHeuristic(NULL); 3949 model>incrementUsed(solver>getColSolution()); 3950 cutoff = model>getCutoff(); 3951 if (newObjectiveValue >= cutoff) // *new* cutoff 3952 objectiveChange = 1.0e100 ; 3953 } 3954 } 3955 } else if (iStatus == 1) { 3956 objectiveChange = 1.0e100 ; 3957 } else { 3958 // Can't say much as we did not finish 3959 choice.finishedDown = false ; 3960 } 3961 choice.downMovement = objectiveChange ; 3962 } 3963 // restore bounds 3964 for ( j = 0; j < numberColumns; j++) { 3965 if (saveLower[j] != lower[j]) 3966 solver>setColLower(j, saveLower[j]); 3967 if (saveUpper[j] != upper[j]) 3968 solver>setColUpper(j, saveUpper[j]); 3969 } 3970 // repeat the whole exercise, forcing the variable up 3971 choice.possibleBranch>branch(); 3972 if (fabs(value  upperValue) > integerTolerance) { 3973 solver>solveFromHotStart() ; 3974 /* 3975 We now have an estimate of objective degradation that we can use for strong 3976 branching. If we're over the cutoff, the variable is monotone up. 3977 If we actually made it to optimality, check for a solution, and if we have 3978 a good one, call setBestSolution to process it. Note that this may reduce the 3979 cutoff, so we check again to see if we can declare this variable monotone. 3980 */ 3981 if (solver>isProvenOptimal()) 3982 iStatus = 0; // optimal 3983 else if (solver>isIterationLimitReached() 3984 && !solver>isDualObjectiveLimitReached()) 3985 iStatus = 2; // unknown 3986 else 3987 iStatus = 1; // infeasible 3988 newObjectiveValue = solver>getObjSense() * solver>getObjValue(); 3989 choice.numItersUp = solver>getIterationCount(); 3990 numberIterationsAllowed = choice.numItersUp; 3991 objectiveChange = newObjectiveValue  objectiveValue_; 3992 if (!iStatus) { 3993 choice.finishedUp = true ; 3994 if (newObjectiveValue >= cutoff) { 3995 objectiveChange = 1.0e100; // say infeasible 3996 } else { 3997 // See if integer solution 3998 if (model>feasibleSolution(choice.numIntInfeasUp, 3999 choice.numObjInfeasUp) 4000 && model>problemFeasibility()>feasible(model, 1) >= 0) { 4001 model>setBestSolution(CBC_STRONGSOL, 4002 newObjectiveValue, 4003 solver>getColSolution()) ; 4004 model>setLastHeuristic(NULL); 4005 model>incrementUsed(solver>getColSolution()); 4006 cutoff = model>getCutoff(); 4007 if (newObjectiveValue >= cutoff) // *new* cutoff 4008 objectiveChange = 1.0e100 ; 4009 } 4010 } 4011 } else if (iStatus == 1) { 4012 objectiveChange = 1.0e100 ; 4013 } else { 4014 // Can't say much as we did not finish 4015 choice.finishedUp = false ; 4016 } 4017 choice.upMovement = objectiveChange ; 4018 4019 // restore bounds 4020 for ( j = 0; j < numberColumns; j++) { 4021 if (saveLower[j] != lower[j]) 4022 solver>setColLower(j, saveLower[j]); 4023 if (saveUpper[j] != upper[j]) 4024 solver>setColUpper(j, saveUpper[j]); 4025 } 4026 } 4027 // If objective goes above certain amount we can set bound 4028 int jInt = back[iColumn]; 4029 newLower[jInt] = upperValue; 4030 if (choice.finishedDown) 4031 objLower[jInt] = choice.downMovement + objectiveValue_; 4032 else 4033 objLower[jInt] = objectiveValue_; 4034 newUpper[jInt] = lowerValue; 4035 if (choice.finishedUp) 4036 objUpper[jInt] = choice.upMovement + objectiveValue_; 4037 else 4038 objUpper[jInt] = objectiveValue_; 4039 objMin = CoinMin(CoinMin(objLower[jInt], objUpper[jInt]), objMin); 4040 /* 4041 End of evaluation for this candidate variable. Possibilities are: 4042 * Both sides below cutoff; this variable is a candidate for branching. 4043 * Both sides infeasible or above the objective cutoff: no further action 4044 here. Break from the evaluation loop and assume the node will be purged 4045 by the caller. 4046 * One side below cutoff: Install the branch (i.e., fix the variable). Break 4047 from the evaluation loop and assume the node will be reoptimised by the 4048 caller. 4049 */ 4050 if (choice.upMovement < 1.0e100) { 4051 if (choice.downMovement < 1.0e100) { 4052 objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax); 4053 // In case solution coming in was odd 4054 choice.upMovement = CoinMax(0.0, choice.upMovement); 4055 choice.downMovement = CoinMax(0.0, choice.downMovement); 4056 // feasible  4057 model>messageHandler()>message(CBC_STRONG, *model>messagesPointer()) 4058 << iObject << iColumn 4059 << choice.downMovement << choice.numIntInfeasDown 4060 << choice.upMovement << choice.numIntInfeasUp 4061 << value 4062 << CoinMessageEol; 4063 } else { 4064 // up feasible, down infeasible 4065 if (!satisfied) 4066 needResolve = true; 4067 choice.fix = 1; 4068 numberToFix++; 4069 saveLower[iColumn] = upperValue; 4070 solver>setColLower(iColumn, upperValue); 4071 } 4072 } else { 4073 if (choice.downMovement < 1.0e100) { 4074 // down feasible, up infeasible 4075 if (!satisfied) 4076 needResolve = true; 4077 choice.fix = 1; 4078 numberToFix++; 4079 saveUpper[iColumn] = lowerValue; 4080 solver>setColUpper(iColumn, lowerValue); 4081 } else { 4082 // neither side feasible 4083 COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i, 4084 model>object(choice.objectNumber)>columnNumber())); 4085 delete ws; 4086 ws = NULL; 4087 //solver>writeMps("bad"); 4088 numberToFix = 1; 4089 delete choice.possibleBranch; 4090 choice.possibleBranch = NULL; 4091 break; 4092 } 4093 } 4094 delete choice.possibleBranch; 4095 if (numberIterationsAllowed <= 0) 4096 break; 4097 //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn, 4098 // choice.downMovement,choice.upMovement,value); 4099 } 4100 COIN_DETAIL_PRINT(printf("Best possible solution %g, can fix more if solution of %g found  looked at %d variables in %d iterations\n", 4101 objMin, objMax, iDo, model>numberAnalyzeIterations()  numberIterationsAllowed)); 4102 model>setNumberAnalyzeIterations(numberIterationsAllowed); 5086 for (int i=0;i<numberColumns;i++) { 5087 if (lower[i]!=saveLower[i]upper[i]!=saveUpper[i]) { 5088 printf("%d changed saved %g,%g now %g,%g\n",i,saveLower[i],saveUpper[i], 5089 lower[i],upper[i]); 5090 } 5091 } 5092 } 5093 COIN_DETAIL_PRINT(printf("Best possible solution %g, can fix more if solution of %g found  looked at %d variables in %d iterations\n", 5094 objMin, objMax, iDo, model>numberAnalyzeIterations()  numberIterationsAllowed)); 5095 model>setNumberAnalyzeIterations(numberIterationsAllowed); 5096 if (numberToFix>0) { 5097 sprintf(general,"%d variable bounds modified by initial strong branching (%.2f seconds  %d iterations)",numberToFix,model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 5098 } else if (numberToFix<0) { 5099 sprintf(general,"initial strong branching found to be infeasible (%.2f seconds  %d iterations)",model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 5100 } else if ((solveType&32)!=0) { 5101 sprintf(general,"No variables fixed by initial strong branching (%.2f seconds  %d iterations)",model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 5102 } else { 5103 general[0]='\0'; 5104 } 5105 if (general[0]!='\0') 5106 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5107 << general 5108 << CoinMessageEol; 5109 double smallestEffect=COIN_DBL_MAX; 5110 double largestEffect=0.0; 5111 for (i = 0; i < numberIntegers; i++) { 5112 int iColumn=integerVariable[i]; 5113 if (back[iColumn]>=numberColumns) 5114 continue; 5115 smallestEffect = CoinMin(smallestEffect,interAction[i]); 5116 largestEffect = CoinMax(largestEffect,interAction[i]); 5117 } 5118 double groupValue[11]; 5119 int groupCounts[11]={0,0,0,0,0,0,0,0,0,0,0}; 5120 groupValue[10]=largestEffect; 5121 for (int i=0;i<10;i++) 5122 groupValue[i]=smallestEffect+i*0.1*(largestEffectsmallestEffect); 5123 sprintf(general,"Looked at %d integer variables  smallest interaction %g", 5124 numberLookIntegers,smallestEffect); 5125 model>messageHandler()>message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, 5126 *model>messagesPointer()) 5127 << general 5128 << CoinMessageEol; 5129 for (int i = 0; i < numberIntegers; i++) { 5130 int iColumn=integerVariable[i]; 5131 if (back[iColumn]>=numberColumns) 5132 continue; 5133 double value = interAction[i]; 5134 int j; 5135 for (j=0;j<11;j++) { 5136 if (value<=groupValue[j]j==10) 5137 break; 5138 } 5139 groupCounts[j]++; 5140 } 5141 general[0]='\0'; 5142 for (int i=0;i<11;i++) 5143 sprintf(general+strlen(general),"%d <= %g ",groupCounts[i],groupValue[i]); 5144 model>messageHandler()>message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, 5145 *model>messagesPointer()) 5146 << general 5147 << CoinMessageEol; 5148 smallestEffect=COIN_DBL_MAX; 5149 largestEffect=0.0; 5150 int numberChanged=0; 5151 int numberZeroMoved=0; 5152 for (i = 0; i < numberIntegers; i++) { 5153 int iColumn=integerVariable[i]; 5154 if (back[iColumn]>=numberColumns) 5155 continue; 5156 for (int iWay=0;iWay<2;iWay++) { 5157 double value=objMovement[2*i+iWay]; 5158 if (value<1.0e7) { 5159 numberZeroMoved++; 5160 } else if (value<1.0e50) { 5161 smallestEffect = CoinMin(smallestEffect,value); 5162 largestEffect = CoinMax(largestEffect,value); 5163 } else { 5164 numberChanged++; 5165 } 5166 } 5167 } 5168 memset(groupCounts,0,sizeof(groupCounts)); 5169 groupValue[10]=largestEffect; 5170 for (int i=0;i<10;i++) 5171 groupValue[i]=smallestEffect+i*0.1*(largestEffectsmallestEffect); 5172 sprintf(general,"Strong branching  %d bounds changed, %d zero objective changes and %d nonzero (smallest %g)", 5173 numberChanged,numberZeroMoved, 5174 2*numberLookIntegersnumberChangednumberZeroMoved,smallestEffect); 5175 model>messageHandler()>message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, 5176 *model>messagesPointer()) 5177 << general 5178 << CoinMessageEol; 5179 sprintf(general,"Breakdown "); 5180 for (i = 0; i < numberIntegers; i++) { 5181 int iColumn=integerVariable[i]; 5182 if (back[iColumn]>=numberColumns) 5183 continue; 5184 for (int iWay=0;iWay<2;iWay++) { 5185 double value = objMovement[2*i+iWay]; 5186 int j; 5187 for (j=0;j<11;j++) { 5188 if (value<=groupValue[j]j==10) 5189 break; 5190 } 5191 groupCounts[j]++; 5192 } 5193 } 5194 for (int i=0;i<11;i++) 5195 sprintf(general+strlen(general),"%d <= %g ",groupCounts[i],groupValue[i]); 5196 model>messageHandler()>message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, 5197 *model>messagesPointer()) 5198 << general 5199 << CoinMessageEol; 5200 delete [] objMovement; 5201 if ((solveType&2)==0) { 4103 5202 // Delete the snapshot 4104 5203 solver>unmarkHotStart(); 4105 // back to normal 4106 solver>setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ; 4107 solver>setIntParam(OsiMaxNumIterationHotStart, saveLimit); 4108 // restore basis 4109 solver>setWarmStart(ws); 5204 } 5205 // back to normal 5206 solver>setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ; 5207 solver>setIntParam(OsiMaxNumIterationHotStart, saveLimit); 5208 // restore basis 5209 solver>setWarmStart(ws); 5210 // skip if infeasible 5211 if (numberToFix<0) 5212 solveType=0; 5213 int numberBoundsChanged=0; 5214 if ((solveType&16)==0) { 5215 double size=numberRows; 5216 size*=numberColumns; 5217 if (size>1000000) { 5218 if ((solveType&32)!=0) 5219 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5220 << "Skipping analyze on other columns as problem too large" 5221 << CoinMessageEol; 5222 solveType &= ~2; 5223 } 5224 } 5225 if ((solveType&2)!=0) { 5226 # ifdef COIN_HAS_CLP 5227 int saveOptions = osiclp ? osiclp>specialOptions() : 0; 5228 if (osiclp) { 5229 //ClpPrimalColumnPivot * primalColumnPivot=NULL; 5230 osiclp>setSpecialOptions(saveOptions2048); // off crunch 5231 } 5232 #endif 5233 double * newLower = new double [2*numberColumns]; 5234 double * newUpper = newLower + numberColumns; 5235 // look at ints/all  should be parametrics  for now primal 5236 OsiSolverInterface * temp = solver>clone(); 5237 // add constraint 5238 int * indices = reinterpret_cast<int *>(newUpper); 5239 double * obj = newLower; 5240 memcpy(obj,solver>getObjCoefficients(),numberColumns*sizeof(double)); 5241 int n=0; 5242 for (int i=0;i<numberColumns;i++) { 5243 if (obj[i]) { 5244 indices[n]=i; 5245 obj[n++]=obj[i]; 5246 } 5247 } 5248 if (n) { 5249 double cutoff=model>getCutoff(); 5250 // relax a little bit 5251 cutoff += 1.0e4; 5252 double offset; 5253 temp>getDblParam(OsiObjOffset, offset); 5254 temp>addRow(n,indices,obj,COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset); 5255 temp>setDblParam(OsiObjOffset, 0.0); 5256 #if defined (THREADS_IN_ANALYZE) && defined (COIN_HAS_CLP) 5257 for (int iThread=0;iThread<numberThreads;iThread++) { 5258 OsiSolverInterface * solver= 5259 reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 5260 solver>addRow(n,indices,obj,COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset); 5261 } 5262 #endif 5263 } 5264 //temp>setHintParam(OsiDoDualInResolve, false, OsiHintDo) ; 5265 temp>setHintParam(OsiDoReducePrint, true, OsiHintTry); 5266 temp>setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX); 5267 temp>resolve(); 5268 { 5269 const double * lower =temp>getColLower(); 5270 const double * upper =temp>getColUpper(); 5271 for (int i=0;i<numberColumns;i++) { 5272 assert (lower[i]==saveLower[i]); 5273 assert (upper[i]==saveUpper[i]); 5274 } 5275 } 4110 5276 delete ws; 4111 4112 delete [] sort; 4113 delete [] whichObject; 4114 delete [] saveLower; 4115 delete [] saveUpper; 4116 delete [] back; 4117 // restore solution 4118 solver>setColSolution(saveSolution); 5277 ws = temp>getWarmStart(); 5278 staticInfo.ws=ws; 5279 staticInfo.newObjective = new double[2*numberColumns]; 5280 memcpy(staticInfo.newObjective,solver>getObjCoefficients(),numberColumns*sizeof(double)); 5281 memset(staticInfo.newObjective+numberColumns,0,numberColumns*sizeof(double)); 5282 #if defined (THREADS_IN_ANALYZE) && defined (COIN_HAS_CLP) 5283 for (int iThread=0;iThread<numberThreads;iThread++) { 5284 OsiSolverInterface * solver= 5285 reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 5286 solver>setObjective(newLower); 5287 solver>setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX); 5288 threadNeedsRefreshing[iThread]=3; 5289 } 5290 #endif 5291 for (int i = 0; i < numberColumns; i++) { 5292 newLower[i]=lower[i]; 5293 newUpper[i]=upper[i]; 5294 } 5295 double * thisSolution = CoinCopyOfArray(temp>getColSolution(),numberColumns); 5296 double primalTolerance; 5297 solver>getDblParam(OsiPrimalTolerance,primalTolerance); 5298 iDo=0; 5299 iDone=1; 5300 numberDone=0; 5301 int iThread=0; 5302 threadStatus=0; 5303 currentChoice=0; 5304 staticInfo.solveType=100; //mark for analyze 5305 staticInfo.originalSolution=thisSolution; 5306 whenPrint=(numberColumns+9)/10; 5307 while (numberDone<numberColumns) { 5308 if ((solveType&32)!=0&&numberDone==whenPrint) { 5309 whenPrint += (numberColumns+9)/10; 5310 sprintf(general,"%d variables looked at  %d bounds changed by secondary solves (%.2f seconds  %d iterations)",numberDone,numberBoundsChanged,model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 5311 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5312 << general 5313 << CoinMessageEol; 5314 } 5315 #ifdef USE_STRONG_THREADS 5316 if (numberThreads) { 5317 threadInfo.waitParallelTask(1,iThread,iDo<numberColumns); 5318 threadStatus = 1+threadInfo.threadInfo_[iThread].status; 5319 currentChoice=iThread; 5320 if (threadNeedsRefreshing[iThread]) { 5321 OsiSolverInterface * solver= 5322 reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 5323 if ((threadNeedsRefreshing[iThread]&1)!=0) 5324 solver>setColLower(saveLower); 5325 if ((threadNeedsRefreshing[iThread]&2)!=0) 5326 solver>setColUpper(saveUpper); 5327 threadNeedsRefreshing[iThread]=0; 5328 } 5329 } 5330 #endif 5331 if (threadStatus==0&&iDo<numberColumns) { 5332 StrongInfo & choice = choices[currentChoice]; 5333 StrongBundle & bundle = bundles[currentChoice]; 5334 bundle.whichChoice=currentChoice; 5335 memset(&choice,0,sizeof(StrongInfo)); 5336 int iColumn = iDo; 5337 iDo++; //started this one 5338 int typeSolve=0; 5339 if (thisSolution[iColumn]>newLower[iColumn]+integerTolerance) 5340 typeSolve=1; 5341 if (thisSolution[iColumn]<newUpper[iColumn]integerTolerance) 5342 typeSolve += 2; 5343 if (typeSolve&&back[iColumn]>=0) { 5344 if (thisSolution[iColumn]<newLower[iColumn]+0.9999) 5345 typeSolve &= ~1; 5346 if (thisSolution[iColumn]>newUpper[iColumn]0.9999) 5347 typeSolve &= ~2; 5348 if (temp>isBinary(iColumn)) 5349 typeSolve=0; // already done 5350 } 5351 if (typeSolve==0  newUpper[iColumn]==newLower[iColumn]) { 5352 #ifdef USE_STRONG_THREADS 5353 // say available 5354 if (numberThreads) { 5355 threadInfo.sayIdle(iThread); 5356 } 5357 #endif 5358 numberDone++; 5359 continue; 5360 } 5361 // Save which object it was 5362 choice.columnNumber = iColumn; 5363 choice.initialValue=thisSolution[iColumn]; 5364 choice.movement[0]=COIN_DBL_MAX; 5365 choice.movement[1]=COIN_DBL_MAX; 5366 choice.upLowerBound=newUpper[iColumn]; 5367 choice.downUpperBound=newLower[iColumn]; 5368 if ((typeSolve&1)==0) 5369 choice.numIters[0]=1; // mark as not done 5370 if ((typeSolve&2)==0) 5371 choice.numIters[1]=1; // mark as not done 5372 bundle.choice=&choice; 5373 bundle.solver = temp; 5374 #ifdef USE_STRONG_THREADS 5375 if (numberThreads) { 5376 bundle.solver=reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2); 5377 threadStatus=0; 5378 #ifdef DETAIL_THREAD 5379 printf("Starting task for column %d on thread %d\n", 5380 choice.columnNumber,iThread); 5381 #endif 5382 threadInfo.startParallelTask(1,iThread,&bundle); 5383 } else { 5384 #endif 5385 threadStatus=2; 5386 solveAnalyze(&bundle); 5387 #ifdef USE_STRONG_THREADS 5388 } 5389 #endif 5390 } 5391 if (threadStatus) { 5392 int whichChoice = bundles[iThread].whichChoice; 5393 StrongInfo & choice = choices[whichChoice]; 5394 int iColumn=choice.columnNumber; 5395 if(choice.modified[0]) { 5396 numberToFix = numberColumns1; 5397 } 5398 double gotLower=COIN_DBL_MAX; 5399 double gotUpper=COIN_DBL_MAX; 5400 if (choice.numIters[0]>=0) { 5401 // go down 5402 double value = choice.movement[0]; 5403 if (value>newLower[iColumn]+100.0*integerTolerance) { 5404 if (back[iColumn]>=0) 5405 value = ceil(valueintegerTolerance); 5406 else 5407 value = CoinMax(newLower[iColumn],value1.0e51.0e8*fabs(value)); 5408 if (value>newLower[iColumn]+1.0e8*(1.0+fabs(value))) { 5409 sprintf(general,"Secondary analysis solve increases lower bound on %d from %g to %g%s", 5410 iColumn,newUpper[iColumn],value,(back[iColumn]>=0) ? "(integer)" : ""); 5411 model>messageHandler()>message(CBC_FPUMP2, *model>messagesPointer()) 5412 << general 5413 << CoinMessageEol; 5414 numberBoundsChanged++; 5415 if (value>newUpper[iColumn]primalTolerance) { 5416 value=newUpper[iColumn]; 5417 if (value>newUpper[iColumn]+10.0*primalTolerance) { 5418 // infeasible 5419 numberToFix=numberColumns1; 5420 } 5421 } 5422 gotLower = value; 5423 } 5424 } 5425 } 5426 if (choice.numIters[1]>=0) { 5427 // go up 5428 double value=choice.movement[1]; 5429 if (value<newUpper[iColumn]100.0*integerTolerance) { 5430 if (back[iColumn]>=0) 5431 value = floor(value+integerTolerance); 5432 else 5433 value = CoinMin(newUpper[iColumn],value+1.0e5+1.0e8*fabs(value)); 5434 if (value<newUpper[iColumn]1.0e8*(1.0+fabs(value))) { 5435 sprintf(general,"Secondary analysis solve decreases upper bound on %d from %g to %g%s", 5436 iColumn,newUpper[iColumn],value,(back[iColumn]>=0) ? "(integer)" : ""); 5437 model>messageHandler()>message(CBC_FPUMP2, *model>messagesPointer()) 5438 << general 5439 << CoinMessageEol; 5440 numberBoundsChanged++; 5441 if (value<newLower[iColumn]+primalTolerance) { 5442 value=newLower[iColumn]; 5443 if (value<newLower[iColumn]10.0*primalTolerance) { 5444 // infeasible 5445 numberToFix=numberColumns1; 5446 } 5447 } 5448 gotUpper=value; 5449 } 5450 } 5451 } 5452 if (gotLower!=COIN_DBL_MAX) { 5453 newLower[iColumn]=gotLower; 5454 temp>setColLower(iColumn,gotLower); 5455 if (!doAtEnd) 5456 solver>setColLower(iColumn,gotLower); 5457 } 5458 if (gotUpper!=COIN_DBL_MAX) { 5459 gotUpper=CoinMax(gotUpper,newLower[iColumn]); 5460 newUpper[iColumn]=gotUpper; 5461 temp>setColUpper(iColumn,gotUpper); 5462 if (!doAtEnd) 5463 solver>setColUpper(iColumn,gotUpper); 5464 } 5465 #if 0 5466 if ((model>specialOptions()&1) != 0) { 5467 const OsiRowCutDebugger *debugger = solver>getRowCutDebugger() ; 5468 if (!debugger) { 5469 abort(); 5470 } else { 5471 printf("still ok\n"); 5472 } 5473 } 5474 #endif 5475 threadStatus=0; 5476 currentChoice++; 5477 numberDone++; 5478 for (int iWay=0;iWay<2;iWay++) { 5479 if (choice.numIters[iWay]>0) 5480 numberIterationsAllowed = choice.numIters[iWay]; 5481 } 5482 if (currentChoice==maxChoices) 5483 currentChoice=0; 5484 #ifdef USE_STRONG_THREADS 5485 // say available 5486 if (numberThreads) { 5487 threadInfo.sayIdle(iThread); 5488 } 5489 #endif 5490 } 5491 } 5492 delete [] thisSolution; 5493 delete temp; 5494 delete [] newLower; 4119 5495 # ifdef COIN_HAS_CLP 4120 if (osiclp) 4121 osiclp>setSpecialOptions(saveClpOptions); 5496 if (osiclp) { 5497 //ClpPrimalColumnPivot * primalColumnPivot=NULL; 5498 osiclp>setSpecialOptions(saveOptions); 5499 } 5500 #endif 5501 } 5502 delete [] staticInfo.newObjective; 5503 # ifdef COIN_HAS_CLP 5504 if (osiclp) { 5505 delete staticInfo.dualRowPivot; 5506 delete staticInfo.primalColumnPivot; 5507 ClpSimplex * simplex = osiclp>getModelPtr(); 5508 ClpDualRowPivot * dualRowPivot=simplex>dualRowPivot(); 5509 ClpDualRowSteepest * steep = dynamic_cast<ClpDualRowSteepest *>(dualRowPivot); 5510 if (steep) 5511 steep>setMode(3); 5512 } 5513 #endif 5514 if ((solveType&64)!=0) { 5515 OsiSolverInterface * temp = solver>clone(); 5516 int numberRows=solver>getNumRows(); 5517 int numberContinuousRows=model>numberRowsAtContinuous(); 5518 int * del = new int[numberRowsnumberContinuousRows]; 5519 for (int i=numberContinuousRows;i<numberRows;i++) 5520 del[inumberContinuousRows]=i; 5521 temp>deleteRows(numberRowsnumberContinuousRows,del); 5522 delete [] del; 5523 # ifdef COIN_HAS_CLP 5524 if (!osiclp) { 5525 #endif 5526 solver>writeMps("analyzed"); 5527 temp>writeMps("analyzed2"); 5528 # ifdef COIN_HAS_CLP 5529 } else { 5530 OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (temp); 5531 osiclp>getModelPtr()>writeMps("analyzed.mps",2,1); 5532 osiclp2>getModelPtr()>writeMps("analyzed2.mps",2,1); 5533 } 5534 #endif 5535 delete temp; 5536 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5537 << "Models saved on 'analyzed' and 'analyzed2'" 5538 << CoinMessageEol; 5539 } 5540 delete [] choices; 5541 for (int i=0;i<numberBundles;i++) { 5542 delete [] bundles[i].tempSolution; 5543 delete bundles[i].tempBasis; 5544 } 5545 delete [] bundles; 5546 #ifdef USE_STRONG_THREADS 5547 if (numberThreads) { 5548 threadInfo.waitAllTasks(); 5549 for (int i=0;i<numberThreads;i++) { 5550 delete reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[i].extraInfo2); 5551 } 5552 } 5553 #endif 5554 delete ws; 5555 5556 delete [] sort; 5557 delete [] whichObject; 5558 delete [] saveLower; 5559 delete [] saveUpper; 5560 delete [] back; 5561 // restore solution 5562 solver>setColSolution(saveSolution); 5563 # ifdef COIN_HAS_CLP 5564 if (osiclp) 5565 osiclp>setSpecialOptions(saveClpOptions); 4122 5566 # endif 4123 model>reserveCurrentSolution(saveSolution); 4124 delete [] saveSolution; 4125 if (needResolve) 4126 solver>resolve(); 5567 delete [] saveSolution; 5568 solver>resolve(); 5569 if (numberToFix<0&&!solver>isProvenOptimal()) { 5570 // infeasible 5571 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5572 << "Analysis shows problem to be infeasible" 5573 << CoinMessageEol; 4127 5574 return numberToFix; 5575 } 5576 if (numberBoundsChanged) { 5577 sprintf(general,"%d bounds changed by secondary solves (%.2f seconds  %d iterations)", 5578 numberBoundsChanged,model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 5579 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5580 << general 5581 << CoinMessageEol; 5582 } else if ((solveType&32)!=0) { 5583 sprintf(general,"No bounds changed by secondary solves (%.2f seconds  %d iterations)", 5584 model>getCurrentSeconds()time1,saveAllowednumberIterationsAllowed); 5585 model>messageHandler()>message(CBC_GENERAL, *model>messagesPointer()) 5586 << general 5587 << CoinMessageEol; 5588 } 5589 model>reserveCurrentSolution(solver>getColSolution()); 5590 if ((solveType&1)!=0) { 5591 if (groupCounts[0]*4>numberIntegers) { 5592 // change priority on this group 5593 int generalPriority=10000000; 5594 for (int i = 0; i < numberIntegers; i++) { 5595 OsiObject * object = model>modifiableObject(i); 5596 CbcSimpleInteger * integerObject = 5597 dynamic_cast <CbcSimpleInteger *>(object) ; 5598 if (!integerObject) 5599 continue; 5600 generalPriority = CoinMax(generalPriority,integerObject>priority()); 5601 } 5602 for (int i = 0; i < numberIntegers; i++) { 5603 OsiObject * object = model>modifiableObject(i); 5604 CbcSimpleInteger * integerObject = 5605 dynamic_cast <CbcSimpleInteger *>(object) ; 5606 if (!integerObject) 5607 continue; 5608 if (!interAction[i]&&integerObject>priority()==generalPriority) 5609 integerObject>setPriority(generalPriority+1); 5610 } 5611 } 5612 } 5613 return numberToFix; 4128 5614 } 4129 5615 … … 4133 5619 { 4134 5620 #ifdef CHECK_NODE 4135 printf("CbcNode % x Constructor from rhs %x\n", this, &rhs);5621 printf("CbcNode %p Constructor from rhs %p\n", this, &rhs); 4136 5622 #endif 4137 5623 if (rhs.nodeInfo_) … … 4187 5673 #ifdef CHECK_NODE 4188 5674 if (nodeInfo_) { 4189 printf("CbcNode % x Destructor nodeInfo %x(%d)\n",5675 printf("CbcNode %p Destructor nodeInfo %p (%d)\n", 4190 5676 this, nodeInfo_, nodeInfo_>numberPointingToThis()); 4191 5677 //assert(nodeInfo_>numberPointingToThis()>=0); 4192 5678 } else { 4193 printf("CbcNode % x Destructor nodeInfo %x(?)\n",5679 printf("CbcNode %p Destructor nodeInfo %p (?)\n", 4194 5680 this, nodeInfo_); 4195 5681 } … … 4206 5692 delete nodeInfo_; 4207 5693 } else { 4208 //printf("node % x nodeinfo %x parent %x\n",this,nodeInfo_,nodeInfo_>parent());5694 //printf("node %p nodeinfo %p parent %p\n",this,nodeInfo_,nodeInfo_>parent()); 4209 5695 // anyway decrement parent 4210 5696 //if (parent)
Note: See TracChangeset
for help on using the changeset viewer.