Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
2d_mandatory_overlap_propagator.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 <optional>
18#include <string>
19#include <utility>
20#include <vector>
21
22#include "absl/types/span.h"
25#include "ortools/sat/integer.h"
26#include "ortools/sat/model.h"
29
30namespace operations_research {
31namespace sat {
32
34 const int id = watcher->Register(this);
35 helper_.WatchAllBoxes(id);
36 return id;
37}
38
40 if (!VLOG_IS_ON(1)) return;
41 std::vector<std::pair<std::string, int64_t>> stats;
42 stats.push_back({"MandatoryOverlapPropagator/called_with_zero_area",
43 num_calls_zero_area_});
44 stats.push_back({"MandatoryOverlapPropagator/called_without_zero_area",
45 num_calls_nonzero_area_});
46 stats.push_back({"MandatoryOverlapPropagator/conflicts", num_conflicts_});
47
48 shared_stats_->AddStats(stats);
49}
50
52 if (!helper_.SynchronizeAndSetDirection()) return false;
53
54 mandatory_regions_.clear();
55 mandatory_regions_index_.clear();
56 bool has_zero_area_boxes = false;
57 absl::Span<const TaskTime> tasks =
58 helper_.x_helper().TaskByIncreasingNegatedStartMax();
59 for (int i = tasks.size() - 1; i >= 0; --i) {
60 const int b = tasks[i].task_index;
61 if (!helper_.IsPresent(b)) continue;
62 const ItemWithVariableSize item = helper_.GetItemWithVariableSize(b);
63 if (item.x.start_max > item.x.end_min ||
64 item.y.start_max > item.y.end_min) {
65 continue;
66 }
67 mandatory_regions_.push_back({.x_min = item.x.start_max,
68 .x_max = item.x.end_min,
69 .y_min = item.y.start_max,
70 .y_max = item.y.end_min});
71 mandatory_regions_index_.push_back(b);
72
73 if (mandatory_regions_.back().SizeX() == 0 ||
74 mandatory_regions_.back().SizeY() == 0) {
75 has_zero_area_boxes = true;
76 }
77 }
78 std::optional<std::pair<int, int>> conflict;
79 if (has_zero_area_boxes) {
80 num_calls_zero_area_++;
81 conflict = FindOneIntersectionIfPresentWithZeroArea(mandatory_regions_);
82 } else {
83 num_calls_nonzero_area_++;
84 conflict = FindOneIntersectionIfPresent(mandatory_regions_);
85 }
86
87 if (conflict.has_value()) {
88 num_conflicts_++;
89 return helper_.ReportConflictFromTwoBoxes(
90 mandatory_regions_index_[conflict->first],
91 mandatory_regions_index_[conflict->second]);
92 }
93 return true;
94}
95
97 NoOverlap2DConstraintHelper* helper, Model* model,
98 GenericLiteralWatcher* watcher, int priority) {
99 MandatoryOverlapPropagator* propagator =
100 new MandatoryOverlapPropagator(helper, model);
101 watcher->SetPropagatorPriority(propagator->RegisterWith(watcher), priority);
102 model->TakeOwnership(propagator);
103}
104
105} // namespace sat
106} // namespace operations_research
void SetPropagatorPriority(int id, int priority)
Definition integer.cc:2353
int Register(PropagatorInterface *propagator)
Registers a propagator and returns its unique ids.
Definition integer.cc:2327
std::optional< std::pair< int, int > > FindOneIntersectionIfPresent(absl::Span< const Rectangle > rectangles)
void CreateAndRegisterMandatoryOverlapPropagator(NoOverlap2DConstraintHelper *helper, Model *model, GenericLiteralWatcher *watcher, int priority)
std::optional< std::pair< int, int > > FindOneIntersectionIfPresentWithZeroArea(absl::Span< const Rectangle > rectangles)
In SWIG mode, we don't want anything besides these top-level includes.