将收货和收货发票分组以使其总和为0

时间:2013-05-30 08:28:30

标签: algorithm sorting

我今天遇到了一个有趣的问题,并决定用C#编写一个算法来解决它。

有传入的发票显示负总数,而传出的发票则显示正总数。任务是从这些发票中分组,其中发票总数恰好为0.每个组可以包含无限成员,因此如果有两个正面和一个负面成员但它们的总值为0,那就没关系。

我们尽量减少剩余发票总额的总和,并且根本没有其他限制。

我想知道这个问题是否可以追溯到一个已知问题,如果没有,这将是最有效的方法。天真的方法是将传入和传出的发票分成两个不同的组,按总计排序,然后尝试逐个添加发票,直到达到零或符号已更改。但是,这假设一组中的发票应该大致相同,这是不正确的(一个巨大的收到发票可以对10个较小的外发发票)

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

您面临的问题是众所周知且经过研究的问题,称为 The Subset Sum Problem

不幸的是,问题是NP-Complet e,所以没有已知的多项式解决方案 1
事实上,没有已知的多项式解决方案可以确定是否存在这样的子集(甚至是单个子集),更不用说找到它了。

但是,如果您的输入包含相对较小(绝对值)的整数,则可以使用非常有效的(伪多项式)dynamic programming solution来解决问题。

如果不是这种情况,那么其他替代方案是:

  1. 使用像brute force这样的指数式解决方案(您可以使用branch and bound技术对其进行优化)
  2. 启发式解决方案,例如Steepest Ascent Hill ClimbingGenethic Algorithm s。
  3. Approximation algorithmŠ

  4. (1)大多数计算机科学研究人员认为一个不存在,这基本上是P VS NP Problem