给定节点的子集,{1,2,...,N}是否有任何STL或boost函数返回所有节点上唯一的无定向导游?
std::next_permutation()提供所有的N!定向旅游,其中1-2-...-N与N-N-1-...-2-1不同。
然而,在这种情况下,我不想两者都要,而只是其中之一。本质上,我只想列举旅游的N! / 2。
下面使用std::next_permutation()和unordered_set的代码可以工作,但是还有什么更有效的吗?下面的代码实质上生成所有的N!有向导游,并在对照unordered_set()检查后丢弃其中的一半。
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <boost/functional/hash.hpp>
template <typename T, typename U> bool unorderedset_val_there_already_add_if_not(std::unordered_set<T, U>& uos, T& val) {
if (uos.find(val) != uos.end())
return true;//val already there
uos.insert(val);
return false;//Value is new.
}
int main() {
std::vector<int> sequence{ 1, 2, 3};
std::unordered_set<std::vector<int>, boost::hash<std::vector<int>>> uos;
do {
printf("Considering ");
for (std::size_t i = 0; i < sequence.size(); i++)
printf("%d ", sequence[i]);
printf("\n");
std::vector<int> rev_sequence = sequence;
std::reverse(rev_sequence.begin(), rev_sequence.end());
if (unorderedset_val_there_already_add_if_not(uos, sequence) || unorderedset_val_there_already_add_if_not(uos, rev_sequence)) {
printf("Already there by itself or its reverse.\n");
}
else {
printf("Sequence and its reverse are new.\n");
}
} while (std::next_permutation(sequence.begin(), sequence.end()));
getchar();
}也就是说,给定{1,2,3},我只想枚举(1-2-3)、(1-3-2)和(2-1-3)。其他三种排列( (2-3-1)、(3-1-2)和(3-2-1) )不应被枚举,因为它们的反向序列已经被枚举。
发布于 2020-08-17 06:08:12
如果您想继续使用next_permutation而不是创建自己的生成器例程,最简单的方法是在某些条件下过滤掉一半的排列。
非常简单的一个:最后一个元素应该比第一个元素大。
#include <vector>
#include <algorithm>
#include "stdio.h"
int main() {
std::vector<int> sequence{ 1, 2, 3, 4};
do {
if (sequence[sequence.size()-1] > sequence[0]) {
for (std::size_t i = 0; i < sequence.size(); i++)
printf("%d ", sequence[i]);
printf("\n");
}
} while (std::next_permutation(sequence.begin(), sequence.end()));
getchar();
}
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 4 1 3
3 1 2 4
3 2 1 4 可能自行执行:
Generate all pairs (start; end) where start < end
Generate all permutations of `n-2` values without start and end
For every permutation make {start, permutation.., end}
1 ... 2 + permutations of {3, 4}
1 3 4 2
1 4 3 2
1 ... 3 + permutations of {2,4}
1 2 4 3
1 4 2 3
...
3 ... 4 + permutations of {1, 2}
3 1 2 4
3 2 1 4
...https://stackoverflow.com/questions/63445072
复制相似问题