【问题标题】:Proving a set of requirements can be met with a set of values using LINQ使用 LINQ 证明一组值可以满足一组要求
【发布时间】:2013-05-24 20:53:47
【问题描述】:

这是here 发布的问题的子集。

给定一组容量为B={x1, x2, ..., xn} 的桶和一组容量为V={v1, v2, ..., vn } 的液体小瓶,如果假设小瓶必须全部倒入一个桶中。允许溢出。

这里一些明显的不变量是桶的基数 |B| 必须小于或等于小瓶的基数 |V| 并且桶的组合体积 Sum(B) 必须小于或等于小瓶的总体积Sum(V)

这是一个众所周知的计算问题吗?如果是这样,是否可以制作一个简单的 LINQ 解决方案来用 C# 表达这一点?

我觉得这是 Eric Lippert 会写博客的内容 ;-)。

【问题讨论】:

  • 我从来没有写过关于这个特殊问题的博客;我不太了解分区问题。这是一个有趣的主题!
  • @EricLippert 我应该知道不要叫你的名字,你就像我发誓的甲壳虫汁。

标签: algorithm linq combinatorics set-theory


【解决方案1】:

考虑这个问题的一个例子,你有两个大小相同的桶,并且 Sum(B) = Sum(V)。这意味着您需要将小瓶平均分配到两个桶上,否则一个会溢出,而另一个则没有足够的空间。这称为partition problem,已知它是 NP 完全的。

编辑: 当然,NP-completeness 并不意味着问题不能解决,只是运行时间会随着输入的大小成指数增长(在这种情况下,是最大桶大小的 log2)。

如果我们能找到装满一桶所需的最少液体量(包括溢出),解决问题很简单,只需对每个桶执行此操作,然后在每个桶之后从可用小瓶集中取出用过的小瓶.

我们可以通过使用动态规划来做到这一点:

  • 对于给定的存储桶 b,请考虑大小为 0 到 volume(b) 的所有存储桶。
  • 0 号桶显然不需要液体
  • 对于每个尺寸 s,找到一个小瓶 v,这样:
    • s-volume(v) 的解决方案不使用 v
    • (s-volume(v)所用的液体量)+volume(v)最小化
  • 最后,您将拥有用于填充桶 b 的小瓶。然后,您只需将这些从可用小瓶中取出,然后移至下一个桶。

【讨论】:

  • 另外,如果您阅读了我之前的回答,请忽略它,因为它是错误的。
  • 当然……这很容易解决。但是有些情况 Sum(B) = Sum(V) 是无法解决的。
  • 我展示的是分区问题,一个NP完全问题,可以表示为这个问题的一个实例。因此,这个问题也是 NP 完全的,因此(可能)根本不是一个容易解决的问题。
  • @ImreKerr 你所展示的是这个问题是 NP-hard(NP-complete 或更难),而不是 NP-complete。
  • 你是对的,对不起。但是假设你有一个解决问题的候选方案,表示为每个桶的一组小瓶。然后,您可以获取给定存储桶的集合,对其进行总结,看看他们是否可以在 O(V) 时间内填满存储桶。查看一个小瓶是否已使用两次也可以在多项式时间内完成。因此问题出在 NP 中,因此是 NP 完全的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2019-09-01
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
相关资源
最近更新 更多