Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
pseudo_costs.h
Go to the documentation of this file.
1// Copyright 2010-2025 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
14#ifndef OR_TOOLS_SAT_PSEUDO_COSTS_H_
15#define OR_TOOLS_SAT_PSEUDO_COSTS_H_
16
17#include <limits>
18#include <string>
19#include <vector>
20
21#include "absl/log/check.h"
22#include "absl/types/span.h"
25#include "ortools/sat/integer.h"
29#include "ortools/sat/model.h"
31#include "ortools/sat/sat_parameters.pb.h"
32#include "ortools/sat/util.h"
34
35namespace operations_research {
36namespace sat {
37
38// Pseudo cost of a variable is measured as average observed change in the
39// objective bounds per unit change in the variable bounds.
41 public:
42 explicit PseudoCosts(Model* model);
43
44 // This must be called before we are about to branch.
45 // It will record the current objective bounds.
46 void BeforeTakingDecision(Literal decision);
47
48 // Updates the pseudo costs for the given decision given to
49 // BeforeTakingDecision().
50 void AfterTakingDecision(bool conflict = false);
51
52 // Advanced usage. Internal functions used by Before/AfterTakingDecision(),
53 // that are exposed for strong branching.
54 double ObjectiveIncrease(bool conflict);
55 bool SaveLpInfo();
56 void SaveBoundChanges(Literal decision, absl::Span<const double> lp_values);
57
58 // Returns the variable with best reliable pseudo cost that is not fixed.
59 IntegerVariable GetBestDecisionVar();
60
61 // Returns the pseudo cost of given variable. Currently used for testing only.
62 double GetCost(IntegerVariable var) const {
63 CHECK_LT(var, pseudo_costs_.size());
64 return pseudo_costs_[var].CurrentAverage();
65 }
66
67 // Visible for testing.
68 // Returns the number of recordings of given variable.
69 int GetNumRecords(IntegerVariable var) const {
70 CHECK_LT(var, pseudo_costs_.size());
71 return pseudo_costs_[var].NumRecords();
72 }
73
74 // Combines the score of the two branch into one score.
75 double CombineScores(double down_branch, double up_branch) const;
76
77 // Alternative pseudo-cost. This relies on the LP more heavily and is more in
78 // line with what a MIP solver would do. Returns all the info about taking a
79 // branch around the current lp_value of var.
81 bool is_fixed = false;
82 bool is_reliable = false;
83 bool is_integer = false;
84 double down_fractionality = 0.0;
85 double score = 0.0;
86 double down_score = 0.0;
87 double up_score = 0.0;
89 };
90 BranchingInfo EvaluateVar(IntegerVariable var,
91 absl::Span<const double> lp_values);
92
93 // Experimental alternative pseudo cost based on the explanation for bound
94 // increases.
95 void UpdateBoolPseudoCosts(absl::Span<const Literal> reason,
96 IntegerValue objective_increase);
97 double BoolPseudoCost(Literal lit, double lp_value) const;
98
99 // Visible for testing.
100 // Returns the bound delta associated with this decision.
102 IntegerVariable var = kNoIntegerVariable;
103 IntegerValue lower_bound_change = IntegerValue(0);
104 double lp_increase = 0.0;
105 };
106 const std::vector<VariableBoundChange>& BoundChanges() {
107 return bound_changes_;
108 }
109
110 private:
111 // Returns the current objective info.
112 struct ObjectiveInfo {
113 std::string DebugString() const;
114
115 IntegerValue lb = kMinIntegerValue;
116 IntegerValue ub = kMaxIntegerValue;
117 double lp_bound = -std::numeric_limits<double>::infinity();
118 bool lp_at_optimal = false;
119 };
120 ObjectiveInfo GetCurrentObjectiveInfo();
121
122 // Model object.
123 const SatParameters& parameters_;
124 IntegerTrail* integer_trail_;
125 IntegerEncoder* encoder_;
126 ModelLpValues* lp_values_;
127 LinearProgrammingConstraintCollection* lps_;
128 IntegerVariable objective_var_ = kNoIntegerVariable;
129
130 // Saved info by BeforeTakingDecision().
131 ObjectiveInfo saved_info_;
132 std::vector<VariableBoundChange> bound_changes_;
133
134 // Current IntegerVariable pseudo costs.
135 std::vector<IntegerVariable> relevant_variables_;
139
140 // This version is mainly based on the lp relaxation.
142 average_unit_objective_increase_;
143
144 // This version is based on objective increase explanation.
146};
147
148} // namespace sat
149} // namespace operations_research
150
151#endif // OR_TOOLS_SAT_PSEUDO_COSTS_H_
void AfterTakingDecision(bool conflict=false)
const std::vector< VariableBoundChange > & BoundChanges()
double CombineScores(double down_branch, double up_branch) const
Combines the score of the two branch into one score.
int GetNumRecords(IntegerVariable var) const
void UpdateBoolPseudoCosts(absl::Span< const Literal > reason, IntegerValue objective_increase)
void BeforeTakingDecision(Literal decision)
IntegerVariable GetBestDecisionVar()
Returns the variable with best reliable pseudo cost that is not fixed.
BranchingInfo EvaluateVar(IntegerVariable var, absl::Span< const double > lp_values)
double BoolPseudoCost(Literal lit, double lp_value) const
double ObjectiveIncrease(bool conflict)
void SaveBoundChanges(Literal decision, absl::Span< const double > lp_values)
double GetCost(IntegerVariable var) const
Returns the pseudo cost of given variable. Currently used for testing only.
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
const IntegerVariable kNoIntegerVariable(-1)
In SWIG mode, we don't want anything besides these top-level includes.