【问题标题】:Combinatorial best match组合最佳匹配
【发布时间】:2012-10-09 03:26:55
【问题描述】:

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

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

假设我有一个需要某些元素的人群列表,这样每个人群都有一个唯一的集合所需的元素:

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

我拥有无限数量的每个已定义组,即它们不被人群消费

假设我正在查看特定的Population。我想找到组的最佳匹配,使得多余元素最少,并且没有不匹配的元素

例如:我的人口需要木材、钢铁、谷物和煤炭。唯一可用的组是 {wood, herbs}, {steel, coal, oil}, {grain, steel} 和 {herbs, meat}。

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

所以对于几百个Population 对象,我需要找到最小浪费最佳匹配并计算浪费了多少元素。

我该如何开始解决这个问题?一旦我找到了一个匹配,计算浪费是微不足道的。一开始就很难找到匹配项。我可以列举所有的可能性,但有几千个人口和数百个群体,这是一项艰巨的任务。尤其是考虑到整个事情都在模拟退火算法的每次迭代中。

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

我希望我已经正确解释了这个问题。我可以澄清任何不清楚的地方。


这是我的二进制程序,有兴趣的人可以...

x 是决策向量,是 {0,1} 的一个元素,表示有问题的总体是否从组 i 接收。每个组都有一个条目。

b 是列向量,是 {0,1} 的一个元素,表示相关人群需要/不需要哪些资源。每个资源都有一个条目。

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

程序是:

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

服从:Ax >= b;

约束只是说必须满足所有必需的资源。目标是最小化所有多余的和使用的组总数。 (即 0 过量使用 1 组优于 0 过量使用 5 组)。

【问题讨论】:

  • 有多少种唯一类型的组,或者更确切地说,可以存在的唯一组的最大数量是多少?每个总体可以使用的最大元素数是多少?如果这些数字偏小,那么您可以通过迭代所有可能的唯一组组合并跟踪最小的浪费来强制解决方案。
  • 正如我在问题中所说,每种类型都有数千个。此外,我需要为我的 SA 算法的每次迭代准确地解决这个问题。

标签: algorithm combinatorics mathematical-optimization


【解决方案1】:

您可以为每个人口@9​​87654321@ 制定一个整数规划,如下所示。使用二进制变量 xj 来表示是否选择了组 j。令 A 为二元矩阵,使得 Aij 为 1 当且仅当项目 i 存在于组 j 中。那么整数程序是:

min Ei,j (xjAij)

s.t. Ej xjAij >= 1 对于P 中的所有 i。

xj = 0, 1 代表所有 j。

注意,上述IP的最优解减去|P|可以得到最小的浪费。

【讨论】:

  • 谢谢,我已经有一个 IP 公式可以解决这个问题 - 但我希望不必在我的 SA 的每次迭代中调用求解器 :(
  • 当种群和组是任意的时,我认为不可能避免在每次迭代中调用 IP。
【解决方案2】:

你是说Maximum matching的问题吗?

您需要构建一个bipartite graph,其中一侧是您的人口,另一侧是群体,如果在其集合中存在组 A 和群体 B 之间的边。

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

【讨论】:

  • 恐怕您的两种建模方法都对给定的问题没有帮助。
【解决方案3】:

看看加权集合覆盖问题,我想这正是你上面描述的。 (未加权)问题的基本描述可以在here 找到。

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

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

【讨论】:

    猜你喜欢
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    相关资源
    最近更新 更多