给出n组数字。每个集合包含1到100之间的一些数字。如何选择要合并到特殊规则下的最长集合的集合,只有两个非重叠集合可以合并。 [1,2,3]可以与[4,5]合并,但不能合并[3,4]。什么是合并到最长集合的有效算法。
我的第一次尝试是形成一个n乘n矩阵。每行/每列代表一组。如果两个集合重叠,则条目(i,j)等于1,条目(i,i)存储集合i的长度。然后问题就变成我们可以同时执行行和列操作,在左上角创建一个对角子矩阵,其轨迹尽可能大。
然而,我陷入了如何有效地执行行和列操作以在左上角形成这样的对角子矩阵。
答案 0 :(得分:2)
正如评论中已经指出的(最大覆盖率问题),你有一个NP-hart问题。幸运的是,matlab提供了整数线性编程的求解器。
所以我们尝试将问题缩小到以下形式:
min f*x subject to Ax<=b , 0<=x
有n组,我们可以将一组编码为0和1的向量。例如,(1,1,1,0,0,...)
代表{1,2,3}
和(0,0,1,1,0,0...)
- {3,4}
。
A
的每一列代表一组。 A(i,j)=1
表示i
- 元素位于j
集合中,A(i,j)=0
表示i
- 元素不在j
元素中1}} - 集合。
现在,x
代表我们选择的集合:如果选择x_j=1
而不是集合j
,则x_j=0
- 而不是未选中!
由于每个元素最多只能在一个集合中,我们选择b=(1, 1, 1, ..., 1)
:如果我们选择两个包含i
- 元素的集合,而不是i
- 元素(Ax)
至少为2。
唯一的问题是f
是什么?我们尝试最大化联合中元素的数量,因此我们选择f_j=-|set_j|
(减去由于min&lt; - &gt;最大转换),|set_j|
- j
中的元素数量-th set。
把它全部放在matlab中我们得到:
f=-sum(A)
xopt=intlinprog(f.',1:n,A,ones(m,1),[],[],zeros(n,1),ones(n,1))
f.'
- 费用函数列为1:n
- n
的所有x
元素都是整数A
- 对n
套ones(m,1)
- b=(1,1,1...)
,有m=100
个元素[],[]
- 没有形式Aeq*x=beq
zeros(n,1), 0<=x
必须持有ones(n,1), x<=1
已经来自其他人的约束,但也许它会帮助解决方案一点点答案 1 :(得分:0)
您可以将集合表示为位字段。按位和操作产生零将指示非重叠集。根据基础数据类型的宽度,您可能需要执行多个操作。例如,对于64位机器字大小,我需要两个字来覆盖1到100作为位字段。