14#ifndef OR_TOOLS_SAT_CIRCUIT_H_
15#define OR_TOOLS_SAT_CIRCUIT_H_
22#include "absl/container/btree_set.h"
23#include "absl/container/flat_hash_map.h"
57 const std::vector<int>& heads,
58 const std::vector<Literal>& literals,
Options options,
72 void AddArc(
int tail,
int head, LiteralIndex literal_index);
77 void FillReasonForPath(
int start_node,
std::vector<
Literal>* reason) const;
90 std::vector<LiteralIndex> self_arcs_;
98 std::vector<Literal> watch_index_to_literal_;
102 std::vector<int> next_;
103 std::vector<int> prev_;
104 std::vector<LiteralIndex> next_literal_;
108 std::vector<int> level_ends_;
109 std::vector<Arc> added_arcs_;
113 int rev_must_be_in_cycle_size_ = 0;
114 std::vector<int> must_be_in_cycle_;
117 std::vector<bool> processed_;
118 std::vector<bool> in_current_path_;
125 const std::vector<int>& heads,
126 const std::vector<Literal>& literals,
Model*
model);
135 const int num_nodes_;
140 std::vector<Literal> watch_index_to_literal_;
141 std::vector<std::vector<std::pair<int, int>>> watch_index_to_arcs_;
145 std::vector<std::vector<int>> graph_;
146 std::vector<std::vector<Literal>> graph_literals_;
152 std::vector<std::vector<int>> components_;
154 std::vector<std::vector<int>>>
158 std::vector<int> level_ends_;
159 std::vector<int> touched_nodes_;
176 const std::vector<int>& distinguished_nodes,
188 void FillFixedPathInReason(
int start,
int end, std::vector<Literal>* reason);
191 const std::vector<std::vector<Literal>> graph_;
192 const int num_nodes_;
193 std::vector<bool> node_is_distinguished_;
197 std::vector<std::pair<int, int>> watch_index_to_arc_;
198 std::vector<std::pair<int, int>> fixed_arcs_;
199 std::vector<int> level_ends_;
202 std::vector<int> next_;
203 std::vector<int> prev_;
204 std::vector<bool> visited_;
209template <
class IntContainer>
211 absl::flat_hash_map<int, int>* mapping_output =
nullptr) {
212 const int num_arcs = tails->size();
213 if (num_arcs == 0)
return 0;
216 absl::btree_set<int>
nodes;
217 for (
int arc = 0;
arc < num_arcs; ++
arc) {
224 absl::flat_hash_map<int, int> mapping;
225 for (
const int node :
nodes) {
226 mapping[node] = new_index++;
230 for (
int arc = 0;
arc < num_arcs; ++
arc) {
231 (*tails)[
arc] = mapping[(*tails)[
arc]];
232 (*heads)[
arc] = mapping[(*heads)[
arc]];
235 if (mapping_output !=
nullptr) {
236 *mapping_output = std::move(mapping);
250 const std::vector<int>& heads,
251 const std::vector<Literal>& literals,
253 bool multiple_subcircuit_through_zero =
false);
257 const std::vector<std::vector<Literal>>&
graph);
259 const std::vector<std::vector<Literal>>&
graph,
260 const std::vector<int>& distinguished_nodes);
CircuitCoveringPropagator(std::vector< std::vector< Literal > > graph, const std::vector< int > &distinguished_nodes, Model *model)
void RegisterWith(GenericLiteralWatcher *watcher)
void SetLevel(int level) final
bool IncrementalPropagate(const std::vector< int > &watch_indices) final
void RegisterWith(GenericLiteralWatcher *watcher)
bool IncrementalPropagate(const std::vector< int > &watch_indices) final
void SetLevel(int level) final
CircuitPropagator(int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, Options options, Model *model)
CircuitPropagator & operator=(const CircuitPropagator &)=delete
CircuitPropagator(const CircuitPropagator &)=delete
This type is neither copyable nor movable.
Enforce the fact that there is no cycle in the given directed graph.
NoCyclePropagator(int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, Model *model)
bool IncrementalPropagate(const std::vector< int > &watch_indices) final
void SetLevel(int level) final
Base class for CP like propagators.
std::function< void(Model *)> CircuitCovering(const std::vector< std::vector< Literal > > &graph, const std::vector< int > &distinguished_nodes)
void LoadSubcircuitConstraint(int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, Model *model, bool multiple_subcircuit_through_zero)
int ReindexArcs(IntContainer *tails, IntContainer *heads, absl::flat_hash_map< int, int > *mapping_output=nullptr)
std::function< void(Model *)> ExactlyOnePerRowAndPerColumn(const std::vector< std::vector< Literal > > &graph)
In SWIG mode, we don't want anything besides these top-level includes.
std::optional< int64_t > end
bool multiple_subcircuit_through_zero