一种分类算法&分组加权对象列表

时间:2010-06-04 10:36:11

标签: .net algorithm sorting grouping

我有很多数据块。

为了论证,我们会说他们是

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

3 个答案:

答案 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”方法开始,运行几个模拟。保持最佳解决方案。使用有限的时间打破搜索并使用迄今为止找到的最佳搜索。