[英]Combinatorics algorithm parallelization
I'm writing the program which is calculates C(n, k) combinations and have big difference between n and k (eg n=39, k=13 -> 8122425444 combinations). 我正在编写计算C(n,k)组合并且在n和k之间有很大差异的程序(例如n = 39,k = 13-> 8122425444组合)。 Also, I need to make some calculations with every combination in realtime. 另外,我需要实时对每种组合进行一些计算。 The question is how can I divide my algorithm to several threads to make it faster? 问题是如何将算法划分为多个线程以使其更快?
public void getCombinations(List<Item> items) {
int n = items.size();
int k = 13;
int[] res = new int[k];
for (int i = 1; i <= k; i++) {
res[i - 1] = i;
}
int p = k;
while (p >= 1) {
//here I make a Set from items in List by ids in res[]
Set<Item> cards = convert(res, items);
//some calculations
if (res[k - 1] == n) {
p--;
} else {
p = k;
}
if (p >= 1) {
for (int i = k; i >= p; i--) {
res[i - 1] = res[p - 1] + i - p + 1;
}
}
}
}
private Set<Item> convert(int[] res, List<Item> items) {
Set<Item> set = new TreeSet<Item>();
for (int i : res) {
set.add(items.get(i - 1));
}
return set;
}
If you're using JDK 7 then you could use fork/join to divide and conquer this algorithm. 如果您使用的是JDK 7,则可以使用fork / join划分并征服此算法。
If you want to keep things simple then I would just get a thread to compute a subset of the input and use a CountDownLatch until all threads have completed. 如果您想保持简单,那么我只需要一个线程来计算输入的子集,并使用CountDownLatch直到所有线程都完成。 The number of threads depends on your CPU. 线程数取决于您的CPU。
You could also use Hadoop's map/reduce if you think the input will grow so you can compute on several computers. 如果您认为输入会增加,那么您也可以使用Hadoop的map / reduce,以便可以在多台计算机上进行计算。 You will need to normalise it as a map/reduce operation - but look at examples. 您将需要将其规范化为映射/归约操作-但请查看示例。
I have been working on some code that works with combinatoric sets of this size. 我一直在研究一些可用于这种大小的组合集的代码。 Here are a few suggestions for getting output in a reasonable amount of time. 以下是在合理的时间内获得输出的一些建议。
The simplest way to split combinations is to have combinations of combinations. 拆分组合的最简单方法是拥有组合的组合。 ;) ;)
For each possible "first" value you can create a new task in a thread pool. 对于每个可能的“第一个”值,您都可以在线程池中创建一个新任务。 Or you can create each possible pair of "first" and "second" in as a new task. 或者,您可以在新任务中创建每个“第一”和“第二”对。 or three etc. You only need to create as many tasks as you have cpus, so you don't need to go over board. 或三个等。您只需要创建cpus,就可以创建尽可能多的任务,因此您无需费力。
eg say you want to create all possible selections of 13 from 39 items. 例如,说您想从39个项目中创建13个所有可能的选择。
for(Item item: items) {
List<Item> items2 = new ArrayList<Item>(items);
items2.remove(item);
// create a task which considers all selections of 12 from 38 (plus item)
createCombinationsOf(item, item2, 12);
}
This creates roughly equal work for 39 cpus which may be more than enough. 这为39 cpus创建了大致相等的功,这可能绰绰有余。 If you want more create pairs (39*38/2) of those. 如果您要创建更多(39 * 38/2)对。
Your question is quite vague. 您的问题很模糊。
What problem are you having right now? 您现在有什么问题? Implementing the divide and conquer part of the algorithm (threading, joining, etc), or figuring out how to divide a problem into it's sub-parts. 实现算法的分而治之部分(线程,连接等),或者弄清楚如何将问题分为子部分。
The later should be your first step. 稍后应该是您的第一步。 Do you know how to break your original problem into several smaller problems (that can then be dispatched to Executor threads or a similar mechanism to be processed), and how to join the results? 您知道如何将最初的问题分解为几个较小的问题(然后可以将其分发到Executor线程或类似的机制进行处理),以及如何将结果结合在一起?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.