*【学习笔记】(23) 常用距离算法详解

本文主要讲述这三种常见距离算法 :欧氏距离,曼哈顿距离,切比雪夫距离 。

1.欧氏距离

欧氏距离 是最易于理解的一种距离算法。在数学的平面直角坐标系中,设点 \(A,B\) 的坐标分别为 \(A(x_1,y_1),B(x_2,y_2)\),求点 \(A,B\) 之间的距离,我们一般会使用如下公式:

\[\left | AB \right | = \sqrt{\left ( x_2 - x_1 \right )^2 + \left ( y_2 - y_1 \right )^2} \]

实际上这就是平面(二维空间)中两点欧氏距离的距离公式,除此之外,\(P(x,y)\) 到原点的欧氏距离可以用公式表示为:

\[\left | P \right | = \sqrt{x^2+y^2} \]

三维空间 中欧氏距离的距离公式为:

\[\left | AB \right | = \sqrt{\left ( x_2 - x_1 \right )^2 + \left ( y_2 - y_1 \right )^2 + \left ( z_2 - z_1 \right )^2} \]

\[\left | P\right | = \sqrt{x^2+y^2+z^2} \]

以此类推,我们就得到了 \(n\) 维空间 中欧氏距离的距离公式:

VDS69x.png

欧氏距离 的一般模型:

在一个坐标系上,求从一个点到另一个点的最短距离。

欧氏距离 的缺点:

两个整点计算其欧氏距离时,往往答案是浮点型,会存在精度误差。

2.曼哈顿距离

二维空间 内,两个点之间的曼哈顿距离为它们横坐标之差的绝对值与纵坐标之差的绝对值之和。设点 \(A(x_1,y_1),B(x_2,y_2)\),则 \(A,B\) 之间的曼哈顿距离用公式可以表示为:

\[d(A,B) = \left | x_1 - x_2\right | + \left | y_1 - y_2 \right | \]

Vdq3QI.png

\(n\) 维空间 的曼哈顿距离公式:

VDSggK.png

三角不等式

从点 \(i\)\(j\) 的直接距离不会大于途经的任何其它点 \(k\) 的距离。

\(d(i,j)\leq d(i,k)+d(k,j)\)

3.切比雪夫距离

二维空间 内,两个点之间的切比雪夫距离为它们横坐标之差的绝对值与纵坐标之差的绝对值的最大值。设点 \(A(x_1,y_1),B(x_2,y_2)\),则 \(A,B\) 之间的切比雪夫距离用公式可以表示为:

\[d(A,B) = \max(\left | x_1 - x_2\right | , \left | y_1 - y_2\right | ) \]

\(n\) 维空间 的切比雪夫距离公式:

VDSo4I.png

4.二维曼哈顿距离与切比雪夫距离的相互转化

假设 \(A(x_1,y_1),B(x_2,y_2)\)

\(A,B\) 两点的 曼哈顿距离 为:

ZncwlV.md.png

我们很容易发现,这就是 \((x_1 + y_1,x_1 - y_1), (x_2 + y_2,x_2 - y_2)\) 两点之间的 切比雪夫距离

所以将每一个点 \((x,y)\) 转化为 \((x + y, x - y)\),新坐标系下的 切比雪夫距离 即为原坐标系下的 曼哈顿距离

同理,\(A,B\) 两点的 切比雪夫距离 为:

VDS5Ed.md.png

而这就是 \(\left(\frac{x_1 + y_1}{2},\frac{x_1 - y_1}{2}\right),\left (\frac{x_2 + y_2}{2},\frac{x_2 - y_2}{2}\right)\) 两点之间的 曼哈顿距离

所以将每一个点 \((x,y)\) 转化为 \(\left(\frac{x + y}{2},\frac{x - y}{2}\right)\),新坐标系下的 曼哈顿距离 即为原坐标系下的 切比雪夫距离

结论:

将切比雪夫坐标系旋转 \(45^\circ\),再缩小到原来的一半,即可得到曼哈顿坐标系。

将点 \((x,y)\) 的坐标变为 \((x + y, x - y)\)

原坐标系中的 曼哈顿距离 \(=\) 新坐标系中的 切比雪夫距离

将点 \((x,y)\) 的坐标变为 \(\left( \frac{x + y}{2},\frac{x - y}{2} \right)\)

原坐标系中的 切比雪夫距离 \(=\) 新坐标系中的 曼哈顿距离

碰到求 切比雪夫距离曼哈顿距离 的题目时,我们往往可以相互转化来求解。两种距离在不同的题目中有不同的优缺点,要学会做出正确的选择。

例题

Ⅰ. P3964 [TJOI2013] 松鼠聚会

很容易看出这道题属于 切比雪夫距离 的一般模型。即对于两个点 \((x_1, y_1),(x_2,y_2)\),它们之间的距离为

\[\max(\left | x_1 - x_2\right | , \left | y_1 - y_2\right | ) \]

直接求 切比雪夫距离 似乎很困难?考虑把 切比雪夫距离 转化为 曼哈顿距离,即把每个点的坐标 \((x,y)\) 变为 \(\left(\frac{x + y}{2}, \frac{x - y}{2} \right)\)

枚举所选的点 \(i\),我们只需要计算其它点到它的曼哈顿距离和即可。

如果某个点 \(j\) 的横坐标 \(x_j \leq x_i\),则它的对总距离的贡献为 \(x_i - x_j\),反之则为 \(x_j - x_i\)

这样就可以分两种情况讨论了。

设前 \(k\) 个点的横坐标都 \(\leq x_i\),那么所有点横坐标的贡献和为

ZnGuuV.png

对于 \(\sum\limits_{i = 1}^k x_i\)\(\sum\limits_{i = k + 1}^n x_i\),我们可以预处理出 \(x\) 的前缀和后 \(O(1)\) 求得。

怎么求 \(k\) 呢?显然可以将横坐标排序后二分得到。

纵坐标 \(y\) 的计算方法与上面一样。时间复杂度为 \(O(n \log n)\)

切比雪夫距离 转成 曼哈顿距离 时要除以 \(2\),为了避免出现小数,我们可以横坐标和纵坐标同时乘上 \(2\),最后答案除以 \(2\)

#include<bits/stdc++.h>
#define N 100005
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,ans=INF;
int p[N],q[N],x[N],y[N],sumx[N],sumy[N];
signed main(){
	n=read();
	for(int i=1;i<=n;++i){
		int a=read(),b=read();
		x[i]=p[i]=a+b,y[i]=q[i]=a-b;
	} 
	sort(p+1,p+1+n),sort(q+1,q+1+n);
	for(int i=1;i<=n;++i) sumx[i]=sumx[i-1]+p[i],sumy[i]=sumy[i-1]+q[i];
	for(int i=1;i<=n;++i){
		int posx=lower_bound(p+1,p+1+n,x[i])-p;
		int posy=lower_bound(q+1,q+1+n,y[i])-q;
		int sx=posx*x[i]-sumx[posx]+sumx[n]-sumx[posx]-(n-posx)*x[i];
		int sy=posy*y[i]-sumy[posy]+sumy[n]-sumy[posy]-(n-posy)*y[i];
		ans=min(ans,sx+sy);
	}
	printf("%lld\n",ans/2);
	return 0;
} 

Ⅱ.AT_code_festival_2017_quala_dFour Coloring

Ⅲ. P3439 [POI2006] MAG-Warehouse

Ⅳ. P2906 [USACO08OPEN] Cow Neighborhoods G

Ⅴ. P4648 [IOI2007] pairs 动物对数

摘自:https://www.luogu.com.cn/blog/xuxing/Distance-Algorithm

posted @ 2023-08-19 22:18  Aurora-JC  阅读(75)  评论(0编辑  收藏  举报