Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
combine_solutions.cc
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
15
16#include <cstdint>
17#include <memory>
18#include <optional>
19#include <string>
20#include <string_view>
21#include <vector>
22
23#include "absl/log/check.h"
24#include "absl/strings/str_cat.h"
25#include "absl/strings/string_view.h"
26#include "absl/types/span.h"
28#include "ortools/sat/model.h"
30
31namespace operations_research {
32namespace sat {
33
34bool TrySolution(const CpModelProto& model, absl::Span<const int64_t> solution,
35 absl::Span<const int64_t> new_solution,
36 absl::Span<const int64_t> base_solution,
37 std::vector<int64_t>* new_combined_solution) {
38 new_combined_solution->resize(new_solution.size());
39 for (int i = 0; i < new_solution.size(); ++i) {
40 if (new_solution[i] != base_solution[i]) {
41 // A value that changed that we patch.
42 (*new_combined_solution)[i] = new_solution[i];
43 } else {
44 (*new_combined_solution)[i] = solution[i];
45 }
46 }
47 return SolutionIsFeasible(model, *new_combined_solution);
48}
49
50std::optional<std::vector<int64_t>> FindCombinedSolution(
51 const CpModelProto& model, absl::Span<const int64_t> new_solution,
52 absl::Span<const int64_t> base_solution,
53 const SharedResponseManager* response_manager, std::string* solution_info) {
54 CHECK_EQ(new_solution.size(), base_solution.size());
55 const std::vector<
56 std::shared_ptr<const SharedSolutionRepository<int64_t>::Solution>>
57 solutions =
58 response_manager->SolutionPool().BestSolutions().GetBestNSolutions(
59 10);
60
61 for (int sol_idx = 0; sol_idx < solutions.size(); ++sol_idx) {
62 std::shared_ptr<const SharedSolutionRepository<int64_t>::Solution> s =
63 solutions[sol_idx];
64 DCHECK_EQ(s->variable_values.size(), new_solution.size());
65
66 if (s->variable_values == new_solution ||
67 s->variable_values == base_solution) {
68 continue;
69 }
70 std::vector<int64_t> new_combined_solution;
71 if (TrySolution(model, s->variable_values, new_solution, base_solution,
72 &new_combined_solution)) {
73 absl::StrAppend(solution_info, " [combined with: ",
74 std::string_view(solutions[sol_idx]->info).substr(0, 20),
75 "...]");
76 return new_combined_solution;
77 }
78 }
79 return std::nullopt;
80}
81
83 SharedResponseManager* response_manager, const CpModelProto& model_proto,
84 absl::Span<const int64_t> new_solution, absl::string_view solution_info,
86 base_solution) {
87 PushedSolutionPointers result = {nullptr, nullptr};
88 result.pushed_solution = response_manager->NewSolution(
89 new_solution, solution_info, nullptr,
90 base_solution == nullptr ? -1 : base_solution->source_id);
91 if (base_solution != nullptr) {
92 std::string combined_solution_info(solution_info);
93 std::optional<std::vector<int64_t>> combined_solution =
94 FindCombinedSolution(model_proto, new_solution,
95 base_solution->variable_values, response_manager,
96 &combined_solution_info);
97 if (combined_solution.has_value()) {
98 result.improved_solution = response_manager->NewSolution(
99 combined_solution.value(), combined_solution_info);
100 }
101 }
102 return result;
103}
104
105} // namespace sat
106} // namespace operations_research
const SharedSolutionPool & SolutionPool() const
std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > NewSolution(absl::Span< const int64_t > solution_values, absl::string_view solution_info, Model *model=nullptr, int source_id=-1)
const SharedSolutionRepository< int64_t > & BestSolutions() const
std::vector< std::shared_ptr< const Solution > > GetBestNSolutions(int n) const
bool TrySolution(const CpModelProto &model, absl::Span< const int64_t > solution, absl::Span< const int64_t > new_solution, absl::Span< const int64_t > base_solution, std::vector< int64_t > *new_combined_solution)
bool SolutionIsFeasible(const CpModelProto &model, absl::Span< const int64_t > variable_values, const CpModelProto *mapping_proto, const std::vector< int > *postsolve_mapping)
PushedSolutionPointers PushAndMaybeCombineSolution(SharedResponseManager *response_manager, const CpModelProto &model_proto, absl::Span< const int64_t > new_solution, absl::string_view solution_info, std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > base_solution)
std::optional< std::vector< int64_t > > FindCombinedSolution(const CpModelProto &model, absl::Span< const int64_t > new_solution, absl::Span< const int64_t > base_solution, const SharedResponseManager *response_manager, std::string *solution_info)
OR-Tools root namespace.
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > improved_solution
std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > pushed_solution