首页 > 编程语言 >*【学习笔记】(23) 常用距离算法详解

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

时间:2023-08-19 22:34:25浏览次数:42  
标签:right frac 23 曼哈顿 比雪夫 距离 算法 详解 left

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

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

标签:right,frac,23,曼哈顿,比雪夫,距离,算法,详解,left
From: https://www.cnblogs.com/jiangchen4122/p/17641783.html

相关文章

  • jmeter详解-线程组详解(3)-再看Ramp-Up(seconds)
    在jmeter线程组的第一篇文章中对Ramp-Up时间讲过一点:jmeter详解-线程组详解(1)-ThreadGroup 这里我们再来看一下Ramp-Up(seconds)在jmeter中Ramp-Up是什么?JMeterRamp-up周期是以秒为单位,ApacheMeter将花费多少时间将所有测试用户(线程)添加到测试执行中。或者换句话说,需要多......
  • 2023/8/19
    今天又是军训前的轻松的一天上午吃饭,和现充室友一起怒斥现充,后来才意识到我是小丑上午在研姐带领下参观了一下校园md,校园是真的大,每个自行车真的活不了参观了盛宣怀雕像,雕像下面摆着几个柑橘等水果难蚌,听学长说是学生高数考试前放的中午吃的牛排饭,味道中杯,但是价格太高啦......
  • 详解二进制,八进制,十进制,十六进制的原理与转换
    首先了解一下数字系统的由来数字系统是人类为了表示数量和进行计数而创造的一种工具。数字系统的发展可以追溯到古代文明,不同的文化和社会在不同的时间和地点创造了各种数字系统。以下是数字系统的一些关键发展阶段: 早期计数:最早的人类社会使用自然物体如石块、棍子、贝壳等......
  • 欧几里得算法(辗转相除法)-- 计算两个数的最大公约数
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-#递归defgcd(a,b):ifb==0:returnaelse:returngcd(b,a%b)print(gcd(12,16))#非递归defgcd2(a,b):whileb>0:r=a%ba=b......
  • 2023.8.19-假期周进度报告
    本周,主要进行暑期社会调查内容的思考和基本社会调查报告的编写,下周准备继续完成暑期社会调查报告和调查日志的编写,并按要求将它们抄到纸上。本周日,思考社会调查的主题,完成了社会调查的主题,遇到了社会调查写什么好呢的问题,解决方法是想到既然在揽月湾附近,就以揽月湾为主题写一个社......
  • 强化学习算法如何将GPU利用率提高到100%——在线强化学习如何将GPU利用率提升至100%
    一直有个疑问,那就是“强化学习算法如何将GPU利用率提高到100%”,在一些论坛中也有人会提出这样的问题,但是一直也没有人比较正面的回答过这个问题,为此正好自己又想到了这么一个问题,于是想在这里正面的谈论下这个问题。......
  • iBooker 技术评论 20230819:打工是风险最高的事情
    很多人总是认为打工是稳定的事情,因为每个月都有工资到账。但是这个稳定从来不取决于你,是公司所决定的。换句话说,公司想什么时候开除你就什么时候开除你。这么看来,打工毫无稳定可言。根据墨菲定律,如果公司能够迫害你,或者说迫害你的收益大于不这么做,就一定会迫害你。那为什么多数人......
  • COMP3506/7505 算法与数据结构
    AssignmentOne–15%AlgorithmsandDataStructures–COMP3506/7505–Semester2,2023Due:3pmonFridaySeptember1st(week6)SummaryThemainobjectiveofthisassignmentistogetyourhandsdirtywithsomesimpledatastructuresandalgorithmstosolveb......
  • 2023.8 水题记录
    集训回来之后做题频率下来了.1.CF1856DMoreWrong这场CF场上只写出来ABD(主要卡B的证明上了),什么水平?90%交互=binarysearch(暴论)2.CF1851GVladandtheMountains是我没见过的操作.学到了.3.CF1856CToBecomeMax考试的时候没看.很简单.4.CF1270G......
  • 08-调度算法
    08-调度算法一、背景1.CPU调度上下文切换切换CPU的当前任务,从一个进程/线程到另一个保存当前进程/线程在PCB/TCB中的执行上下文(CPU状态)读取下一个进程/线程的上下文CPU调度从就绪队列中挑选一个进程/线程作为CPU将要运行的下一个进程/线程调度程序:挑选进程/线程的内......