Finding the numbers from a set which give the minimum amount of waste

烂漫一生 提交于 2019-11-30 12:34:57

You have a couple of problems.

One is this line: int a = clonedSet.min(); //select next candidate

If you walk through your example, it would have found the value 1 and used that first, so 1 and 4 would have been used, but 6 wouldn't.

You are better looking for the max value that will be <= the remaining length.

This line also is odd to me:

WASTAGE +=a;

You should be subtracting I think, and why are you modifying a static integer?

If this is something that can be mutable, then you should just pass it in, then pass back when you are done what was the amount wasted, so have a new class that you return, the solution and the amount that was wasted.

For recursion you will want to have your example, then walk through one at a time and see if the behavior it does is what you expect.

You may want to look at this loop:

for (int i = 0; i < possibleOrders.numberInSet(); i++) // the repeat

As, if you are doing this recursively, then if you have 3 possible solutions, you will end up doing 6 tests, I believe, rather than going through three times, which is what you expect.

If you remove the for loop you should still be fine. Put in a print statement so you can watch it go through each time.

UPDATE:

Based on more information, what you will want to do is to collect all the possible solutions, then what you can do is to go through and do the first pass, get the solutions that work that way. Then, shift left or right the possible solutions, then try again.

When you have shifted all the way through, you will have tried various combinations, but not every possible combination, but, you can then take those solutions, and see which is optimal.

If you want to test more of the combinations, then you will need to loop through removing an item, and this could be recursive.

So, you will need one recursive function inside another one, so you recursively go through all possible combinations, then recursively look to find a solution to the problem.

I think looking for the max would probably be best, but that is just my gut feeling, and it could be shown that min is best.

I agree with James, you don't need/want the loop. As I understand it, your 'tryCutting' algorithm takes a list of possible orders, a current solution under consideration and the the length left if you were to cut the current solution. Then you need to:

  • remove the shortest cut from the orders. If it's longer than the length left, don't try any more. Otherwise,
  • first case: you don't fulfil that cut - tryCutting again with the new list of orders and the same current length
  • second case: you do fulfil that cut. Add it to the current solution and tryCutting with the new list of orders and the length reduced by that cut. Finally take it off the current solution again (for backtracking)
  • put the shortest cut back on the orders (for backtracking)

Now, for each case you try, check the length left against your global best case so far. It it's shorter then update a global with (a clone of) the current solution.

This will give you the single best solution or one of them if there are several equally good. To get all solutions you need a global list of SetInts. If you find a solution better than the current, clear the list and add the new solution. If it's equal to the current best, just add it.

Here it is in code:

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, solution, lengthleft); // Try without that cut
        solution.add(a); // add to the solution
        tryCutting(possibleOrders, solution, lengthleft - a); // Try with that cut
        solution.remove(a); // remove again
        possibleOrders.add(a); // add the candidate back on again
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!