生成一个集合的所有可能序列的并行算法
Parallel algorithm to produce all possible sequences of a set
在尝试生成给定字符集的所有可能字符串时,我遇到了困难。设S
为符号集。我需要处理长度为n
的S
的所有可能组合。例如,如果S={'a','b','+','-'}
和n=4
,算法应处理以下序列:
aaaa
aaab
abab
+aa-
// And all other sequences in the universe
目前我的算法是一个低效的递归算法,如下所述。我有两个问题:
- 有没有更快的算法?
- 是否有并行算法来解决这个问题?
当前实现:(简化)
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);
}
}
}
你的算法看起来已经很有效了,你没有浪费任何工作。唯一可以稍微改进的是由于递归导致的函数调用开销。但是递归是好的,因为它允许简单的并行化:
#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
线程,您可以根据您的硬件并发性进行调整。
您需要所有的排列或组合吗?从你的例子中,它似乎是组合(顺序不重要,符号可以重复),但在你的代码中,它看起来像你可能试图生成排列(猜测函数名)。组合是一个简单的以n为基数计数的问题-在这种情况下是4^4,排列将是少得多的4!但是稍微复杂一点的递归算法取决于你是否想保持字典顺序。无论哪种方式,算法都是计算机科学的基本支柱之一,并且已经被很好地覆盖了,试试其他的Q:
生成所有可能的组合
生成字符串所有可能排列的列表
你可以迭代地做。但是它不会快很多。
假设集合中的字符为数字。
'a' = 0, 'b' = 1, '+' = 2, '-' = 3
从0000开始,然后递增,直到3333。
0000年,0001年,0002年,0003年,0010年,0011年,等等…
这可以很容易地并行化。对于两个线程,让第一个线程执行从0000到1333的工作,另一个线程执行从2000到3333的工作。显然,这可以很容易地扩展到任意数量的线程。
没有什么可做的了。如果你的程序很慢,那是因为有太多的组合可以选择。通过此代码找到所有组合所需的时间线性取决于存在的组合的数量。- 有可能在Armadillo中复制MATLAB circshift方法吗
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 有可能使shared_ptr协变吗
- 有可能在信号处理程序中设置promise吗
- 如何在 C++17 STL 并行算法中处理调度?
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 是否有可能构建面向Linux和Windows的.Net Core C++ / CLI应用程序?
- 是否有可能使用debug_info获取ELF文件的源代码?
- C++,是否有可能/如何定义在.h和.cpp源文件中调用函数的类构造函数
- 有可能在C++中有类的查找表吗
- 在并行算法中使用 ranges::view::iota
- C++17 并行算法已经实现了吗?
- 是否有可能让 c++ dll 在后台运行 python 程序并让它填充向量图?如果是这样,如何?
- 向量的大小是否有可能为 1 但其中的元素数量为零?
- 是否有可能编写新的叮当声现代化规则?
- 是否有可能通过指向另一个未关联的子对象的指针来获取指向一个子对象的指针?
- 使用STL并行算法对用户有哪些限制?
- 有没有可能并行化这个for循环
- 是否有可能在OpenCL中并行运行求和计算?
- 生成一个集合的所有可能序列的并行算法