Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
gap.cc
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <cmath>
17#include <limits>
18
20
21constexpr double kInf = std::numeric_limits<double>::infinity();
22
23double WorstGLPKDualBound(const bool is_maximize, const double objective_value,
24 const double relative_gap_limit) {
25 // With:
26 // |best_objective_value − best_dual_bound|
27 // gap := ----------------------------------------
28 // |best_objective_value| + DBL_EPSILON
29 //
30 // When gap = relative_gap_limit:
31 //
32 // |best_objective_value − best_dual_bound|
33 // relative_gap_limit = ----------------------------------------
34 // |best_objective_value| + DBL_EPSILON
35 //
36 // Thus if we define:
37 //
38 // delta := relative_gap_limit * (|best_objective_value| + DBL_EPSILON)
39 //
40 // By definition:
41 // - if we are maximizing: best_objective_value <= best_dual_bound
42 // - if we are minimizing: best_dual_bound <= best_objective_value
43 //
44 // As a consequence:
45 // - if we are maximizing:
46 //
47 // best_dual_bound = best_objective_value + delta
48 //
49 // - if we are minimizing:
50 //
51 // best_dual_bound = best_objective_value - delta
52 //
53 // Note that DBL_EPSILON is std::numeric_limits<double>::epsilon().
54 if (std::isnan(objective_value)) {
55 return objective_value;
56 }
57 // Note that -kInf and NaN are handled below with std::fmax().
58 if (relative_gap_limit == kInf) {
59 return is_maximize ? kInf : -kInf;
60 }
61 if (!std::isfinite(objective_value)) {
62 return objective_value;
63 }
64 // Note that std::fmax() treats NaN as missing value.
65 const double non_negative_relative_gap_limit =
66 std::fmax(0.0, relative_gap_limit);
67 const double delta =
68 non_negative_relative_gap_limit *
69 (std::abs(objective_value) + std::numeric_limits<double>::epsilon());
70 // Note that delta can overflow, leading to infinite values. This is OK though
71 // as objective_value is finite; hence objective_value +/- delta will return
72 // the corresponding infinite.
73 return objective_value + (is_maximize ? 1.0 : -1.0) * delta;
74}
75
76} // namespace operations_research::math_opt
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
double WorstGLPKDualBound(const bool is_maximize, const double objective_value, const double relative_gap_limit)
Definition gap.cc:23
int64_t delta
Definition resource.cc:1709
double objective_value
The value objective_vector^T * (solution - center_point).