我在java中设计了一个算法我生成了列表元素的所有组合。例如,元素[A, B , C]
生成组合,[A]
,[B]
,[C]
,[AB]
,[BC]
,[ABC]
。或者基于元素[A, A, B]
生成组合[A]
,[B]
,[AA]
,[AB]
,[AAB]
。
这是我生成组合的代码。
private List<Elemento> combinazioneMassima = new ArrayList<>();
private Log logger = LogFactory.getLog(Combinazioni3.class);
public Combinazioni3(List<Elemento> generaCombinazioneMassima) {
this.combinazioneMassima = generaCombinazioneMassima;
}
public void combine() {
this.findAllCombinations(combinazioneMassima);
}
private static class Node{
int lastIndex = 0;
List<Elemento> currentList;
public Node(int lastIndex, List<Elemento> list) {
this.lastIndex = lastIndex;
this.currentList = list;
}
public Node(Node n) {
this.lastIndex = n.lastIndex;
this.currentList = new ArrayList<Elemento>(n.currentList);
}
}
public void findAllCombinations(List<Elemento> combinazioni) {
Date dataInizio = new Date();
List<List<Elemento>> resultList = new ArrayList<List<Elemento>>();
LinkedList<Node> queue = new LinkedList<Node>();
int n = combinazioni.size();
ArrayList<Elemento> temp = new ArrayList<Elemento>();
temp.add(combinazioni.get(0));
queue.add(new Node(0, temp));
// add all different integers to the queue once.
for(int i=1;i<n;++i) {
if(combinazioni.get(i-1) == combinazioni.get(i)) continue;
temp = new ArrayList<Elemento>();
temp.add(combinazioni.get(i));
queue.add(new Node(i, temp));
}
// do bfs until we have no elements
while(!queue.isEmpty()) {
Node node = queue.remove();
if(node.lastIndex+1 < n) {
Node newNode = new Node(node);
newNode.lastIndex = node.lastIndex+1;
newNode.currentList.add(combinazioni.get(node.lastIndex+1));
queue.add(newNode);
}
for(int i=node.lastIndex+2;i<n;++i) {
if(combinazioni.get(i-1) == combinazioni.get(i)) continue;
// create a copy and add extra integer
Node newNode = new Node(node);
newNode.lastIndex = i;
newNode.currentList.add(combinazioni.get(i));
queue.add(newNode);
}
GestoreRegole gestoreRegole = new GestoreRegole();
gestoreRegole.esegui(node.currentList);
}
}
但是对于input > 250
,程序会停止并且花费太长时间才能完成所有组合。
我该如何改进这个解决方案?或者有更好的解决方案吗?
答案 0 :(得分:3)
对于input = 250,会有如此多的组合: 看看这个例子:
(1) {a} => {a}
(3) {a,b} => {a}, {b}, {a,b}
(7) {a,b,c} => {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, {a,b,c}
如您所见,将有2 ^ n-1个元素
因此输入= 250 - 2 ^ 250-1 = large number(1.8 * 10 ^ 75)
使用了太多内存。我认为大约20(1048575)的数字也会造成麻烦
答案 1 :(得分:1)
这是我告诉你的基本想法。我只插入几个关键点。您应该将此附加到您最熟悉的代码中。
public void findnThCombination(List<Elemento> combinazioni, int n) {
...
int counter_combinations = 0;
// add all different integers to the queue once.
for(int i=1;i<n;++i) {
if(combinazioni.get(i-1) == combinazioni.get(i)) continue;
temp = new ArrayList<Elemento>();
temp.add(combinazioni.get(i));
queue.add(new Node(i, temp));
}
counter_combinations ++;
// do bfs until we have no elements
while(!queue.isEmpty()) {
//when you add a new combination
counter_combinations++;
if(counter_combinations == n) //return this combination
}}
我希望这会有所帮助。