我有两组整数,A和B,不一定大小相同。根据我的需要,我将每个2个元素a和b(整数)之间的距离设为abs(a-b)
。
我定义了两组之间的距离如下:
我的问题是,根据上面的定义,以下算法(只是一个直观的猜测)给出了正确的答案。
D
m X n
的矩阵D(i,j) = abs(A(i)-B(j))
D
的最小元素,累加它,并删除该元素的行和列。累计下一个最小的条目,并继续累积,直到删除所有行和列。例如,如果A={0,1,4}
和B={3,4}
,那么D
是(上面和左边的元素):
3 4
0
3 4
1
2 3
4
1 0
距离为0 + 2 = 2
,来自将4
与4
和3
与1
配对。
答案 0 :(得分:5)
请注意,此问题有时被称为滑雪板和滑雪者问题,其中您有n个滑雪板和滑雪者,其长度和高度各不相同。目标是将滑雪板与滑雪者相匹配,以便最大限度地减少高度和滑雪板长度之差的总和。
要解决这个问题,你可以使用最小权重二分匹配,这需要O(n ^ 3)时间。
更好的是,使用下面的简单动态编程算法,您可以使用O(n)额外内存实现O(n ^ 2)时间。
最理想的情况是,如果已使用此paper中描述的算法对点进行排序,则可以在线性时间内解决问题。
O(n ^ 2)动态规划算法:
if (size(B) > size(A))
swap(A, B);
sort(A);
sort(B);
opt = array(size(B));
nopt = array(size(B));
for (i = 0; i < size(B); i++)
opt[i] = abs(A[0] - B[i]);
for (i = 1; i < size(A); i++) {
fill(nopt, infinity);
for (j = 1; j < size(B); j++) {
nopt[j] = min(nopt[j - 1], opt[j - 1] + abs(A[i] - B[j]));
swap(opt, nopt);
}
return opt[size(B) - 1];
在上面外部i
循环的每次迭代for
之后,opt[j]
包含使用元素{A[0],..., A[i]}
匹配{B[0],..., B[j]}
的最佳解决方案。
该算法的正确性依赖于以下事实:在任何最佳匹配中,如果a1与b1匹配,则a2与b2匹配,并且a1 <1。 a2,然后b1&lt; = b2。
答案 1 :(得分:2)
为了获得最佳效果,请在D
上解决分配问题。
分配问题在二分图中找到完美匹配,使得总边缘权重最小化,从而完美地映射到您的问题。它也在P。
编辑解释OP的问题如何映射到作业。
为了简化说明,请使用特殊元素e_k
扩展较小的集合。
设A是一组工人,B是任务集(内容只是标签)。
让成本为A和B中的元素之间的距离(即D
的条目)。 e_k
与任何内容之间的距离为0.
然后,我们希望找到A和B的完美匹配(即每个工人与任务匹配),从而使成本最小化。这个 是分配问题。
答案 2 :(得分:1)
否这不是最好的答案,例如:
A:{3,7} 和 B:{0,4} 您将选择: {(3,4),(0,7)} < / strong>且距离为8
,但您应选择 {(3,0),(4,7)} ,在这种情况下,距离为6
。
答案 3 :(得分:0)
您的答案给出了最小值的近似值,但不一定是最佳值。您正在遵循“贪婪”的方法,这种方法通常更容易,并且效果很好,但无法保证最佳答案。