使用并行性来解决Java

时间:2015-05-01 09:55:27

标签: java multithreading recursion

我正在尝试优化一个过程,即计算所有可能的玩家组合以形成分区。为了解我的问题,我使用以下示例。例如,我们有一组玩家N = {1,2,3,4,5} ,这个玩家会像{1,2},{3,4},{5}一样重新组合。这意味着palyer 1将作为单个玩家与玩家2一起玩,所以一个玩家。每组玩家都有一套策略或选择。每个玩家选择他想要归属的组,例如: 小组{1,2}有这些可能性{{1,2};{1,2,3,4}};即球员{1,2}他们选择留在一起或加入小组{3,4}。 对其他球员的解释相同:

{3,4}=>{{3,4};{3,4,5};{1,2,3,4}}
{5}=>{{5};{3,4,5}}

现在,选择相同策略的玩家组将形成一个新组(联盟)。例如,小组{1,2}选择了策略{1,2,3,4};即。球员{1,2}希望与球员{3,4}组成一个新的球队。玩家{3,4}选择策略{3,4,5},玩家{5}选择策略{3,4,5}。玩家选择相同的策略将组合在一起,在最终形成一个像这样的玩家分区:{1,2},{3,4,5};玩家3,4,5选择了相同的策略,所以他们组合在一起,玩家{1,2}选择不同的策略让你独自留下。我们对玩家策略的所有可能组合做同样的事情,以获得基数= K的所有可能的玩家分区。在最后,我必须选择玩家的最佳分区。在前面的示例中:我必须只生成基数= 2的分区:     | {1,2,3,4},{5} | = 2     | {1,2} {3,4,5} | = 3 此分区不可接受:|{1,2}{3,4}{5}|=3 我已经将这个过程编程为一个递归函数,以获得所有允许的玩家分区。这里的另一个问题是我的函数生成了所有可能的分区,而且我只获得了多次允许的允许值!

现在我的问题是,是否可以在java中使用并行性来计算玩家的所有可允许分区,特别是当我们有很多玩家和很多分区时。我必须做些什么来加速大问题的执行?

 import static java.util.Arrays.asList;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 public class Test {
 @SafeVarargs
 static <T> Set<T> set(T ... elems) {
  return new HashSet<T>(asList(elems));
 }
 static <T> List<Set<Set<T>>> calcPartitions(List<T> teams, Map<T,    List<Set<T>>> team2Strategies, int k, boolean doParallel) {
if(k == 0) {
  if(teams.isEmpty()) return asList(new HashSet<>());
  else return new ArrayList<>();
} else if(teams.isEmpty()) {
  return new ArrayList<>();
}

Set<T> teamsSet = new HashSet<>(teams);

T team = teams.get(0);
Stream<Set<T>> strategies = 
  (doParallel ? team2Strategies.get(team).parallelStream() : team2Strategies.get(team).stream())
    .filter(strategy ->
      strategy.stream().allMatch(team2 ->
        teamsSet.contains(team2) && team2Strategies.get(team2).contains(strategy)));
  return strategies.flatMap(strategy -> {
    List<T> newTeams = new ArrayList<>(teams);
    newTeams.removeAll(strategy);
    List<Set<Set<T>>> restPartitions = calcPartitions(newTeams, team2Strategies, k - 1, false);
    for(Set<Set<T>> partition: restPartitions) {
      partition.add(strategy);
    }
    return restPartitions.stream();
  })
  .collect(Collectors.toList());
}

public static void main(String[] args) {
List<Set<Integer>> teams = asList(set(0,1,2), set(3,4), set(5),set(6,7,8),set(9,10,11),set(12,13,14));

Map<Set<Integer>, List<Set<Set<Integer>>>> team2Strategies = new HashMap<>();

team2Strategies.put(set(0,1,2), asList(set(set(0,1, 2)),
                                     set(set(0,1, 2), set(3, 4))));
team2Strategies.put(set(3,4), asList(set(set(3, 4), set(5)),
                                     set(set(0,1, 2), set(3, 4))));
team2Strategies.put(set(5), asList(set(set(5)),
                                   set(set(3, 4), set(5)),set(set(5),set(6,7,8)),set(set(5),set(6,7,8),set(9,10,11),set(12,13,14))));


team2Strategies.put(set(6,7,8), asList(set(set(6,7,8)),
        set(set(6, 7,8), set(5)),set(set(5),set(6,7,8),set(9,10,11),set(12,13,14))));

team2Strategies.put(set(9,10,11), asList(set(set(9,10,11)),
        set(set(9, 10,11), set(12,13,14)),set(set(5),set(6,7,8),set(9,10,11),set(12,13,14))));

team2Strategies.put(set(12,13,14), asList(set(set(12,13,14)),
        set(set(12, 13,14), set(9,10,11)),set(set(5),set(6,7,8),set(9,10,11),set(12,13,14))));
List<Set<Set<Set<Integer>>>> partitions = calcPartitions(teams,   team2Strategies, 3, true);

  Comparator<List<Integer>> intListComparator = (a, b) -> {
  int i = 0;
  while(i < a.size() && i < b.size()) {
    if(a.get(i) > b.get(i)) return 1;
    else if(a.get(i) < b.get(i)) return -1;
    i++;
  }
  return a.size() - b.size();
};

//in "partitions" a strategy was a Set<Set<Integer>>
//in "partitionsList" however a strategy is a List<Integer>
List<List<List<Integer>>> partitionsList =
  partitions.stream().map(partition ->
    partition.stream().map(strategy ->
      strategy.stream().flatMap(Set::stream)
                       .sorted()
                       .collect(Collectors.toList()))
    .sorted(intListComparator).collect(Collectors.toList()))
  .collect(Collectors.toList());

System.out.println(partitionsList);

System.out.println(
  partitionsList.stream().map(partition ->
    partition.stream().map(strategy ->
      strategy.stream().map(i -> i.toString()).collect(Collectors.joining(", ", "{", "}")))
    .collect(Collectors.joining()))
  .collect(Collectors.joining("\n")));
 }
}

0 个答案:

没有答案