当您搜索 Google 时,结果显示在第二位以下 - 从最相关到最不相关排列。当 Netflix 推荐电影时,它会根据您喜欢的可能性对数千部影片进行排序。每个快速查找和每个排名列表的背后都有一个排序或搜索算法。
排序后的数据是强大的数据。整理好列表后,您可以:
冒泡排序重复遍历列表,比较相邻的项目,如果顺序错误则交换它们。较大的值会“冒泡”到底。
[5, 3, 8, 1, 2]
↕
[3, 5, 8, 1, 2] → swapped 5 and 3
[3, 5, 1, 8, 2] → swapped 8 and 1
[3, 5, 1, 2, 8] → swapped 8 and 2
... keep going until no swaps needed
时间复杂度:O(n²) - 对于 n 个项目中的每一个,您可以与所有其他项目进行比较。对于 1,000 个项目,最多可进行 1,000,000 次比较。拥有 1,000,000 件物品?一万亿次比较。对于人工智能工作负载来说不实用。
如果冒泡排序大约进行 n2 次比较,那么对 100 万个项目进行排序与对 1000 个项目进行排序相比会慢多少?考虑一下比率:(1,000,000)² 与 (1,000)²。仅仅因为数据量增加了一千倍,速度就慢了一百万倍。
合并排序采用更聪明的方法:将列表分成两半,对每一半进行排序,然后将已排序的两半合并在一起。
[5, 3, 8, 1, 2, 7, 4, 6]
split
[5, 3, 8, 1] [2, 7, 4, 6]
split split
[5, 3] [8, 1] [2, 7] [4, 6]
↓ ↓ ↓ ↓
[3, 5] [1, 8] [2, 7] [4, 6]
merge merge
[1, 3, 5, 8] [2, 4, 6, 7]
merge
[1, 2, 3, 4, 5, 6, 7, 8]
时间复杂度:O(n log n) - 速度显着加快。对于 100 万个商品,大约需要 2000 万次比较,而不是 1 万亿次。这种算法使真正的人工智能系统成为可能。
Python 的内置排序使用 Timsort——一种结合了合并排序和插入排序的混合算法。它由 Tim Peters 于 2002 年发明,现在用于 Python、Java 和 Android。它经过专门设计,可以在通常已部分排序的现实数据上表现良好。
|项目 |冒泡排序 (O(n²)) |归并排序 (O(n log n)) | |--------|---------------------|------------------------| | 100 | 100 10,000 次操作 |约 700 次操作 | | 10,000 | 100,000,000 次操作 |约 130,000 次操作 | | 1,000,000 | 1,000,000,000,000 次操作 |约 20,000,000 次操作 |
这种差异不是学术上的——而是“一秒钟内完成”和“下周完成”之间的差异。
为什么对于人工智能应用中的大型数据集,合并排序优于冒泡排序?
想象一下在电话簿中查找“史密斯”。你不会从第一页开始阅读每个名字。你可以大致从中间打开书,看看你在哪里,然后跳到正确的一半。然后重复。
这就是二分搜索 - 它只适用于排序的数据。
登录 参与讨论
sorted_list = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
target = 23
Step 1: Middle = 16 → 23 > 16, search right half
Step 2: Middle = 38 → 23 < 38, search left half
Step 3: Middle = 23 → Found it!
时间复杂度:O(log n)。在一百万个项目的排序列表中,二分搜索最多需要 20 个步骤才能找到任何项目。线性搜索最多需要一百万步。
已排序的数据库包含 1,000,000 条记录。最坏情况下二分查找需要多少次比较?
当 Google 处理您的查询时,它会对每个相关页面进行评分并按相关性对它们进行排序。前 10 个结果显示在第一页。如果没有高效的排序,这将需要几分钟而不是几毫秒。
Netflix 会根据您的观看历史记录计算数千部影片的“匹配分数”,然后对它们进行排序,首先向您展示最匹配的影片。排序算法直接影响您在主屏幕上看到的内容。
这个经典的 AI 算法会找到与给定输入最相似的 K 个项目。它计算到每个项目的距离,然后进行部分排序以找到 K 个最小距离。高效的排序使得这对于数百万个数据点来说非常实用。
并不总是需要完全排序。如果您只需要一百万个项目中的前 10 个结果,部分排序或 堆 可以在 O(n log k) 时间内找到它们 - 比对所有内容进行排序要快得多。
在训练之前,人工智能从业者经常对数据进行排序以创建平衡的批次 - 确保每个训练批次包含简单和困难示例的混合,或类别的平衡分布。
这是一个至关重要的设计决策:
|场景|最佳选择|为什么 | |----------|------------|-----| |按键查找一项 |哈希图| O(1) 查找 | |查找前 10 项 |排序 |需要订购结果| |检查项目是否存在 |哈希图| O(1) 与 O(log n) | |按顺序获取物品 |排序 |哈希映射没有顺序 | |范围查询(A 和 B 之间的项目)|排序数组+二分查找 |哈希映射不能做范围 |
音乐流媒体服务需要显示您的“播放次数最多的 50 首歌曲”。您会对整个收听历史记录进行排序,还是维护一个始终知道前 50 名的数据结构?每种方法的权衡是什么?
Google 每天处理超过 85 亿次搜索。每次搜索都需要在几毫秒内对数百个潜在结果进行排序和排名。排序算法的效率直接影响谷歌数据中心消耗的电力——更好的算法实际上可以节省兆瓦的电力。
二分查找什么时候不合适?