组合最佳匹配

时间:2012-10-09 03:26:55

标签: algorithm combinatorics mathematical-optimization

假设我有一个Group数据结构,其中包含Element个对象列表,这样每个组都有一个唯一集合元素。:

public class Group
{
  public List<Element> Elements;
}

并说我有一个需要某些元素的人口列表,每个人口都有一个唯一集合所需元素:

public class Population
{
  public List<Element> RequiredElements;
}

每个定义的组都有无限量,即人群不会消耗。

说我正在查看特定的Population。我想找到最佳匹配组,以便有最少的多余元素,没有不匹配的元素

例如:我的人口需要木材,钢材,粮食和煤炭。唯一可用的组是{木材,草药},{钢,煤,油},{粮食,钢},和{草药,肉}。

我的人口根本不需要最后一组 - {草药,肉},因此不使用它。所有其他都是必需的,但不需要草药和油,因此浪费了。此外,钢在最小组中存在两次,因此也浪费了一批钢。此示例中的最佳匹配的浪费为3。

因此,对于几百个Population个对象,我需要找到最小浪费最佳匹配并计算浪费的元素数量。

我怎么开始解决这个问题?一旦我找到一场比赛,计算浪费是微不足道的。首先找到比赛很难。我可以列举所有可能性,但有几千人口和数百个群体,这是一项相当艰巨的任务。特别是考虑到整个事情都在模拟退火算法的每次迭代中。

我想知道我是否可以将整个事物表示为混合整数程序,并在每次迭代时调用像GLPK这样的求解器。

我希望我已正确解释了这个问题。我可以澄清一些不清楚的事情。


这是我的二进制程序,对于那些你感兴趣的人......

x是决策向量,是{0,1}的一个元素,它表示有问题的人群从群组i接收/不接收。每个小组都有一个条目。

b是列向量,是{0,1}的元素,它表示有问题的人口所需/不需要的资源。每个资源都有一个条目。

A是一个矩阵,是{0,1}的一个元素,它表示哪些资源属于哪些组。

该计划是:

最小化:((Ax - b)'* 1-vector)+(x'* 1-vector);

主题:Ax&gt; = b;

约束只是说必须满足所有必需的资源。目标是尽量减少所有过量和使用的组总数。 (即,使用1组的0过量优于0过量,使用5组)。

3 个答案:

答案 0 :(得分:0)

您的意思是Maximum matching问题吗?

你需要建立一个bipartite graph,其中一方是你的人口而另一方是群组,如果它在集合中有边缘,则存在于群A和群B之间。

要找到最大边缘匹配,您可以轻松使用Kuhn算法,该算法有很大的描述here on TopCoder
但是,如果你想找到最小边缘支配集(覆盖所有顶点的最小边集),那么问题就变成了NP难,并且在多项式时间内无法解决。

答案 1 :(得分:0)

您可以为每个人口P制定一个整数程序,如下所示。使用二进制变量x j 表示是否选择了组j。令A为二进制矩阵,使得当且仅当项目i存在于组j中时,A ij 为1。然后整数程序是:

min E i,j (x j A ij

s.t。 E j x j 对于P中的所有i, ij &gt; = 1。

x j = 0,1为所有j。

请注意,您可以通过从上述IP的最佳解决方案中减去|P|来获得最小浪费。

答案 2 :(得分:0)

看看加权套装问题,我认为这正是你上面所描述的。可以找到({未加权)问题的基本描述here

如上所述,找到最小的浪费等同于找到一个集合覆盖,使得覆盖集的基数之和最小。因此,必须将每组(=一组元素)的权重定义为等于其基数。

由于即使未加权的集合覆盖问题是NP完全的,也不太可能存在针对您的问题实例的有效算法。也许一个好的贪心近似算法就足够了你的目的?谷歌搜索加权集覆盖提供了几个有希望的结果,例如这script