当我解决子集和问题或"P = NP“时,使用下面的代码需要5分钟。我真的很想知道,如果我使用.parallelStream,它会快得多。但是,我不知道如何转换代码。
public class MainActivity {
final static Integer[] POPS = {8897109, 12828837, 9461105, 6371773, 5965343, 5946800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279833, 3095313, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411};
final static int TOTAL = 100000000;
/**
* @param args
*/
public static void main(String[] args) {
Combinations c = new Combinations(POPS, TOTAL);
c.chooser();
}}
import java.util.ArrayList;
import org.paukov.combinatorics.Factory;
import org.paukov.combinatorics.Generator;
import org.paukov.combinatorics.ICombinatoricsVector;
public class Combinations {
private Integer[] POPS;
private int TOTAL;
public combinations(Integer[] pops, int total){
this.POPS = pops;
this.TOTAL = total;
}
public void chooser(){
for(int i = 1; i<=POPS.length; i++){
System.out.println(i);
ICombinatoricsVector<Integer> initialVector = Factory.createVector(POPS);
Generator<Integer> gen = Factory.createSimpleCombinationGenerator(initialVector, i);
for (ICombinatoricsVector<Integer> combination : gen) {
String temp = combination.toString();
int size = temp.indexOf("size");
temp = temp.substring(22, size-3);
int sum = Adder(temp);
if (sum == TOTAL){
System.out.println(temp);
}
}
}
}
public int adder(String combos){
int total = 0;
String[] parts = combos.split(", ");
ArrayList<Integer> nums = new ArrayList<>();
for(int i = 0; i<parts.length; i++){
nums.add(Integer.parseInt(parts[i]));
}
for(int temp : nums){
total += temp;
}
return total;
}
}这是去掉字符串内容的代码。现在只需要15秒。我意识到.parallelStream()不会大大减少它的时间,但是有人至少还能给我一些关于如何做的提示吗?
import java.util.ArrayList;
import java.util.List;
import org.paukov.combinatorics.Factory;
import org.paukov.combinatorics.Generator;
import org.paukov.combinatorics.ICombinatoricsVector;
public class Combinations {
private Integer[] POPS;
private int TOTAL;
public Combinations(Integer[] pops, int total){
this.POPS = pops;
this.TOTAL = total;
}
public void chooser(){
for(int i = 1; i<=POPS.length; i++){
System.out.println(i);
ICombinatoricsVector<Integer> initialVector = Factory.createVector(POPS);
Generator<Integer> gen = Factory.createSimpleCombinationGenerator(initialVector, i);
for (ICombinatoricsVector<Integer> combination : gen) {
List<Integer> temp = combination.getVector();
int sum = adder(temp);
if (sum == TOTAL){
System.out.println(temp);
}
}
}
}
public int adder(List<Integer> combos){
int total = 0;
for(Integer temp : combos){
total+=temp;
}
return total;
}
}发布于 2014-08-20 21:26:13
它在我的机箱上运行速度是我的三倍(i7-2600带有超线程,8个虚拟内核):
public class Combinations {
private Integer[] POPS;
private int TOTAL;
public Combinations(Integer[] pops, int total) {
this.POPS = pops;
this.TOTAL = total;
}
public void chooser() {
ICombinatoricsVector<Integer> initialVector = Factory.createVector(POPS);
IntStream.range(1, POPS.length + 1).parallel()
.peek(System.out::println)
.mapToObj(i -> Factory.createSimpleCombinationGenerator(initialVector, i))
.flatMap(gen -> genToStream(gen, false)
.map(ICombinatoricsVector::getVector)
.filter(v -> adder(v) == TOTAL))
.forEach(System.out::println);
}
public static int adder(Iterable<Integer> combos) {
int total = 0;
for (Integer temp : combos) {
total += temp;
}
return total;
}
public static <E> Stream<ICombinatoricsVector<E>> genToStream(Generator<E> gen, boolean parallel) {
return StreamSupport.stream(Spliterators.spliterator(gen.iterator(),
gen.getNumberOfGeneratedObjects(), Spliterator.ORDERED), parallel);
}
}这将使用并行流作为外部循环,规则流用于内环,并且避免使用流来对列表进行求和(为了速度)。您可以使用genToStream(gen, true)来尝试并行的内部流,但是我没有看到任何速度上的差异。
另外,如果您想要匹配的List<List<Integer>>,只需将forEach行更改为.collect(Collectors.toList());即可。
https://stackoverflow.com/questions/25367847
复制相似问题