带权中位数问题:
1.带权中位数
我国蒙古大草原上有N(N是不大于100的自然数)个牧民定居点P1(X1,Y1)、P2(X2,Y2)、 …Pn(Xn,Yn),相应地有关权重为Wi,现在要求你在大草原上找一点P(Xp,Yp),使P点到任 一点Pi的距离Di与Wi之积之和为最小。
即求 D=W1*D1+W2*D2+…+Wi*Di+…+Wn*Dn 有最小值
结论:对x与y两个方向分别求解带权中位数,转化为一维。
设最佳点p为点k,则点k满足:
令W为点k到其余各点的带权距离之和,则
sigema( i=1 to k-1) Wi*Di < = W/2
sigema( i=k+1 to n) Wi*Di < = W/2
同时满足上述两式的点k即为带权中位数。
我们都学过中位数问题,即给定了
N
个数后,位于第
[N/2]
的数就是中位数。所谓带权中位数,就是给定的
N
个数都有一个权值,或者说相当于个数。此时的中位数就不再是第
[N/2]
个数了,而是第
[
∑
D[I]
/2
]
个数。
而在信息学竞赛中,有这样一类题,给出了若干个排列在一条直线上的点,每个点有一个权值,比如说货物量、人数什么的,然后让我们找出使所有点的货物、人集合到一个点的总代价最小的位置。我们将会发现,这一类问题实际上就是带权中位数问题。
{
一些符号的意思:
D[I]
—第
I
个点的权值
DIST
(
I
,
J
)—
I
到
J
点的距离,即
DIST
(
I
,
J
)
=|NUM[I]-NUM[J]|
由定义式易知:
DIST
(
I
,
J
)
=DIST
(
J
,
I
)
}
证明(简):
若最优点在
T
则有:
∑
{D[I]*DIST(I
,
T)}(I<>T)<=
∑
{D[I]*DIST(I,T+1)}(I<>T+1)
将此式化为:
∑
{D[L]}*DIST(L,T)}+∑
{D[R]*DIST(R,T)}+D[T+1]*DIST(T+1,T)
<=∑
{D[L]}*DIST(L,T+1)}+∑
{D[R]*DIST(R,T+1)}+D[T]*DIST(T,T+1) (L<T&R>T+1)
即:
∑{D[L]*DIST(L,T+1)}-∑{D[L]*DIST(L,T)}(L<T)+D[T]*(DIST(T,T+1))
>=∑{D[R]*DIST(R,T)}-∑(D[R]*DIST(R,T+1))(R>T+1)+D[T+1]*(DIST(T,T+1))
进一步化简为:
∑{D[L]*(DIST(L,T)-DIST[L,T+1])}(L<=T)<=∑{D[R]*(DIST(R,T+1)-DIST(R,T))}(R>=T+1)
∵
DIST(L,T)-DIST(L,T+1)=DIST(T,T+1)
DIST(R,T+1)-DIST(R,T)=DIST(T+1,T)
OBVIOUSLY : DIST(T,T+1)=DIST(T+1,T)
因此:
∑
D[L](L<=T)>=
∑
(D[R])(R>=T+1)
即:∑
D[L](L<T)+D[T]>=
∑
(D[R])(R>T)
因此我们发现,若
T是最优点,则必有其左边的权值和加上
D[T]后大于右边的权值和
而类似的,我们可以证明其右边的权值和加上
D[T]后大于左边的权值和
因此我们要找的点也就是满足以上条件的点。注意到此时我们的选择已经和具体的位置(坐标)没有关系了,而成为主要考虑因素的仅仅是各点上的权值。
因为左边的权值和数+
D[T]>=右边的权值和,那么:
LEFTSUM+D[T]>=
RIGHTSUM=
SUMALL-(LEFTSUM+D[T])
=>2*(LEFTSUM+D[T])>=
SUMALL
=>2*RIGHTSUM<=
SUMALL
同理可得:
RIGHTSUM+D[T]>=
LEFTSUM=
SUMALL-(RIGHTSUM+D[T])
=>2*(RIGHTSUM+D[T])>=
SUMALL
=>2*LEFTSUM<=
SUMALL
此时我们发现:
2*LEFTSUM<=
SUMALL 而
2*(LEFTSUM+D[T])>=
SUMALL
也即是说当前的位置
T上的数包含了第[(
SUMALL)/2]个数,由开篇的简述可知,这第[(
SUMALL)/2]个数,就是这个序列中的带权中位数。所以这一类问题,实质上就是带权中位数问题。
证明的简单说明:
我们可以简单地把上面的证明过程看作是左边的人都集合到了M点,而右边的人都集合到了M+1点。此时形成了两军对垒的形式,如果左边的总人数比右边的多,那么从左边走到右边去就没有从右边走到左边来优,反之亦然。那么既然在当前点我们左边的总人数已经比右边多了,那么再往右边移动,左边的人数会进一步增多,而右边的人会减少,那么只会导致更差的结果,所以此时我们可以判断最优点一定在当前点的左边,或者至少在当前这个点。那么范围就从当前的[L,R]缩小到了[L,M],通过不断地缩小范围(而每一次缩小我们都砍掉了一半的范围),最后我们得到的将是一个点——那就是我们要求的集合位置。
NOTIFY THAT THE CHOICE OF THE MEETPLACE HAS NOTHING TO DO WITH THE DISTANCES
!!
最优位置的选择与距离无关!!
带权中位数问题常见算法:
1
:朴素算法:
方法:枚举集合点,进行计算
时间复杂度:
O
(
N^2
)
2
:递推算法:
1
.朴素递推:
方法:分别计算对于一个点从左右过来的总代价,求其最小值
时间复杂度:
O
(
N
)
2
.
递推改进算法
方法:利用前面证明的结论和带权中位数的定义,只需要一次扫描即可
时间复杂度:
O
(
N
)
3
:分治算法:
1.
O
(
NlogN
)
的算法
方法:二分集合点,比较集合点为
M
与
M+1
时的谁更优,不断缩小范围
2.
O
(
N
)
的二分改进算法
方法:二分集合点,但利用了已知信息,将时间复杂度降到
O
(
N
)
附录:
证明二分优化后的时间复杂度:
由于是二分,所以共执行了
logN
次
最后一次的次数是
1
,之后依次递增:
即:
2^0+2^1+…..+2^(logN)=2^(logN+1)-1=2*N-1
所以时间复杂度为:
O(N)
{
更新于
2006-10-24
晚
21
:
34
分
UPDATED AT 21
:
34 IN
OCT 24TH
,
2006
}
优化后的二分实现:采用类似二分查找的迭代法
1.
SET
L=1
;
R=N
;
2.
WHILE
(L<=R) DO
3.
M=(L+R)/2;
4.
IF
R=L
5.
THEN BREAK
6.
ELSE
CALC_LEFTSUM&RIGHTSUM
7.
COMPARE
LEFTSUM&RIGHTSUM
8.
IF
LEFTSUM >RIGHTSUM
9.
THEN SET
R=M; SET SUM[R]=SUM[R]+RIGHTSUM
10. ELSE IF LEFTSUM<RIGHTSUM
11. THEN SET L=M+1; SET SUM[L]=SUM[L]+LEFTSUM
12 .ELSE BREAK
13. IF NOT BREAK THEN BACK TO 2
14
SET
MEETPLACE=M
15 CALC THE COST TO GET ALL TOGETHER AT MEETPLACE
即:
1.
设置初始的左右边界
LR
2.
若左右边界
LR
未错位
3.
计算二分点
M
的位置
4.
若左右边界已重合
5.
则此时的二分点
M
就是最优点
6.
否则计算
1~M
的和
LEFTSUM
、
M+1~N
的和
RIGHTSUM
7.
比较
LEFTSUM
和
RIGHTSUM
8.
若
LEFTSUM
大于
RIGHTSUM
9.
则最优点在当前
M
的左边
10.
置左边界为
M+1
,把
LEFTSUM
加到
SUM[L]
上
11.
若
RIGHTSUM
大于
LEFTSUM
12.
则最优点在当前
M
的右边(或在
M
点)
13.
置右边界为
M
,把
RIGHTSUM
加到
SUM[R]
上
14.
否则此时的
M
就是最优点
15.
若没有找到最优点则继续迭代
16.
置集合位置
MEETPLACE
为
M
17.
计算到
MEETPLACE
的代价
{
更新于
2006-10-25 8
:
19
UPDATED AT 8
:
19
,
OCT 25TH
,
2006
}
递推改进算法的实现:
1.
CALC THE SUM OF ALL POINTS
2.
SET
M=1
3.
WHILE
LEFTSUM+SUM[M]<(SUM-ALL DIV 2) DO
4.
SET
LEFTSUM=LEFTSUM+SUM[M] SET M=M+1
5.
SET
MEETPLACE=M
6.
CALC THE COST TO GET ALL TOGETHER TO MEETPLACE
即:
1.
计算总的人数和
2.
从
1
开始计算
3.
若满足左边的总人数
+
当前点的人数
<
总人数的一半
4.
则把当前点的人数累加到
LEFTSUM
中,同时
M
向后移动一位
5.
满足左边的人数和
+
当前点的人数和的点就是我们的最优点
6.
计算到
MEETPLACE
总代价