我似乎遇到了使用回溯实现功率集算法的问题。我想要实现的是相当简单,生成任何给定数字的幂集: 防爆。 [1 2 3] => [1] [2] [3]; [1,2] [1,3] [2,3]; [1,2,3]
我的算法使用堆栈来放置数字,它将数字添加到堆栈并发送它们进行计算。代码如下:
public int calculatePowerSet(int x, LinkedList<Integer> arr)
{
int size = 1;
int nrOfTimes=0;
int calculate =0;
boolean goOn=true;
Stack<Integer> stack = new Stack<Integer>();
int k=0, len = arr.size();
double temp=0.0f;
while(size<=len)
{
goOn=true;
stack.push(arr.get(0));
k = arr.indexOf(stack.peek());
temp = size; //ignore these as they are for calculating time
temp/=len; //ignore these as they are for calculating time
temp*=100; //ignore these as they are for calculating time
setPowerSetPrecentage((int)temp);
while(goOn)
{
if(isStopProcess())return 0;
if((k==len)&&(stack.size()==0)) goOn=false;
else if(stack.size()==size)
{
String sign = "";
if((stack.size()%2)==0) sign="+";
else sign="-";
calculate =calculateSets(stack.toArray(), sign, calculate, x);
k = arr.indexOf(stack.pop())+1;
}
else if(k==len)
k = arr.indexOf(stack.pop())+1;
else
{
prepereStack(stack,arr.get(k));
k++;
}
}
size++;
}
return calculate;
}
这是计算方法:
private int calculate(int[] arr2, int x)
{
int calc=1;
float rez = 0;
for(int i=0;i<arr2.length;i++)
calc*=arr2[i];
rez = (float)(x/calc);
calc = (int) (rez+0.5d);
return calc;
}
代码似乎对20以下的所有数字都有效,但在此之后我似乎得到了错误的结果。我无法手动检查数字,因为有数百种组合。例如,对于25个数字的一个输入,我应该得到1229的结果,而不是我得到1249.我不知道我错过了什么,因为我认为算法应该在理论上工作,所以如果有人有任何建议会很好
答案 0 :(得分:0)
我建议从计算中分离掉电源组的生成。虽然有一些非常有效的算法用于生成功率集,但我建议在需要效率之前保持它非常简单。
private void forEachSet(List<Integer> currentSet, List<Integer> rest) {
if (rest.isEmpty()) {
process(currentSet);
} else {
Integer nextInt = rest.remove(0);
forEachSet(currentSet, rest);
currentSet.add(nextInt);
forEachSet(currentSet, rest);
current.remove(nextInt);
rest.add(nextInt);
}
}
public forEachSet(List<Integer> set) {
forEachSet(new ArrayList<>(), new ArrayList<>(set));
}