-1

I'm in abit of a pickle. I've got to implement a recursive backtracking algorithm that will work out how to cut a bar with the least ammount of wasteage.

this is from the specification for the coursework.

Quote: Now, imagine the scenario in which a factory manufactures steel bars of length 150mm. Its cutting shop receives orders for cut lengths of bars, which must be met by cutting up the manufactured bars. With each order the factory wants to cut the bar is such a way that it produces the least amount of wastage.

Develop a java method which given manufactured bar of length 150mm, a set of all orders in the order list and an empty set produces the set of orders which can be met by cutting up the bar with minimum wastage. currently I've sort of got it working non recursively but not 100% and when I try and get it working recurisvely it just crashed lol infinite loop / stack overflow I think.

Would anyone mind looking at my code and giving me a hand? its for uni coursework and its the first time i've really tryed recursive backtracking so any help would be brilliant.

Non recursive code that sort of works.

Code:

private SetInt tryCutting(SetInt possibleOrders, SetInt solution, int lengthLeft)
    {
        //SetInt possibleOrders = solution.clone();


        while(!possibleOrders.isEmpty())
        {

            if(possibleOrders.min()<= lengthLeft)
            {
                if(possibleOrders.min() > solution.min())
                {
                System.out.println(possibleOrders.min() + "added to solution \n");
                solution.add(possibleOrders.min());
                lengthLeft -= possibleOrders.min();
                possibleOrders.remove(possibleOrders.min());
                }
                else
                {
                    possibleOrders.remove(possibleOrders.min());
                }
                try{
                        Thread.sleep(10); //sleep 1000 milliseconds
                        }catch(Exception e){}
            }


            else if(possibleOrders.min() > lengthLeft)
            {
                System.out.println("poss order min" + possibleOrders.min()+"\n");
                System.out.println("solution min" + solution.min()+"\n");
                if(possibleOrders.min() > solution.min())
                {
                    int value = possibleOrders.min();
                    while(value > lengthLeft)
                    {
                        lengthLeft += solution.min();
                        System.out.println(solution.min() + "added to possible orders \n");
                        possibleOrders.add(solution.min());
                        solution.remove(solution.min());
                    }
                    solution.add(value);
                    possibleOrders.remove(value);
                    lengthLeft -= value;
                }
                else
                {
                    possibleOrders.remove(possibleOrders.min());
                }
            }

        }
        System.out.print("Solution :");
        solution.printNumbers();
        System.out.println("Wastage :" + lengthLeft);
        return solution;
    }

My attempt at recursive code

private SetInt tryCutting(SetInt possibleOrders, SetInt solution, int lengthLeft)
    {
        while(!possibleOrders.isEmpty())
        {
            System.out.println("not empty");
            int value = possibleOrders.min();
            if(value < lengthLeft && value>solution.min())
            {
                solution.add(value);
                possibleOrders.remove(value);
                lengthLeft-=value;

                if(!possibleOrders.isEmpty())
                {
                    possibleOrders.tryCutting(possibleOrders,solution,lengthLeft);
                }
                else
                    break;
            }
        }
        return solution;
    }
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 1
    You may want to read the questions and answers of your collegue: http://stackoverflow.com/questions/5738406/problem-with-recursive-backtracking and http://stackoverflow.com/questions/5680641/problem-with-recursive-backtracking – subsub Apr 28 '11 at 11:34

1 Answers1

0

Here's my solution. I didn't use sets because that would prohibit orders with multiple occurrences of the same bar length. It's easy to adapt this example to a version with sets though.

import java.util.ArrayList;
import java.util.Arrays;

public class SteelMill {

    private int maximumLength;
    private Order best;

    public SteelMill() {
        Order ordered = new Order(3, 4, 1, 6, 2, 5);
        Order filled = new Order();
        maximumLength = 7;
        fillOrder(ordered, filled, 0);
        System.out.println("best solution found: " + best + " waste = "
                + (maximumLength - best.total()));
    }

    private void fillOrder(Order ordered, Order filled, int depth) {
        print(depth, "ordered = " + ordered + " filled = " + filled);
        depth++;
        if (filled.total() > maximumLength) {
            return;
        }
        if (filled.total() == maximumLength || best == null
                || filled.total() > best.total()) {
            best = filled;
            if (filled.total() == maximumLength) {
                System.out.println("perfect solution found: " + filled);
            }
        }
        for (Integer bar : ordered) {
            Order childOrdered = new Order(ordered);
            childOrdered.remove(bar);
            Order childFilled = new Order(filled);
            childFilled.add(bar);
            fillOrder(childOrdered, childFilled, depth);
        }
    }

    public class Order extends ArrayList<Integer> {
        private static final long serialVersionUID = 1L;

        public Order(Order toCopy) {
            super(toCopy);
        }

        public Order(Integer... values) {
            for (Integer value : values) {
                add(value);
            }
        }

        public int total() {
            int total = 0;
            for (Integer value : this) {
                if (value != null) {
                    total += value;
                }
            }
            return total;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }
    }

    private static void print(int depth, String msg) {
        StringBuilder tabs = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            tabs.append("  ");
        }
        System.out.println(tabs + msg);
    }

    public static void main(String[] args) {
        new SteelMill();
    }
}
Adriaan Koster
  • 15,870
  • 5
  • 45
  • 60