【发布时间】:2013-03-29 09:33:26
【问题描述】:
我刚开始在大学学习Backtracking 算法。不知何故,我设法为子集和问题制作了一个程序。工作正常,但后来我发现我的程序并没有给出所有可能的组合。
例如:目标总和可能有一百个组合,但我的程序只给出 30 个。 这是代码。如果有人能指出我的错误是什么,那将是一个很大的帮助。
int tot=0;//tot is the total sum of all the numbers in the set.
int prob[500], d, s[100], top = -1, n; // n = number of elements in the set. prob[i] is the array with the set.
void subset()
{
int i=0,sum=0; //sum - being updated at every iteration and check if it matches 'd'
while(i<n)
{
if((sum+prob[i] <= d)&&(prob[i] <= d))
{
s[++top] = i;
sum+=prob[i];
}
if(sum == d) // d is the target sum
{
show(); // this function just displays the integer array 's'
top = -1; // top points to the recent number added to the int array 's'
i = s[top+1];
sum = 0;
}
i++;
while(i == n && top!=-1)
{
sum-=prob[s[top]];
i = s[top--]+1;
}
}
}
int main()
{
cout<<"Enter number of elements : ";cin>>n;
cout<<"Enter required sum : ";cin>>d;
cout<<"Enter SET :\n";
for(int i=0;i<n;i++)
{
cin>>prob[i];
tot+=prob[i];
}
if(d <= tot)
{
subset();
}
return 0;
}
当我运行程序时:
Enter number of elements : 7
Enter the required sum : 12
Enter SET :
4 3 2 6 8 12 21
SOLUTION 1 : 4, 2, 6
SOLUTION 2 : 12
虽然4、8也是一种解决方案,但我的程序并没有显示出来。 输入数量为 100 或更多时,情况更糟。至少会有 10000 个组合,但我的程序显示 100 个。
我试图遵循的逻辑:
- 将主 SET 的元素放入一个子集中,只要 子集的总和保持小于或等于目标总和。
- 如果将特定数字添加到子集总和使其 大于目标,它不接受它。
- 一旦到达终点 的集合,并且没有找到答案,它删除了最 最近从集合中取出号码并开始查看号码 在最近号码的位置后的位置去掉。 (因为我存储在数组 's' 中的是 从主 SET 中选择的数字)。
【问题讨论】:
-
如果你的变量有更多的描述性名称会有所帮助(这对你的编程生涯一般来说很有用),或者至少如果你告诉我们每个变量应该是什么意思,它们如何重新声明,初始化等。
-
您能否添加一些示例输入,您期望的输出是什么,以及输出是什么。完全不清楚这段代码是如何提供任何东西的,或者它是从哪里得到输入的。
-
抱歉含糊不清。这是我第一次在网上发布代码。
-
第二个
while()循环似乎很奇怪。 一般来说,我很难弄清楚你的算法的逻辑。你能用几个自然语言的词清楚地表达出来吗? -
好的,我刚刚编辑了我的帖子并添加了我尝试使用的逻辑。第二个 while 循环将最近添加的元素删除到子集中。
标签: c++ algorithm backtracking subset-sum