我有很多数据块。
为了论证,我们会说他们是
File 1 - 150Kb
File 2 - 50Kb
File 3 - 70Kb
File 4 - 60Kb
File 5 - 70Kb
File 6 - 100Kb
File 7 - 90Kb
对于传输,我可以将它们打包到300Kb的最大有效载荷中。
如果你只是按顺序遍历它们
TRANS1: 150Kb + 50Kb + 70Kb = 270Kb - the next file puts you over the limit of 300Kb
TRANS2: 60Kb + 70Kb + 100Kb = 230Kb - the next file puts you over the limit of 300Kb
TRANS3: 90Kb
所以三个单独的传输。
但是如果你重新组织它们,你可以发送
Files 1,2,6 together = 300Kb
Files 3,4,5,7 together = 290Kb
因此,您需要减少单独传输的数量。既然有一个 与每次传输相关的货币成本(这些传输实际上是对第三方系统的API调用,我们按照API调用计费)我们希望保留这些数字 单独的有效载荷发送到最低限度。
这种优化是否有任何排序算法, 这将获取一个加权对象列表,并对它们进行排序/分组,以便结束 最少数量的团体
作为参考,我将在.NET中对此进行编码,但如果您能够提供其他语言或伪代码实现/描述的示例,那也会很棒。
谢谢, Eoin C
答案 0 :(得分:2)
你的问题正是Bin packing问题,遗憾的是NP-Complete :( 如果数据包的数量非常小,您可以强制执行所有可能的组合。
否则,我建议的动态编程解决方案不会给出最佳答案,因为它会假设您始终将连续数据包分组。但它会表现得很快并且能够提供接近真相的东西。我使用带有memoization的递归。最好在开始时按顺序对数据包进行排序。
const int INF = 1000000;
const int MAXSIZE = 300;
int DP[NumberOfPackets][MaxPayload];
int solve(int packetNum, int sizeUsed)
{
if (packetNum == NumberOfPackets)
return 0;
if (DP[packetNum][sizeUsed] != -1)
return DP[packetNum][sizeUsed];
int res = INF;
//Try to put the packet in the current group
if (sizeUsed + size[packetNum] <= MAXSIZE)
res = min(res, solve(packetNum + 1, sizeUsed + size[packetNum]));
//Try to start another group with the current packet
res = min(res, solve(packetNum + 1, size[packetNum]) + 1);
return DP[packetNum][sizeUsed] = res;
}
int answer = solve(1, size[0]);
答案 1 :(得分:1)
您正在寻找的是背包算法或对它的修改。 问题无法有效解决,但您可以接近完美的解决方案。
您可以使用this google search进行实施。
答案 2 :(得分:0)
这让我想起Knapsack problem。我没有跟进,但我记得这是一个NP完全问题:读“硬”。你基本上需要在“正确”和“快速”之间找到妥协。
这并不意味着不可能,但这显然是一个完美是善的敌人的领域。
我将从“Big Rocks First”方法开始,运行几个模拟。保持最佳解决方案。使用有限的时间打破搜索并使用迄今为止找到的最佳搜索。