递归回溯帮助!

时间:2011-04-28 10:53:22

标签: java recursion

我是一个泡菜。我必须实现一个递归回溯算法,该算法将解决如何用最少量的废物切割条形码。

这来自课程作业的规范。

引用: 现在,想象一下工厂生产长度为150毫米的钢筋的情况。它的切割车间收到切割长度的钢筋订单,必须通过切割制造的钢筋来满足。对于每个订单,工厂想要切割钢筋是这样一种方式,它产生最少的浪费。

开发一种java方法,该方法给出了长度为150mm的制造条,订单列表中的所有订单的集合以及空集产生了可以通过以最小的浪费来切割条来满足的订单集。 目前我有点非递归地工作,但不是100%,当我尝试让它恢复工作时它只是崩溃lol无限循环/堆栈溢出我认为。

有人会介意看我的代码然后帮我一把吗?它用于单一课程,这是我第一次尝试递归回溯,所以任何帮助都会很棒。

非递归代码,有效。

代码:

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;
    }

我尝试递归代码

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;
    }

1 个答案:

答案 0 :(得分:0)

这是我的解决方案。我没有使用集合,因为这会禁止多次出现相同条形长度的订单。这个示例很容易适应具有集合的版本。

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();
    }
}