简体   繁体   English

生成具有顺序约束的所有排列

[英]Generating all permutations with order constraints

I'm trying to implement a code in c++ that solves the following problem: Given a natural number n, and m pairs of natural numbers between 1 and n, generate (print in the console) all the permutations from 1 to n such that the first element of each pair appears before the second element in the permutation.我正在尝试用 C++ 实现一个代码来解决以下问题:给定一个自然数 n,以及 1 和 n 之间的 m 对自然数,生成(在控制台中打印)从 1 到 n 的所有排列,使得每对的第一个元素出现在排列中的第二个元素之前。

The code I've written so far is a simple backtracking algorithm that I have adapted from the standard algorithm for generating all permutations from 1 to n.到目前为止,我编写的代码是一个简单的回溯算法,我从标准算法改编而来,用于生成从 1 到 n 的所有排列。

In the following code, M is a matrix such that the row M[j] contains all numbers such that j must go before them, and N is a matrix such that N[j] contains all the numbers such that j must go after them.在下面的代码中,M 是一个矩阵,使得行 M[j] 包含所有使得 j 必须在它们之前的数字,而 N 是一个矩阵,使得 N[j] 包含所有使得 j 必须在它们之后的数字. Also, the "used" vector keeps track of the elements that I've already used.此外,“使用过的”向量会跟踪我已经使用过的元素。

void f(int i){
if (i == n) return print();

if (i == 0){
    for (int j = 0; j < n; ++j){
      V[i] = j;
      used[j] = 1;
      f(i+1);
      used[j] = 0;
    }
}

else {
    for (int j = 0; j < n; ++j){

    bool aux = true;
    int k = 0;
    while (aux and k < M[j].size()){
        if (used[M[j][k]]) aux = false;
        ++k;
    }
    k = 0;
    while (aux and k < N[j].size()){
        if (not used[N[j][k]]) aux = false;
        ++k;
    }

    if (aux){
        if (not used[j]){
            V[i] = j;
            used[j] = 1;
            f(i+1);
            used[j] = 0;
        }
    }

}
}

The problem is this code is too slow.问题是这段代码太慢了。 So I'm asking you guys if you know any way to make it faster.所以我问你们是否知道有什么方法可以让它更快。

What about this?那这个呢?

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <functional>
#include <iterator>


using namespace std;

int main()
{
    vector<pair<int,int>> m={{1,2},{4,3}};
    vector<int> arr={1,2,3,4,5};

    do
    {
        if (all_of(m.begin(),m.end(),[&](pair<int,int>& p)
            {
                auto it1 = find(arr.begin(),arr.end(),p.first);
                auto it2 = find(arr.begin(),arr.end(),p.second);
                return (it1 != arr.end() && it2 != arr.end() && it1 <= it2);
            }))
        {
            for(auto it: arr)
                cout<<it<<" ";
            cout<<endl;
        }
    }while(std::next_permutation(arr.begin(),arr.end()));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM