如何使用背包找到裁剪原料问题的最佳组合

问题描述 投票:0回答:5

编辑(2019 年 12 月 31 日)- https://jonathan.overholt.org/projects/cutlist

上面是免费项目的链接,这正是我正在寻找的。我只是在寻找适当的指导,以便我能够使其发挥作用。

我正在努力最大程度地减少铝推拉窗制造商的铝挤压切割浪费,但我无法弄清楚应该采用哪种算法/数据结构来解决该问题。

我做了基础研究,发现问题属于切削库存问题(也称为一维切削问题)、线性规划问题、贪心算法。但我无法决定应该选择哪一个以及如何开始。

问题简介:

窗户制造商基本上有3种尺寸的材料可供选择。

12 | 15 | 16 (IN FT)

现在输入将是窗口的大小。

宽度 x 高度(英尺)

1) 6 x 8 - 10 个窗口

2) 9 x 3 - 20 个窗户

计算公式为(2 x 宽度)+(2 x 高度)。所以从上面的窗口尺寸来看,它们需要如下挤压。

1) 6' (FT) 尺寸的碎片 -> 2 x 10 = 20

2) 8' (FT) 尺寸的块 -> 2 x 10 = 20

3) 9' (FT) 尺寸块 -> 2 x 20 = 40

4) 3' (FT) 尺寸块 -> 2 x 20 = 40

使用背包,我们可以找出组合,但它的尺寸限制为只能为 1,而在我的例子中,我有 3 种不同的尺寸可用,我想从中生成切割库存问题的最佳组合。

我需要帮助来解决上述有关 Java 或任何其他语言的数据结构和算法的问题。我的数学知识达不到要求,这就是为什么我在项目中实现逻辑时面临问题,并希望从社区获得一些帮助。

java algorithm math linear-programming
5个回答
7
投票

除了强力检查所有可能的组合之外,没有任何算法可以保证您获得最佳解决方案。这显然不是一个好的算法,至少如果你有大量的数据集的话。

您应该看看启发式搜索算法,例如 Simulated AnnealingMCTS 等。找到启发式搜索引擎的现有实现应该没有问题,可以为它们提供

  • 输入集(材料上的碎片随机分布),
  • 转换功能(在材质之间移动碎片),
  • 和评估函数(浪费量)

并为您计算一个接近最优的解决方案。


2
投票

我会回应其他答案的观点:虽然这个问题可能有一个“最正确”的解决方案,但您真正寻找的是一个“足够正确”的解决方案。

也就是说,我写了这个小附录来帮助理解您引用的项目中的代码:cutlist 生成器设计说明

转述:

每次迭代都从创建最长库存的新实例开始,并将尽可能多的部件放入其中。然后,库存被减少到仍然适合所有选定部件的最小库存。重复这一切,直到没有碎片为止。

另一条建议:确保清楚地识别您在算法中构建的所有假设。我的假设是,单位库存越长越便宜,而且总是首选,但有人要求我进行一些变化,以优化最少的切割次数(捆绑切割),或者跟踪并更喜欢首先使用以前运行的边角料。

一如既往:在设定假设之前非常清楚地了解客户的流程。


0
投票

您考虑过单纯形算法吗? 您有一个最小化问题,可以将其转换为最大化问题,然后通过算法求解,或者通过对偶单纯形算法求解。 您会在 Google 上找到实现。


0
投票

下面的代码将为您提供按废物排序的组合或模式(min = 0)。只需提供您允许的废物即可。所以,它是根据你的切割次数深度的多个嵌套循环,所以如果 50 次切割,那么你将有 50 个嵌套循环,这就是为什么我将其更改为递归,来自其他线程的想法。仍在研究应用该算法的代码。

using System;
using System.Collections.Generic;
using System.Linq;

namespace Bar_Cutting_Recursive
{
    public class BarCuts
    {
        public int[] Qty { get; set; }
        public double TotalLength { get; set; }
        public double Waste { get; set; }
       
        public String result()  // return output.
        {
            return $"{string.Join(", ", Qty)}, TL = {TotalLength}, Waste = {Waste:F2}";
        }
    }

    internal class Program
    {
        private static double[] BarCuts = {9,8,7,6};  // List of Bar Cuttings.
        private static int BarLength = 20;
        private static double WasteRqd = 4;
        private static List<BarCuts> CutCombs= new List<BarCuts>();
        static void Main(string[] args)
        {
            int[] limits = GetLimits(BarCuts);           
            AddToCollectionRecursive(limits);
            CutCombs.Sort(delegate(BarCuts w1, BarCuts w2) { return w1.Waste.CompareTo(w2.Waste); });

            foreach (var item in CutCombs)
                Console.WriteLine(item.result());
            Console.ReadLine();
        }

        static void AddToCollectionRecursive(params int[] limits)
        {
            AddTo(new List<int>(), limits, limits.Length - 1);
        }

        static void AddTo(IEnumerable<int> value, IEnumerable<int> counts, int left)
        {
            for (var i = 0; i < counts.First(); i++)    // should change the upper limit or some break in outermost level if total > 20.
            {
                var list = value.ToList();
                list.Add(i);
                if (left == 0)
                {
                    // nt added
                    double tl = Combination_Length(list);
                    if (tl > BarLength) { break; }

                    double waste = BarLength - tl;          // BarLength = avlb bar length.
                    if (waste <= WasteRqd)
                    {
                        CutCombs.Add(new BarCuts { Qty = list.ToArray(), TotalLength = tl, Waste = waste });
                    }

                }
                else
                {
                    AddTo(list, counts.Skip(1), left - 1);
                }
            }
        }

        static double Combination_Length(List<int> CutsQty)
        {
            double tl = 0;
            for (int j = 0; j < CutsQty.Count; j++)
                tl += CutsQty[j] * BarCuts[j];
            return tl;
        }

        static int[] GetLimits(double[] Cuts)
        {
            int[] L = new int[Cuts.Length];
            for (int i = 0;i < Cuts.Length;i++)
            {
                L[i] = Convert.ToInt32(BarLength / Cuts[i]) + 1;
            }
            return L;
        }
    }
}

-4
投票

顶部外部玻璃推拉门 - Bunnings |建筑铝材

Builtec Aluminium 是一家值得信赖的优质外部玻璃推拉门制造商和供应商,为全球客户提供服务。我们的产品专注于卓越的工艺、创新的设计和无与伦比的耐用性,改善了住宅和商业空间。 使用Builtec Aluminium 的外部玻璃推拉门体验无缝功能、轻松风格和无与伦比的性能,现已在 Bunnings 和全球其他领先零售商出售。

© www.soinside.com 2019 - 2024. All rights reserved.