根据简单规则对项目进行分组的算法

时间:2018-11-09 10:58:32

标签: c# algorithm

我想要一些帮助来找到问题的良好算法,但是我什至无法弄清楚如何抽象这个问题,所以我将把这个问题作为我想要的例子来写。

说我有一个2种类型的项目( A B )的列表,它们都有一个值。列表看起来像这样:

  1. A1:10
  2. B1:11
  3. A2:9
  4. B2:6
  5. B3:4

我的问题是,我想针对以下规则制作尽可能多的商品组:

  • 必须至少有1种 A 类型项目和1种 B 类型项目
  • 每组值的总和必须至少为20

算法的输出应为:

找到2个群组:

  • 第1组包含A1,B2和B3
  • 第2组包含A2和B1

问题的参数可能有所不同:

  • 当然,此列表本身(项目数,值等)
  • 项目类型的数量(从1到很多)
  • 每种类型所需的物品数量(我可能希望A中至少有2件,B中至少3件)
  • 最低要求值总和

我几乎可以肯定这种算法的存在,这让我想到了背包问题,但实际上我什至不知道要搜索什么。


更新:以下是我为解决此问题而制作的算法,可帮助您更好地了解我的需求。


算法1

此算法仅提取必需项,以达到每种类型的必需项数并达到最小和。

  1. 获取A型的第一个可用物品
  2. 获取B型的第一个可用物品
  3. 带更多种类的物品,必要时总计20件
  4. 如果达到了所有必需的项目和总和,则将项目标记为不可用,然后返回第一组
  5. 循环直到无法分组为止

此算法取决于列表的顺序,并返回单个组:

  • 第1组包含A1和B1

速度非常快,但没有给我想要的结果。


算法2

此算法计算原始列表的所有可能排序,并在所有可能的情况下执行算法1。

然后,它从结果中取出最大的组数,并返回具有该组数的第一种可能性。

输出是我期望的:

找到2个群组:

  • 第1组包含A1,B2和B3
  • 第2组包含A2和B1

问题在于它具有指数级的复杂性,它在5个项目(120种可能性)中速度很快,而在10个项目(3628800种可能性)中速度慢。


我需要的是一种从算法2获得结果的算法,但是速度更快,我需要一种启发式方法,但是...如何?

1 个答案:

答案 0 :(得分:1)

可以通过数学约束求解器轻松解决:

我们使用以下术语:

  • @A =类别A的项目数
  • @B =类别B的项目数
  • n =分钟(@A,@B)
  • G_j = i = 0至(α_j_i* A_i)的@A的总和+ i = 0至(β_j_i* B_i)的@B的总和

然后,必须具有以下等式才能得到有效的解决方案:

  • G_j为0或G_j大于20
  • min(α_j_0...α_j_@ A ...β_j_0...β_j_@ B)为0或1
  • sum(α_0_0...α_0_n)为1(每个A使用一次)
  • sum(β_0_0...β_0_n)为1(每个B使用一次)

然后我们简单地最大化

T = i = 0到n的2的总和^ G_i-1

这将为每个空组添加一个0,为每个非空组添加一个更大的值。