絕對是。
並行化這些排列問題的一個大問題是,爲了很好地並行化,您需要「索引」爲任意排列。總之,你需要找到第k個排列。您可以利用一些很酷的數學性質的,你會發現這一點:
std::vector<int> kth_perm(long long k, std::vector<int> V) {
long long int index;
long long int next;
std::vector<int> new_v;
while(V.size()) {
index = k/fact(V.size() - 1);
new_v.push_back(V.at(index));
next = k % fact(V.size() - 1);
V.erase(V.begin() + index);
k = next;
}
return new_v;
}
所以,那麼你的邏輯可能是這個樣子:
long long int start = (numperms*threadnum)/ numthreads;
long long int end = threadnum == numthreads-1 ? numperms : (numperms*(threadnum+1))/numthreads;
perm = kth_perm(start, perm); // perm is your list of permutations
for (int j = start; j < end; ++j){
if (is_valid_tour(adj_list, perm, startingVertex, endingVertex)) {
isValidTour=true;
return perm;
}
std::next_permutation(perm.begin(),perm.end());
}
isValidTour = false;
return perm;
顯然有很多的代碼,但這個想法並行化它可以通過我發佈的小代碼捕獲。你可以想像「索引」是這樣的:
|--------------------------------|
^ ^ ^
t1 t2 ... tn
查找第i個置換,並讓一個線程調用std::next_permutation
直到找到下一個線程的起點。
注意,你會想換一個包含#pragma omp parallel
非常感謝!現在它工作得很完美,我從你的和@erip的回答中學到了更多關於OpenMP的知識,而不是在我的Uni上長達1.5小時的講座。 – Siemko