如何解决枚举唯一的无向路径的有效方法
给定节点{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,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,3}
,我只想列举(1-2-3)
,(1-3-2)
和(2-1-3)
。其他三个排列(2-3-1)
,(3-1-2)
和(3-2-1)
不应枚举,因为它们的反向顺序已被枚举。
解决方法
如果您想继续使用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
...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。