簡體   English   中英

產生一組所有可能序列的並行算法

[英]Parallel algorithm to produce all possible sequences of a set

我在嘗試產生給定字符集的所有可能字符串時遇到了困難。 S為符號集。 我需要處理長度為nS所有可能組合。 例如,如果S={'a','b','+','-'}n=4則算法應處理以下序列:

aaaa
aaab
abab
+aa-
// And all other sequences in the universe

當前,我的算法是下面描述的非有效遞歸算法。 我有兩個問題:

  1. 有更快的算法嗎?
  2. 是否有並行算法可以解決此問題?

當前實施:(簡體)

void workhorse(vector<char> &input, vector<char>::iterator i)
{
    if(i==inputs.end()) {
        // process the input
        return;
    }
    else {
        for( const auto& symbol : S) {
            *i=symbol;
            workhorse(input, i+1);
        }
    }
}   

您是否需要所有排列或組合? 在您的示例中,看起來好像是組合(順序無關緊要,可以重復符號),但是在您的代碼中,看起來您可能正在嘗試生成置換(通過函數名進行猜測)。 組合是簡單的以n為底數的問題-在這種情況下為4 ^ 4,而排列數要少得多4! 但是稍微復雜一點的遞歸算法,取決於您是否要保留字典順序。 無論哪種方法,算法都是計算機科學的基本支柱之一,並且已經被廣泛介紹,請嘗試以下其他Q:

生成所有可能的組合

生成字符串的所有可能排列的列表

您的算法看起來已經非常高效,您不會浪費任何工作。 唯一可以稍微改善的是由於遞歸導致的函數調用開銷。 但是遞歸是好的,因為它允許簡單的並行化:

#include <thread>
#include <array>
#include <string>
#include <vector>
using namespace std;

array<char,3> S = {{ 'a', 'b', 'c' }};
const int split_depth = 2;
void workhorse(string& result, int i) {
    if (i == result.size()) {
        // process the input
        return;
    }
    if (i == split_depth) {
        vector<thread> threads;
        for (char symbol : S) {
            result[i] = symbol;
            threads.emplace_back([=] {
                string cpy(result);
                workhorse(cpy, i + 1);
            });
        }
        for (thread& t: threads) t.join();
    } else {
        for (char symbol : S) {
            result[i] = symbol;
            workhorse(result, i + 1);
        }
    }
}

int main() {
    string res(6, 0);
    workhorse(res, 0);
}

確保使用C ++ 11功能進行編譯並啟用線程,例如

$ g++ -O3 -std=c++11 -lpthread [file].cpp

此版本的函數將枚舉長度最大為split_depth所有前綴,然后生成一個線程以進一步處理每個前綴。 因此,它將總共啟動|S|^split_depth線程,您可以對其進行調整以匹配您的硬件並發性。

您可以迭代地進行。 但這不會更快。

想象一下集合中的字符是數字。

'a'= 0,'b'= 1,'+'= 2,'-'= 3

您從0000開始,然后遞增直到3333。

0000、0001、0002、0003、0010、0011等...

這很容易並行化。 對於兩個線程,讓第一個線程執行從0000到1333的工作,而另一個線程執行從2000到3333的工作。顯然,這可以輕松擴展到任意數量的線程。

沒什么可做的了。 如果您的程序運行緩慢,那是因為有太多的組合可供選擇。 通過此代碼線性查找所有組合所需的時間取決於存在的組合數量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM