78#ifndef OR_TOOLS_UTIL_PERMUTATION_H_
79#define OR_TOOLS_UTIL_PERMUTATION_H_
87template <
typename IndexType>
100 IndexType destination)
const = 0;
114 virtual void SetSeen(IndexType* unused_permutation_element)
const {
115 LOG(FATAL) <<
"Base implementation of SetSeen() must not be called.";
125 virtual bool Unseen(IndexType unused_permutation_element)
const {
126 LOG(FATAL) <<
"Base implementation of Unseen() must not be called.";
141template <
typename DataType,
typename IndexType>
152 IndexType destination)
const override {
153 data_[destination] = data_[source];
156 data_[destination] = temp_;
158 void SetSeen(IndexType* permutation_element)
const override {
159 *permutation_element = -*permutation_element - 1;
161 bool Unseen(IndexType permutation_element)
const override {
162 return permutation_element >= 0;
176template <
typename IndexType>
180 : cycle_handler_(cycle_handler) {}
186 void Apply(IndexType permutation[],
int permutation_start,
187 int permutation_end) {
188 for (IndexType current = permutation_start; current < permutation_end;
190 IndexType
next = permutation[current];
192 const IndexType cycle_start = current;
193 if (cycle_handler_->Unseen(
next)) {
194 cycle_handler_->SetSeen(&permutation[current]);
195 DCHECK(!cycle_handler_->Unseen(permutation[current]));
196 cycle_handler_->SetTempFromIndex(current);
197 while (cycle_handler_->Unseen(permutation[
next])) {
198 cycle_handler_->SetIndexFromIndex(
next, current);
201 cycle_handler_->SetSeen(&permutation[current]);
202 DCHECK(!cycle_handler_->Unseen(permutation[current]));
204 cycle_handler_->SetIndexFromTemp(current);
208 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.