假设我有一个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组)。
答案 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)