Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
elemental_to_string.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
14#include <cstdint>
15#include <iterator>
16#include <string>
17#include <utility>
18#include <vector>
19
20#include "absl/algorithm/container.h"
21#include "absl/log/check.h"
22#include "absl/strings/escaping.h"
23#include "absl/strings/str_cat.h"
24#include "absl/strings/str_join.h"
25#include "absl/strings/string_view.h"
26#include "absl/types/span.h"
31
33namespace {
34
35// Returns a tuple of names of elements corresponding to the element ids in the
36// key. For example, if there is a variable named "x" with id 0 and a constraint
37// named "c" with id 3, then
38// GetAttrKeyNames(e, DoubleAttr2::kLinConCoef, AttrKey(0, 3))
39// returns "(x, c)".
40template <typename AttrType>
41std::string GetAttrKeyNames(const Elemental& elemental, const AttrType attr,
42 const AttrKeyFor<AttrType> key) {
43 std::vector<std::string> element_names;
44 for (int i = 0; i < GetAttrKeySize<AttrType>(); ++i) {
45 auto n = elemental.GetElementNameUntyped(GetElementTypes(attr)[i], key[i]);
46 CHECK_OK(n);
47 element_names.push_back(absl::StrCat("\"", absl::CEscape(*n), "\""));
48 }
49 return absl::StrCat("(", absl::StrJoin(element_names, ", "), ")");
50}
51
52std::vector<std::string> ElementalModelDebugString(const Elemental& elemental) {
53 std::vector<std::string> lines;
54 lines.push_back("Model:");
55 if (!elemental.model_name().empty()) {
56 lines.push_back(absl::StrCat("model_name: \"",
57 absl::CEscape(elemental.model_name()), "\""));
58 }
59 if (!elemental.primary_objective_name().empty()) {
60 lines.push_back(
61 absl::StrCat("primary_objective_name: \"",
62 absl::CEscape(elemental.primary_objective_name()), "\""));
63 }
64
65 for (ElementType e : kElements) {
66 if (elemental.NextElementId(e) == 0) {
67 continue;
68 }
69 lines.push_back(absl::StrCat("ElementType: ", e,
70 " num_elements: ", elemental.NumElements(e),
71 " next_id: ", elemental.NextElementId(e)));
72 std::vector<int64_t> elements = elemental.AllElementsUntyped(e);
73 absl::c_sort(elements);
74 for (const int64_t element_id : elements) {
75 absl::StatusOr<absl::string_view> element_name =
76 elemental.GetElementNameUntyped(e, element_id);
77 CHECK_OK(element_name); // CHECK is safe, just got from the model.
78 lines.push_back(absl::StrCat(" id: ", element_id, " name: \"",
79 absl::CEscape(*element_name), "\""));
80 }
81 }
82 AllAttrs::ForEachAttr([&elemental, &lines](const auto a) {
83 const int64_t num_non_defaults = elemental.AttrNumNonDefaults(a);
84 if (num_non_defaults == 0) {
85 return;
86 }
87 lines.push_back(
88 absl::StrCat("Attribute: ", a, " non-defaults: ", num_non_defaults));
89 auto keys = elemental.AttrNonDefaults(a);
90 absl::c_sort(keys);
91 for (const auto key : keys) {
92 lines.push_back(absl::StrCat(
93 " key: ", key,
94 " value: ", FormatAttrValue(elemental.GetAttr(a, key)),
95 " (key names: ", GetAttrKeyNames(elemental, a, key), ")"));
96 }
97 });
98 return lines;
99}
100
101std::vector<std::string> DiffDebugString(const Elemental& elemental,
102 const Diff& diff) {
103 std::vector<std::string> lines;
104 for (ElementType e : kElements) {
105 if (diff.checkpoint(e) == elemental.NextElementId(e) &&
106 diff.deleted_elements(e).empty()) {
107 continue;
108 }
109 lines.push_back(absl::StrCat("ElementType: ", e,
110 " next_id: ", elemental.NextElementId(e),
111 " checkpoint: ", diff.checkpoint(e)));
112 if (diff.deleted_elements(e).empty()) {
113 continue;
114 }
115 std::vector<int64_t> deleted_elements;
116 for (const int64_t element_id : diff.deleted_elements(e)) {
117 deleted_elements.push_back(element_id);
118 }
119 absl::c_sort(deleted_elements);
120 lines.push_back(absl::StrCat(" deleted: [",
121 absl::StrJoin(deleted_elements, ", "), "]"));
122 }
123 // NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat)
124 AllAttrs::ForEachAttr([&lines, &elemental, &diff]<typename Attr>(Attr attr) {
125 if (diff.modified_keys(attr).empty()) {
126 return;
127 }
128 std::vector<AttrKeyFor<Attr>> sorted_keys;
129 for (AttrKeyFor<Attr> key : diff.modified_keys(attr)) {
130 sorted_keys.push_back(key);
131 }
132 absl::c_sort(sorted_keys);
133 lines.push_back(absl::StrCat("Attribute: ", attr));
134 for (const auto key : sorted_keys) {
135 lines.push_back(absl::StrCat(
136 " ", key, " (names: ", GetAttrKeyNames(elemental, attr, key), ")"));
137 }
138 });
139 return lines;
140}
141
142std::string ElementalDebugString(
143 const Elemental& elemental,
144 absl::Span<const std::pair<int64_t, const Diff*>> diffs) {
145 std::vector<std::string> lines = ElementalModelDebugString(elemental);
146 for (const auto& [id, diff] : diffs) {
147 lines.push_back(absl::StrCat("Diff: ", id));
148 absl::c_move(DiffDebugString(elemental, *diff), std::back_inserter(lines));
149 }
150 return absl::StrJoin(lines, "\n");
151}
152
153} // namespace
154
155std::string Elemental::DebugString(const bool print_diffs) const {
156 std::vector<std::pair<int64_t, const Diff*>> diffs;
157 if (print_diffs) {
158 for (auto& [id, diff] : diffs_->GetAll()) {
159 diffs.push_back({id, diff});
160 }
161 }
162 // It intentional that that this function is implemented without access to the
163 // private API of elemental. This allows us to change the implementation
164 // elemental without breaking the DebugString() code.
165 return ElementalDebugString(*this, absl::MakeConstSpan(diffs));
166}
167
168} // namespace operations_research::math_opt
std::string DebugString(bool print_diffs=true) const
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
AttrKey< AttrTypeDescriptorT< AttrType >::kNumKeyElements, typename AttrTypeDescriptorT< AttrType >::Symmetry > AttrKeyFor
The type of the AttrKey for attribute type AttrType.
constexpr std::array< ElementType, GetAttrKeySize< attr >()> GetElementTypes()
std::string FormatAttrValue(const ValueType v)