news 2026/4/29 5:28:08

从棋盘到代码:手把手教你用Python实现切比雪夫距离(附与曼哈顿、欧氏距离的对比实验)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从棋盘到代码:手把手教你用Python实现切比雪夫距离(附与曼哈顿、欧氏距离的对比实验)

从棋盘到代码:Python实现切比雪夫距离的实战指南

想象一下国际象棋中的国王如何在棋盘上移动——它能够一步走到相邻的任意方向,包括对角线。这种移动方式恰好体现了切比雪夫距离的核心思想:在所有维度中,只考虑最大差异的那个维度。作为数据科学和机器学习中重要的距离度量之一,切比雪夫距离在图像处理、游戏AI和聚类分析等领域有着独特优势。

本文将带您从零开始实现三种经典距离度量:切比雪夫、曼哈顿和欧氏距离。我们不仅会编写Python函数,还会通过可视化对比实验,直观展示它们在不同场景下的表现差异。无论您是正在学习机器学习基础的学生,还是需要优化算法性能的工程师,这些距离度量的深入理解都将为您的工具箱增添实用利器。

1. 距离度量的数学基础

距离度量是衡量空间中两点间差异的数学工具,在机器学习和数据科学中扮演着关键角色。让我们先了解这三种距离的数学定义:

切比雪夫距离(Chebyshev Distance)定义为两点在各坐标轴上数值差绝对值的最大值:

D(x,y) = max(|x₁ - y₁|, |x₂ - y₂|, ..., |xₙ - yₙ|)

曼哈顿距离(Manhattan Distance),又称城市街区距离,是各坐标轴差值的绝对值之和:

D(x,y) = Σ|xᵢ - yᵢ|

欧氏距离(Euclidean Distance)则是我们最熟悉的直线距离,计算各坐标差值的平方和的平方根:

D(x,y) = √(Σ(xᵢ - yᵢ)²)

这三种距离实际上是闵可夫斯基距离(Minkowski Distance)的特例:

距离类型闵可夫斯基参数p几何特性典型应用场景
曼哈顿距离1只允许沿坐标轴移动城市导航、特征选择
欧氏距离2直线最短路径空间分析、聚类
切比雪夫距离允许任意方向移动棋盘游戏、图像处理

提示:切比雪夫距离之所以对应p=∞,是因为当p趋近于无穷大时,最大差值项将主导整个距离计算。

2. Python实现三种距离函数

现在让我们用NumPy来实现这三种距离计算。首先确保安装了必要的库:

pip install numpy matplotlib

2.1 基础距离函数实现

import numpy as np def euclidean_distance(x, y): """计算欧氏距离""" x = np.array(x) y = np.array(y) return np.sqrt(np.sum((x - y)**2)) def manhattan_distance(x, y): """计算曼哈顿距离""" x = np.array(x) y = np.array(y) return np.sum(np.abs(x - y)) def chebyshev_distance(x, y): """计算切比雪夫距离""" x = np.array(x) y = np.array(y) return np.max(np.abs(x - y))

2.2 向量化计算优化

对于需要批量计算距离的场景,我们可以利用NumPy的广播机制进行优化:

def batch_distances(points, ref_point, metric='chebyshev'): """批量计算点到参考点的距离""" points = np.array(points) ref_point = np.array(ref_point) diffs = np.abs(points - ref_point) if metric == 'chebyshev': return np.max(diffs, axis=1) elif metric == 'manhattan': return np.sum(diffs, axis=1) elif metric == 'euclidean': return np.sqrt(np.sum(diffs**2, axis=1)) else: raise ValueError("不支持的度量类型")

3. 可视化对比实验

理解距离度量最直观的方式就是观察它们的"等距离线"——即到中心点距离相等的所有点构成的图形。

3.1 生成等距离线数据

import matplotlib.pyplot as plt def plot_distance_contours(metric, levels=[1, 2, 3], title=None): """绘制指定距离度量的等距离线""" x = np.linspace(-3, 3, 500) y = np.linspace(-3, 3, 500) X, Y = np.meshgrid(x, y) points = np.stack([X.ravel(), Y.ravel()], axis=1) if metric == 'chebyshev': Z = batch_distances(points, [0, 0], 'chebyshev') elif metric == 'manhattan': Z = batch_distances(points, [0, 0], 'manhattan') else: Z = batch_distances(points, [0, 0], 'euclidean') Z = Z.reshape(X.shape) plt.figure(figsize=(6, 6)) plt.contour(X, Y, Z, levels=levels, colors='blue') plt.grid(True) plt.axis('equal') plt.title(title or f"{metric}距离等值线") plt.xlabel('X轴') plt.ylabel('Y轴') plt.show()

3.2 等距离线对比分析

让我们同时绘制三种距离的等距离线:

plt.figure(figsize=(15, 5)) metrics = ['chebyshev', 'manhattan', 'euclidean'] titles = ['切比雪夫距离 (L∞)', '曼哈顿距离 (L1)', '欧氏距离 (L2)'] for i, (metric, title) in enumerate(zip(metrics, titles)): plt.subplot(1, 3, i+1) plot_distance_contours(metric, title=title, levels=[1, 2, 3]) plt.gca().set_aspect('equal')

观察这些图形,我们可以发现:

  • 切比雪夫距离的等距离线是正方形,反映了"国王可以朝任何方向移动"的特性
  • 曼哈顿距离的等距离线是旋转45度的正方形,模拟了城市街区只能沿街道行走的情况
  • 欧氏距离的等距离线则是完美的圆形,符合我们对"直线距离"的直觉

4. 实际应用场景分析

不同距离度量适用于不同场景,理解它们的特性有助于我们做出正确选择。

4.1 切比雪夫距离的典型应用

  1. 棋盘游戏AI:在国际象棋等游戏中,计算棋子移动距离
  2. 图像处理:检测图像中的矩形特征或最大差异
  3. 工业质量控制:当产品合格标准由最大偏差决定时
  4. 并行计算:衡量处理器间的最大延迟差异

4.2 聚类算法中的距离选择

让我们用不同距离度量进行简单的聚类实验:

from sklearn.cluster import KMeans # 生成测试数据 np.random.seed(42) data = np.random.randn(100, 2) * [3, 1] + [5, 2] # 自定义距离度量函数 def custom_metric(x, y): return chebyshev_distance(x, y) # 使用切比雪夫距离进行聚类 kmeans = KMeans(n_clusters=3, n_init=10) kmeans.fit(data) # 可视化聚类结果 plt.scatter(data[:, 0], data[:, 1], c=kmeans.labels_) plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], marker='x', s=200, linewidths=3, color='r') plt.title("使用切比雪夫距离的聚类结果") plt.show()

注意:虽然这个例子使用了K-Means,但严格来说K-Means是基于欧氏距离的算法。要实现真正的切比雪夫距离聚类,需要使用如K-Medoids等支持自定义距离的算法。

5. 性能比较与优化建议

在实际应用中,距离计算可能成为性能瓶颈,特别是在高维数据或大规模数据集上。让我们比较三种距离的计算效率:

import time def time_distance_calc(metric, dim=1000, size=10000): """测试距离计算性能""" data = np.random.randn(size, dim) ref = np.zeros(dim) start = time.time() if metric == 'chebyshev': [chebyshev_distance(x, ref) for x in data] elif metric == 'manhattan': [manhattan_distance(x, ref) for x in data] else: [euclidean_distance(x, ref) for x in data] return time.time() - start # 性能测试 dims = [10, 100, 1000] results = {} for dim in dims: times = [] for metric in ['chebyshev', 'manhattan', 'euclidean']: elapsed = time_distance_calc(metric, dim=dim) times.append(elapsed) results[dim] = times

测试结果通常显示:

  1. 曼哈顿距离计算最快,因为它只涉及绝对值和加法
  2. 切比雪夫距离次之,需要额外的最大值操作
  3. 欧氏距离最慢,因为涉及平方和平方根运算

优化建议

  • 对于高维数据,考虑使用更简单的距离度量
  • 利用NumPy的向量化操作替代循环
  • 对于稀疏数据,只计算非零维度差异
  • 在机器学习中,可以预先计算和缓存距离矩阵
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 5:26:10

Caret包:R语言机器学习全流程自动化实战指南

1. 项目概述:Caret包在预测建模中的应用价值第一次接触caret包是在2013年处理一个工业设备故障预测项目时。当时需要快速比较多种机器学习算法的表现,手动编写每个模型的交叉验证代码让我苦不堪言。直到发现caret这个"瑞士军刀"般的工具包&…

作者头像 李华
网站建设 2026/4/29 5:26:09

金融领域LLM评估新标准:BizFinBench.v2实战解析

1. 项目背景与核心价值金融行业每天产生海量业务数据,但如何评估大语言模型(LLM)在这些真实场景中的表现一直是个难题。传统评估基准多使用模拟数据或公开数据集,无法反映模型在实际业务环境中的真实能力。BizFinBench.v2的推出填…

作者头像 李华
网站建设 2026/4/29 5:22:24

收藏!AI时代,程序员已不稀缺,掌握这项能力才是关键

AI编程工具的飞速发展使得写代码的速度远超产品方案构思的速度,编程不再是稀缺技能。吴恩达和傅盛指出,技术能力的稀缺性下降导致产品想法的稀缺性上升,产品经理需从“功能定义者”转变为“AI指令精准设计者”。未来,判断力——即…

作者头像 李华
网站建设 2026/4/29 5:21:20

【桂林电子科技大学主办,SPIE (ISSN: 0277-786X)出版,往届均已见刊病连续多届EI核心稳定检索】第十一届机电控制技术与交通运输国际学术会议(ICECTT 2026)

第十一届机电控制技术与交通运输国际学术会议(ICECTT 2026) 2026 11th International Conference on Electromechanical Control Technology and Transportation 2026年6月5日至7日,中国桂林 大会官网:www.icectt.net 【参会投…

作者头像 李华
网站建设 2026/4/29 5:19:24

Armbian 22.05版本更新与ARM开发板支持解析

1. Armbian 22.05版本更新概览Armbian社区于2022年5月发布了22.05稳定版,这是继2月22.02版本后的重要更新。作为专为ARM架构优化的轻量级Linux发行版,本次更新延续了Armbian一贯的稳定性优先策略,同时带来了四款新开发板的官方支持。我注意到…

作者头像 李华