77#ifndef OR_TOOLS_UTIL_PERMUTATION_H_
78#define OR_TOOLS_UTIL_PERMUTATION_H_
86template <
typename IndexType>
99 IndexType destination)
const = 0;
113 virtual void SetSeen(IndexType* unused_permutation_element)
const {
114 LOG(FATAL) <<
"Base implementation of SetSeen() must not be called.";
124 virtual bool Unseen(IndexType unused_permutation_element)
const {
125 LOG(FATAL) <<
"Base implementation of Unseen() must not be called.";
140template <
typename DataType,
typename IndexType>
151 IndexType destination)
const override {
152 data_[destination] = data_[source];
155 data_[destination] = temp_;
157 void SetSeen(IndexType* permutation_element)
const override {
158 *permutation_element = -*permutation_element - 1;
160 bool Unseen(IndexType permutation_element)
const override {
161 return permutation_element >= 0;
175template <
typename IndexType>
179 : cycle_handler_(cycle_handler) {}
185 void Apply(IndexType permutation[],
int permutation_start,
186 int permutation_end) {
187 for (IndexType current = permutation_start; current < permutation_end;
189 IndexType next = permutation[current];
191 const IndexType cycle_start = current;
192 if (cycle_handler_->Unseen(next)) {
193 cycle_handler_->SetSeen(&permutation[current]);
194 DCHECK(!cycle_handler_->Unseen(permutation[current]));
195 cycle_handler_->SetTempFromIndex(current);
196 while (cycle_handler_->Unseen(permutation[next])) {
197 cycle_handler_->SetIndexFromIndex(next, current);
199 next = permutation[next];
200 cycle_handler_->SetSeen(&permutation[current]);
201 DCHECK(!cycle_handler_->Unseen(permutation[current]));
203 cycle_handler_->SetIndexFromTemp(current);
207 DCHECK_EQ(cycle_start, current);
void SetTempFromIndex(IndexType source) override
ArrayIndexCycleHandler(const ArrayIndexCycleHandler &)=delete
This type is neither copyable nor movable.
ArrayIndexCycleHandler & operator=(const ArrayIndexCycleHandler &)=delete
bool Unseen(IndexType permutation_element) const override
void SetSeen(IndexType *permutation_element) const override
void SetIndexFromTemp(IndexType destination) const override
Sets a data element from the temporary.
ArrayIndexCycleHandler(DataType *data)
void SetIndexFromIndex(IndexType source, IndexType destination) const override
Moves a data element one step along its cycle.
PermutationApplier(const PermutationApplier &)=delete
This type is neither copyable nor movable.
PermutationApplier & operator=(const PermutationApplier &)=delete
PermutationApplier(PermutationCycleHandler< IndexType > *cycle_handler)
void Apply(IndexType permutation[], int permutation_start, int permutation_end)
virtual void SetIndexFromTemp(IndexType destination) const =0
Sets a data element from the temporary.
PermutationCycleHandler(const PermutationCycleHandler &)=delete
This type is neither copyable nor movable.
PermutationCycleHandler & operator=(const PermutationCycleHandler &)=delete
virtual ~PermutationCycleHandler()
PermutationCycleHandler()
virtual bool Unseen(IndexType unused_permutation_element) const
virtual void SetTempFromIndex(IndexType source)=0
virtual void SetIndexFromIndex(IndexType source, IndexType destination) const =0
Moves a data element one step along its cycle.
virtual void SetSeen(IndexType *unused_permutation_element) const
In SWIG mode, we don't want anything besides these top-level includes.