Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
capacity_model.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 <algorithm>
17#include <limits>
18#include <numeric>
19#include <vector>
20
21#include "absl/log/check.h"
22#include "absl/log/log.h"
25
26namespace operations_research {
27void CapacityModel::AddTerm(SubsetIndex subset, ElementIndex element,
28 CapacityWeight weight) {
29 subsets_.push_back(subset);
30 elements_.push_back(element);
31 weights_.push_back(weight);
32
33 CHECK_EQ(elements_.size(), subsets_.size());
34 CHECK_EQ(elements_.size(), weights_.size());
35}
36
38 CHECK_NE(min_capacity, std::numeric_limits<CapacityWeight>::max());
39 min_capacity_ = min_capacity;
40}
41
43 CHECK_NE(max_capacity, std::numeric_limits<CapacityWeight>::min());
44 max_capacity_ = max_capacity;
45}
46
48 if (weights_.empty()) {
49 // A sum of zero terms is zero.
50 return min_capacity_ <= 0.0 && max_capacity_ >= 0.0;
51 }
52
53 // Compute the minimum and maximum constraint activations.
54 CapacityWeight min_activation = 0.0;
55 CapacityWeight max_activation = 0.0;
56 for (const CapacityWeight weight : weights_) {
57 if (weight < 0.0) {
58 min_activation += weight;
59 } else {
60 max_activation += weight;
61 }
62 }
63
64 DVLOG(1) << "[Capacity constraint] Activation bounds: [" << min_activation
65 << ", " << max_activation << "]";
66 DVLOG(1) << "[Capacity constraint] Capacity bounds: [" << min_capacity_
67 << ", " << max_capacity_ << "]";
68 return min_activation <= max_capacity_ && max_activation >= min_capacity_;
69}
70
71std::vector<CapacityTermIndex> CapacityModel::CanonicalIndexing() {
72 std::vector<CapacityTermIndex> idx(num_terms());
73 std::iota(idx.begin(), idx.end(), CapacityTermIndex(0));
74 // TODO(user): use RadixSort when it's available. The implementation in
75 // radix_sort.h does not support a lambda for comparing.
76 std::sort(idx.begin(), idx.end(),
77 [&](CapacityTermIndex lhs, CapacityTermIndex rhs) -> bool {
78 return subsets_[lhs] < subsets_[rhs]
79 ? true
80 : elements_[lhs] < elements_[rhs];
81 });
82 return idx;
83}
84
85CapacityConstraintProto CapacityModel::ExportModelAsProto() {
86 CapacityConstraintProto proto;
87 proto.set_min_capacity(min_capacity_);
88 proto.set_max_capacity(max_capacity_);
89
90 CapacityConstraintProto::CapacityTerm* current_term = nullptr;
91
92 for (CapacityTermIndex i : CanonicalIndexing()) {
93 if (current_term == nullptr ||
94 current_term->subset() != subsets_[i].value()) {
95 current_term = proto.add_capacity_term();
96 current_term->set_subset(subsets_[i].value());
97 }
98 DCHECK(current_term != nullptr);
99
100 CapacityConstraintProto::CapacityTerm::ElementWeightPair* pair =
101 current_term->add_element_weights();
102 pair->set_element(elements_[i].value());
103 pair->set_weight(weights_[i]);
104 }
105
106 return proto;
107}
108
109void CapacityModel::ImportModelFromProto(const CapacityConstraintProto& proto) {
110 elements_.clear();
111 subsets_.clear();
112 weights_.clear();
113
114 SetMinimumCapacity(proto.min_capacity());
115 SetMaximumCapacity(proto.max_capacity());
116
117 ReserveNumTerms(proto.capacity_term_size());
118 for (const CapacityConstraintProto::CapacityTerm& term :
119 proto.capacity_term()) {
120 for (const CapacityConstraintProto::CapacityTerm::ElementWeightPair& pair :
121 term.element_weights()) {
122 AddTerm(SubsetIndex(term.subset()), ElementIndex(pair.element()),
123 pair.weight());
124 }
125 }
126}
127} // namespace operations_research
CapacityConstraintProto ExportModelAsProto()
BaseInt num_terms() const
Returns the current number of terms in the constraint.
void ImportModelFromProto(const CapacityConstraintProto &proto)
Imports the model from a CapacityConstraintProto.
void SetMaximumCapacity(CapacityWeight max_capacity)
void ReserveNumTerms(BaseInt num_terms)
Reserves num_terms terms in the model.
void SetMinimumCapacity(CapacityWeight min_capacity)
void AddTerm(SubsetIndex subset, ElementIndex element, CapacityWeight weight)
Adds a new term to the constraint.
In SWIG mode, we don't want anything besides these top-level includes.
int64_t CapacityWeight
Basic type for weights. For now, the same as Cost for the set covering.