Skip to content

Commit d0ce461

Browse files
Add golden ratio search
1 parent 750b43e commit d0ce461

File tree

4 files changed

+80
-24
lines changed

4 files changed

+80
-24
lines changed

src/Enums.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,12 @@ enum class ES_PrimalNLPStrategy
372372
IterationOrTimeAndAllFeasibleSolutions
373373
};
374374

375+
enum class ES_ReductionCutStrategy
376+
{
377+
Fraction,
378+
GoldenSection
379+
};
380+
375381
enum class ES_ReformulationBinaryMonomials
376382
{
377383
None,

src/Solver.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -896,15 +896,28 @@ void Solver::initializeSettings()
896896
"These settings control the added dual reduction cuts from the primal solution that will try to force a better "
897897
"primal solution. This functionality is only used if SHOT cannot deduce that the problem is nonconvex .");
898898

899+
env->settings->createSetting(
900+
"ReductionCut.Use", "Dual", true, "Enable the dual reduction cut strategy for nonconvex problems");
901+
902+
VectorString enumReductionCutStrategy;
903+
enumReductionCutStrategy.push_back("Fraction");
904+
enumReductionCutStrategy.push_back("GoldenSection");
905+
906+
ES_ReductionCutStrategy reductionCutStrategy;
907+
908+
reductionCutStrategy = ES_ReductionCutStrategy::Fraction;
909+
910+
env->settings->createSetting("ReductionCut.Strategy", "Dual", static_cast<int>(reductionCutStrategy),
911+
"The reduction cut strategy to use", enumReductionCutStrategy,
912+
static_cast<int>(ES_ReductionCutStrategy::Fraction));
913+
enumMIPSolver.clear();
914+
899915
env->settings->createSetting("ReductionCut.MaxIterations", "Dual", 5,
900916
"Max number of primal cut reduction without primal improvement", 0, SHOT_INT_MAX);
901917

902918
env->settings->createSetting(
903919
"ReductionCut.ReductionFactor", "Dual", 0.001, "The factor used to reduce the cutoff value", 0, 1.0);
904920

905-
env->settings->createSetting(
906-
"ReductionCut.Use", "Dual", true, "Enable the dual reduction cut strategy for nonconvex problems");
907-
908921
// Dual strategy settings: Relaxation strategies
909922

910923
env->settings->createSettingGroup("Dual", "Relaxation", "Relaxation strategies",

src/Tasks/TaskAddPrimalReductionCut.cpp

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -72,42 +72,78 @@ void TaskAddPrimalReductionCut::run()
7272
return;
7373
}
7474

75-
double relativeGap = env->results->getRelativeCurrentObjectiveGap();
75+
double cutOffToUse;
7676

77-
// Different logic if gap is large
78-
if(relativeGap <= 1.0 && relativeGap > 0.1)
77+
if(env->settings->getSetting<int>("ReductionCut.Strategy", "Dual") == (int)ES_ReductionCutStrategy::Fraction)
7978
{
80-
double factor
81-
= ((double)env->solutionStatistics.numberOfPrimalReductionCutsUpdatesWithoutEffect) / (maxIterations + 1.0);
79+
double relativeGap = env->results->getRelativeCurrentObjectiveGap();
8280

83-
env->dualSolver->cutOffToUse
84-
= factor * env->results->currentDualBound + (1 - factor) * env->results->currentPrimalBound;
85-
86-
if(env->reformulatedProblem->objectiveFunction->properties.isMinimize)
81+
// Different logic if gap is large
82+
if(relativeGap <= 1.0 && relativeGap > 0.1)
8783
{
88-
env->results->currentDualBound = SHOT_DBL_MIN;
84+
double factor = ((double)env->solutionStatistics.numberOfPrimalReductionCutsUpdatesWithoutEffect)
85+
/ (maxIterations + 1.0);
86+
87+
cutOffToUse = factor * env->results->currentDualBound + (1 - factor) * env->results->currentPrimalBound;
8988
}
9089
else
9190
{
92-
env->results->currentDualBound = SHOT_DBL_MAX;
91+
double reductionFactor = env->settings->getSetting<double>("ReductionCut.ReductionFactor", "Dual");
92+
93+
if(env->reformulatedProblem->objectiveFunction->properties.isMinimize)
94+
{
95+
cutOffToUse = env->dualSolver->cutOffToUse - reductionFactor * std::abs(env->dualSolver->cutOffToUse);
96+
}
97+
else
98+
{
99+
cutOffToUse = env->dualSolver->cutOffToUse + reductionFactor * std::abs(env->dualSolver->cutOffToUse);
100+
}
93101
}
94102
}
95-
else
103+
else if(env->settings->getSetting<int>("ReductionCut.Strategy", "Dual")
104+
== (int)ES_ReductionCutStrategy::GoldenSection)
96105
{
97-
double reductionFactor = env->settings->getSetting<double>("ReductionCut.ReductionFactor", "Dual");
106+
double factor = 0.618;
98107

99-
if(env->reformulatedProblem->objectiveFunction->properties.isMinimize)
108+
// If first cut iteration after PB update
109+
if(env->solutionStatistics.numberOfPrimalReductionCutsUpdatesWithoutEffect == 0)
100110
{
101-
env->dualSolver->cutOffToUse
102-
= env->dualSolver->cutOffToUse - reductionFactor * std::abs(env->dualSolver->cutOffToUse);
103-
env->results->currentDualBound = SHOT_DBL_MIN;
111+
if(env->reformulatedProblem->objectiveFunction->properties.isMinimize)
112+
{
113+
currentLowerBoundForReductionCut = std::max(SHOT_DBL_MIN, env->results->globalDualBound);
114+
}
115+
else
116+
{
117+
currentLowerBoundForReductionCut = std::min(SHOT_DBL_MAX, env->results->globalDualBound);
118+
}
104119
}
105-
else
120+
121+
cutOffToUse = (1 - factor) * currentLowerBoundForReductionCut + factor * env->results->currentPrimalBound;
122+
123+
std::cout << " Cut off diff: " << std::abs(currentLowerBoundForReductionCut - cutOffToUse) << std::endl;
124+
if(std::abs(currentLowerBoundForReductionCut - cutOffToUse) < 1e-4)
106125
{
107-
env->dualSolver->cutOffToUse
108-
= env->dualSolver->cutOffToUse + reductionFactor * std::abs(env->dualSolver->cutOffToUse);
109-
env->results->currentDualBound = SHOT_DBL_MAX;
126+
env->tasks->setNextTask(taskIDIfFalse);
127+
return;
110128
}
129+
130+
currentLowerBoundForReductionCut = cutOffToUse;
131+
std::cout << " Cut off to use: " << cutOffToUse << std::endl;
132+
std::cout << " Primal improv. after repair: "
133+
<< env->solutionStatistics.numberOfPrimalImprovementsAfterInfeasibilityRepair << std::endl;
134+
std::cout << " Primal improv. after red. cut: "
135+
<< env->solutionStatistics.numberOfPrimalImprovementsAfterReductionCut << std::endl;
136+
}
137+
138+
env->dualSolver->cutOffToUse = cutOffToUse;
139+
140+
if(env->reformulatedProblem->objectiveFunction->properties.isMinimize)
141+
{
142+
env->results->currentDualBound = SHOT_DBL_MIN;
143+
}
144+
else
145+
{
146+
env->results->currentDualBound = SHOT_DBL_MAX;
111147
}
112148

113149
std::stringstream tmpType;

src/Tasks/TaskAddPrimalReductionCut.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ class TaskAddPrimalReductionCut : public TaskBase
2727
std::string taskIDIfTrue;
2828
std::string taskIDIfFalse;
2929
int totalReductionCutUpdates = 0;
30+
double currentLowerBoundForReductionCut = SHOT_DBL_INF;
3031
};
3132
} // namespace SHOT

0 commit comments

Comments
 (0)