我正在研究一种用于解决一种拼图的强力算法。 这个谜题是一个矩形,由于某些原因在这里无关紧要,矩形的大小为宽*高的可能解的数量是2 ^(min(width,height))而不是2 ^(width * height)。 两个尺寸都可以被认为是在1..50的范围内。 (尽管通常低于30) 这样,解决方案的数量最差为2 ^ 50(约为1 000 000 000 000 000)。我将解决方案存储为无符号64位数,一种"种子"
我有两个工作的algortihms用于强力解决。 假设N是min(width,height)并且isCorrect(uint64_t)是一个谓词,它返回给定种子的解是否正确。
最天真的算法大致如下:
vector<uint64_t> solutions;
for (uint64_t i = 0; i < (1 << N); ++i)
{
if (isCorrect(i))
solutions.push_back(i);
}
它完美地工作(假设谓词实际上是实现的:D)但是没有从多个核心中获利,所以我想要采用多线程方法。 我遇到过QtConcurrent,它提供了并发的过滤器和映射函数,可以自动创建最佳线程数来分担负担。
所以我有一个新算法大致如下:
vector<unit64_t> solutionsToTry;
solutionsToTry.reserve(1 << N);
for (uint64_t i = 0; i < (1 << N); ++i)
solutionsToTry.push_back(i);
//Now, filtering
QFuture<unit64_t> solutions = QtConcurrent::filtered(solutionsToTry, &isCorrect);
它确实有效,而且速度更快,但是当N高于20时,我的RAM中没有足够的空间来分配vecotr(N = 20和64位numbes,我需要8 ,3 GB的RAM。交换分区等没关系,但是每当N增加1时它就会乘以2,它就不能再进一步了)
是否有一种简单的方法可以在不增加内存的情况下进行并发过滤?
如果没有,我可能宁愿手动拆分4个线程上的循环以获得没有最佳大小的并发,或者在Haskell中编写算法以获得惰性评估和过滤无限列表: - )