将数字分类为具有特定总和的集合的算法
algorithm to sort numbers into sets which have a specific sum
我有 27 块硬木地板条,长度从 18 英寸到 48 英寸不等。我想制作 3 块木板,每块木板包含 3 排地板。两块木板必须长 60 英寸,另一块木板必须长 72 英寸。所有条带的总长度足以构建这些木板。显然,我可以 select 随机地将条带粘起来并切成一定尺寸。但是我想尽量减少切割浪费。
问题可以更简单地重述为:我有 27 个整数,想将它们分成 9 组。 6组每组加起来是60,剩下的三组每组加起来是72。这个问题是子集求和问题的变体。
我找到了一些讨论“dynamic programming”的帖子,但我对这种方法一无所知,更不用说如何编码了。
不久前有人提出了一个 similar 问题,但缺乏讨论。
我的做法是'google way'。蛮力。计算一切。稍后再解决。所以,
将整数分组为 9 个数组,每组 3 个 numbers.Note 有 9!/3! = 60480 个分组。
每组
计算每个数组的总和,称之为 ArraySum。有9个。
(A,B,C,D,E,F,G,H,I)
计算与目标总和 (72,60,60) 的差值
A-72,B-72,C-72, D-60, E-60,...
将这个组的所有差异相加并存储该数字(称之为 GroupSum)。这是我要最小化的数字。
排列 ArraySums 和目标总和之间的成对差异给出 (9!/3!=60480)
现在返回,更改分组并重复。
我得到 60480 x 60480 GroupSums = 3657830400
对组和进行排序,找到最低的组和,选择该分组。
有没有比预计算和排序更好的方法?
除非我误解了什么,否则你如何对它们进行分组似乎无关紧要,只要你能找到一个有效的分组(即所有组至少达到所需的长度)
逻辑是您刚开始时使用的条带数量正好,这意味着无论如何您都需要使用所有条带。您需要的条带总长度是恒定的 (60 * 6 + 72 * 3),您将使用的总长度也是恒定的(无论您的 27 条总和是多少),所以浪费是一个常数——无论它们之间有什么区别是。如果我理解正确,贪心算法应该可以解决问题——只需使用任何组合为每个给定的木板提供最小结果,任意解决关系,然后继续下一个。
除非你想尽量减少需要切割的条带数量,即将所有 "waste" 分配给尽可能少的条带。在这种情况下,您应该使用 L0 损失函数,而不是您建议的 L1(即您想要最小化总和的数量!= 0,而不是总和本身的值)
我有 27 块硬木地板条,长度从 18 英寸到 48 英寸不等。我想制作 3 块木板,每块木板包含 3 排地板。两块木板必须长 60 英寸,另一块木板必须长 72 英寸。所有条带的总长度足以构建这些木板。显然,我可以 select 随机地将条带粘起来并切成一定尺寸。但是我想尽量减少切割浪费。
问题可以更简单地重述为:我有 27 个整数,想将它们分成 9 组。 6组每组加起来是60,剩下的三组每组加起来是72。这个问题是子集求和问题的变体。
我找到了一些讨论“dynamic programming”的帖子,但我对这种方法一无所知,更不用说如何编码了。
不久前有人提出了一个 similar 问题,但缺乏讨论。
我的做法是'google way'。蛮力。计算一切。稍后再解决。所以,
将整数分组为 9 个数组,每组 3 个 numbers.Note 有 9!/3! = 60480 个分组。
每组 计算每个数组的总和,称之为 ArraySum。有9个。
(A,B,C,D,E,F,G,H,I)
计算与目标总和 (72,60,60) 的差值
A-72,B-72,C-72, D-60, E-60,...
将这个组的所有差异相加并存储该数字(称之为 GroupSum)。这是我要最小化的数字。
排列 ArraySums 和目标总和之间的成对差异给出 (9!/3!=60480)
现在返回,更改分组并重复。 我得到 60480 x 60480 GroupSums = 3657830400
对组和进行排序,找到最低的组和,选择该分组。
有没有比预计算和排序更好的方法?
除非我误解了什么,否则你如何对它们进行分组似乎无关紧要,只要你能找到一个有效的分组(即所有组至少达到所需的长度)
逻辑是您刚开始时使用的条带数量正好,这意味着无论如何您都需要使用所有条带。您需要的条带总长度是恒定的 (60 * 6 + 72 * 3),您将使用的总长度也是恒定的(无论您的 27 条总和是多少),所以浪费是一个常数——无论它们之间有什么区别是。如果我理解正确,贪心算法应该可以解决问题——只需使用任何组合为每个给定的木板提供最小结果,任意解决关系,然后继续下一个。
除非你想尽量减少需要切割的条带数量,即将所有 "waste" 分配给尽可能少的条带。在这种情况下,您应该使用 L0 损失函数,而不是您建议的 L1(即您想要最小化总和的数量!= 0,而不是总和本身的值)