首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举唯一无向路径的有效方法

枚举唯一无向路径的有效方法
EN

Stack Overflow用户
提问于 2020-08-17 05:35:13
回答 1查看 59关注 0票数 1

给定节点的子集,{1,2,...,N}是否有任何STLboost函数返回所有节点上唯一的无定向导游?

std::next_permutation()提供所有的N!定向旅游,其中1-2-...-NN-N-1-...-2-1不同。

然而,在这种情况下,我不想两者都要,而只是其中之一。本质上,我只想列举旅游的N! / 2

下面使用std::next_permutation()unordered_set的代码可以工作,但是还有什么更有效的吗?下面的代码实质上生成所有的N!有向导游,并在对照unordered_set()检查后丢弃其中的一半。

代码语言:javascript
复制
#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) )不应被枚举,因为它们的反向序列已经被枚举。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-17 06:08:12

如果您想继续使用next_permutation而不是创建自己的生成器例程,最简单的方法是在某些条件下过滤掉一半的排列。

非常简单的一个:最后一个元素应该比第一个元素大。

代码语言:javascript
复制
#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 

可能自行执行:

代码语言:javascript
复制
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  
...
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63445072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档