如何解决从一组中找到给出最少废物量的数字
|| 将一个集合传递到下面的此方法,并且还传递一个条的长度。如果从该条的长度中删除了该集合中的某些数字,则解决方案应该输出该集合中的数字,这些数字将提供最少的浪费。因此,条形长度10,集合包括6,1,4,因此解为6和4,浪费为0。我在通过集合回溯的条件上遇到了一些麻烦。香港专业教育学院也试图使用浪费的“全局”变量来帮助回溯方面,但无济于事。 SetInt是一个手工制作的集合实现,可以添加,删除,检查集合是否为空并从集合中返回最小值。/*
* To change this template,choose Tools | Templates
* and open the template in the editor.
*/
package recback;
public class RecBack {
public static int WASTAGE = 10;
public static void main(String[] args) {
int[] nums = {6,4};
//Order Numbers
int barLength = 10;
//Bar length
SetInt possibleOrders = new SetInt(nums.length);
SetInt solution = new SetInt(nums.length);
//Set Declarration
for (int i = 0; i < nums.length; i++)possibleOrders.add(nums[i]);
//Populate Set
SetInt result = tryCutting(possibleOrders,solution,barLength);
result.printNumbers();
}
private static SetInt tryCutting(SetInt possibleOrders,SetInt solution,int lengthleft)
{
SetInt clonedSet = possibleOrders.cloneSet(); //initialise selection of candidates
for (int i = 0; i < possibleOrders.numberInSet(); i++) // the repeat
{
int a = clonedSet.min(); //select next candidate
if (a <= lengthleft) //if accecptable
{
solution.add(a); //record candidate
lengthleft -= a;
clonedSet.remove(a); //remove from original set
if (!clonedSet.isEmpty()) //solution not complete
{
WASTAGE +=a;
tryCutting(clonedSet,lengthleft);//try recursive call
if (lengthleft > WASTAGE)//if not successfull
{
WASTAGE += a;
solution.remove(a);
}
} //solution not complete
}
} //for loop
return solution;
}
}
解决方法
你有几个问题。
一个是这一行:
int a = clonedSet.min(); //select next candidate
如果您遍历您的示例,它将找到值1并首先使用该值,因此将使用1和4,但不会使用6。
您最好寻找小于等于剩余长度的最大值。
这行对我也很奇怪:
WASTAGE +=a;
我认为您应该减去,为什么还要修改静态整数?
如果这是可以改变的,那么您应该将其传递,然后在完成后传递回去,这是浪费的数量,因此您要返回一个新的类,解决方案和浪费的数量。
对于递归,您将需要一个示例,然后一次遍历一个示例,看看它的行为是否符合您的期望。
您可能要看一下以下循环:
for (int i = 0; i < possibleOrders.numberInSet(); i++) // the repeat
因为,如果您递归执行此操作,那么如果您有3种可能的解决方案,那么我相信您最终将进行6次测试,而不是经过3次测试(这是您期望的)。
如果您删除了for循环,您还是可以的。放入打印声明,以便您每次都能查看。
更新:
根据更多信息,您将要做的是收集所有可能的解决方案,然后您可以做的是经过并进行第一遍,以这种方式获得可行的解决方案。然后,向左或向右移动可能的解决方案,然后重试。
一路转换完后,您将尝试各种组合,但不是每种可能的组合,但是您可以采用这些解决方案,然后看看哪种是最佳的。
如果您想测试更多的组合,则需要遍历删除项,这可能是递归的。
因此,您将需要在另一个函数内部使用一个递归函数,以便您递归地研究所有可能的组合,然后递归地寻找问题的解决方案。
我认为寻找max
可能是最好的,但这只是我的直觉,可以证明min
是最好的。
,我同意James的观点,您不需要/不想循环。据我了解,您的\'tryCutting \'算法会列出可能的订单,正在考虑的当前解决方案以及要剪切当前解决方案时剩余的长度。然后,您需要:
从中删除最短的切口
命令。如果长度超过剩余长度,请不要再尝试了。除此以外,
第一种情况:您不满足
削减-尝试再次使用新的
订单清单和当前相同
长度
第二种情况:您确实实现了
切。将其添加到当前
解决方案并尝试使用新的订单清单和长度切割
通过削减减少。最后拿
再次关闭当前解决方案
回溯)
放最短的切
返回订单(用于回溯)
现在,对于您尝试的每种情况,请检查到目前为止的最佳情况下剩余的长度。它要短一些,然后使用当前解决方案(的一个克隆)更新一个全局变量。
这将为您提供最佳的解决方案,如果有多个同样好的解决方案,则可以选择其中一种。要获得所有解决方案,您需要一个全局的SetInts列表。如果找到比当前更好的解决方案,请清除列表并添加新解决方案。如果等于当前的最佳值,则将其添加。
它在代码中:
public static void main(String[] args) {
int[] nums = {6,1,4}; //Order Numbers
int barLength = 10; //Bar length
bestSolution = new HashSet<SetInt>();
bestWastage = barLength;
SetInt possibleOrders = new SetInt(nums.length);
SetInt solution = new SetInt(nums.length); //Set Declarration
for (int i = 0; i < nums.length; i++) {
possibleOrders.add(nums[i]); //Populate Set
}
tryCutting(possibleOrders,solution,barLength);
for (SetInt result : bestSolution) {
result.printNumbers();
}
}
private static int bestWastage;
private static Set<SetInt> bestSolution;
private static void tryCutting(SetInt possibleOrders,SetInt solution,int lengthleft) {
if (lengthleft < bestWastage) {
// Better than the best solution
bestWastage = lengthleft;
bestSolution.clear();
bestSolution.add(solution.cloneSet());
} else if (lengthleft == bestWastage) {
// Just as good as the best solution
bestSolution.add(solution.cloneSet());
}
int a = possibleOrders.min(); //select next candidate
if (a <= lengthleft) { // If acceptable
possibleOrders.remove(a); // Remove it
tryCutting(possibleOrders,lengthleft); // Try without that cut
solution.add(a); // add to the solution
tryCutting(possibleOrders,lengthleft - a); // Try with that cut
solution.remove(a); // remove again
possibleOrders.add(a); // add the candidate back on again
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。