'最有效的材料分配'算法:

时间:2014-03-09 01:11:44

标签: algorithm sorting frequency

最有效的材料分配有序java编程问题:

这是一个编程问题,我根本无法处理。这是一个面试问题,所以需要在10-15分钟内解决。

  

一家公司希望自动订购三种尺寸的木材   董事会成为最具成本效益的订单(更长的董事会更少   昂贵)。木材公司提供的木材出售   16',12'和8'板。板越长越便宜。

     

订单是针对7',6'和5'板的倍数单位。所以   你可以从一个16'中获得两个7'板,或者从5'中获得两个7'板   16')等。如果您只需要两个5'板,您可以订购   单身12',而不是16'。

     

编写一个算法,该算法将接收混合板数量的订单   三种类型并返回效率最高(性价比高)   订购(最多)三种可用尺寸。

我不禁想到改变最佳造币的问题,但与此相比,这相对简单。似乎有项目频率的元素,但我看不出如何分配最佳顺序。

我认为这是一个两步过程,第一步是将频率记录在地图中,例如6 x 7页脚,5 x 6页脚等。频率图按值排序,这就是我卡住的地方。

只是为了澄清:更大的电路板更便宜,应尽可能先使用。

我会继续关注这一点,但如果有人有想法,我们将不胜感激。

1 个答案:

答案 0 :(得分:0)

package max.test.com;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/*
 * Board Cutter algorithm based on John T Erickson's 
 * code found at http://pastebin.com/1XPiBD20
 * 
 * I can't take credit for it - I just rendered it to Java  
 * 
 * Max Tomlinson
 * 
 */
public class BoardCutter
{

    static List<Double> boards;
    static List<Double> lengthsNeeded;

    static double cutWidth = Double.NaN;
    static double totalBoardLength;

    static int lengthsNeededLeft = 0;

    static List<String> instructions = new ArrayList<String>();
    static List<String> summary = new ArrayList<String>();

    public static void main(String[] args)
    {
        double[] tmp = new double[] { 48, 48, 48, 48, 48, 48 };
        boards = new ArrayList<Double>();
        for (int i = 0; i < tmp.length; i++)
        {
            boards.add(tmp[i]);
            totalBoardLength += tmp[i];
        }

        lengthsNeeded = new ArrayList<Double>();

        tmp = new double[] { 36.75, 36.5, 36.5, 26.25, 26.125, 22.5, 21, 20.5,
                14.5, 9.25, 9, 6.5, 4 };

        for (int i = 0; i < tmp.length; i++)
        {
            lengthsNeeded.add(tmp[i]);
        }

        cutWidth = 0.125;

        Collections.sort(lengthsNeeded);
        Collections.reverse(lengthsNeeded); //sorted high to low - biggest cuts first

        lengthsNeededLeft = lengthsNeeded.size();

        writeLine("Boards: ");

        double boardSum = 0;

        Iterator<Double> itd = boards.iterator();
        while (itd.hasNext())
        {
            double board = itd.next();
            writeLine("" + board);
            boardSum += board;
        }

        writeLine("Total: " + boardSum);

        writeLine("Lengths Needed:");

        double lengthsNeededSum = 0;

        itd = lengthsNeeded.iterator();

        while (itd.hasNext())
        {
            double ln = itd.next();
            writeLine("" + ln);
            lengthsNeededSum += ln;
        }

        writeLine("Total: " + lengthsNeededSum);

        tryCut();

        Collections.reverse(instructions);

        for (int i = 0; i < instructions.size(); i++)
            writeLine("Cut " + (i + 1) + ": " + instructions.get(i));

        for (int i = 0; i < summary.size(); i++)
            writeLine(summary.get(i));
    }

    /*
     * recursive cutting method
     */
    static boolean tryCut()
    {
        //last case, then exit
        if (lengthsNeededLeft == 0)
        {
            double boardLengthRemaining = 0;

            Iterator<Double> it = boards.iterator();
            while (it.hasNext())
            { // sum
                double board = it.next();
                if (!Double.isNaN(board)) 
                    boardLengthRemaining += board;                  
            }

            summary.add("Boards Remaining: ");

            for (int j = 0; j < boards.size(); j++)
            {
                if (boards.get(j).equals(Double.NaN)) continue;
                summary.add(" Board " + j + ": " + boards.get(j));
            }

            summary.add("Total Remaining " + boardLengthRemaining
                    + " efficiency "
                    + (100 * (1 - (boardLengthRemaining) / totalBoardLength)));

            return true;
        }

        //normal, recursive case

        //loop for all lengths needed
        for (int i = 0; i < lengthsNeeded.size(); i++)
        {
            double lengthNeeded = lengthsNeeded.get(i);

            if (Double.isNaN(lengthNeeded)) continue; //isNaN = 'done'

            for (int j = 0; j < boards.size(); j++)
            {
                double board = boards.get(j);

                if ( Double.isNaN(board)) continue; //isNaN = 'in use'

                double boardRemaining = board - lengthNeeded - cutWidth;

                if (boardRemaining >= 0.0)
                {
                    lengthsNeeded.set(i, Double.NaN); //set this length needed to 'done'
                    lengthsNeededLeft--;

                    boards.set(j, Double.NaN); //set board to used

                    boards.add(0, boardRemaining); //add new cut board remainder to front of available boards for possible reuse

                    int newBoardIndex = boards.size() - 1; //adjust size

                    //recursive call
                    if (tryCut())
                    {
                        instructions.add("Cut board " + (j + 1) + " of length " + board 
                                + " to size: " + lengthNeeded 
                                + " (leaving board " +  (newBoardIndex + 1) + " of length "
                                +  boardRemaining + ")");
                        return true;                        
                    }

                    boards.remove(boards.size() - 1);

                    lengthsNeeded.set(i, lengthNeeded);
                    lengthsNeededLeft++;

                    boards.set(j, board);
                }
            }
        }

        // all boards are too short 

        return false;
    }

    static void writeLine(String s)
    {
        System.out.println(s);
    }
}
//output
/*
Boards: 
48.0
48.0
48.0
48.0
48.0
48.0
Total: 288.0
Lengths Needed:
36.75
36.5
36.5
26.25
26.125
22.5
21.0
20.5
14.5
9.25
9.0
6.5
4.0
Total: 269.375
Cut 1: Cut board 1 of length 48.0 to size: 36.75 (leaving board 7 of length 11.125)
Cut 2: Cut board 2 of length 48.0 to size: 36.5 (leaving board 8 of length 11.375)
Cut 3: Cut board 3 of length 48.0 to size: 36.5 (leaving board 9 of length 11.375)
Cut 4: Cut board 4 of length 48.0 to size: 26.25 (leaving board 10 of length 21.625)
Cut 5: Cut board 5 of length 48.0 to size: 26.125 (leaving board 11 of length 21.75)
Cut 6: Cut board 6 of length 48.0 to size: 22.5 (leaving board 12 of length 25.375)
Cut 7: Cut board 10 of length 21.625 to size: 21.0 (leaving board 13 of length 0.5)
Cut 8: Cut board 11 of length 21.75 to size: 20.5 (leaving board 14 of length 1.125)
Cut 9: Cut board 12 of length 25.375 to size: 14.5 (leaving board 15 of length 10.75)
Cut 10: Cut board 7 of length 11.125 to size: 9.25 (leaving board 16 of length 1.75)
Cut 11: Cut board 8 of length 11.375 to size: 9.0 (leaving board 17 of length 2.25)
Cut 12: Cut board 9 of length 11.375 to size: 6.5 (leaving board 18 of length 4.75)
Cut 13: Cut board 15 of length 10.75 to size: 4.0 (leaving board 19 of length 6.625)
Boards Remaining: 
 Board 12: 0.5
 Board 13: 1.125
 Board 15: 1.75
 Board 16: 2.25
 Board 17: 4.75
 Board 18: 6.625
Total Remaining 17.0 efficiency 94.09722222222221
*/
相关问题