pin_drop当前位置:知识文库 ❯ 图文

itertools.permutations详解 - Python排列与路径规划

一、概述

itertools.permutations 是 Python 标准库 itertools 模块中的组合迭代器之一,用于生成可迭代对象中元素的所有排列。排列是指从 n 个元素中取出 r 个元素,按照一定顺序进行排列,顺序不同则视为不同的排列。

如果不指定 r,则默认生成所有元素的全排列。排列在密码学、概率统计、路径规划、算法设计等领域有广泛应用。


二、语法

代码示例

itertools.permutations(iterable, r=None)

三、参数说明

参数 类型 必填 默认值 说明
iterable 可迭代对象 需要排列的元素集合
r int None 每个排列的长度。若为 None,则 r 等于输入元素个数(全排列)

四、返回值

返回一个迭代器对象,产生所有长度为 r 的排列元组。排列按照输入可迭代对象中的元素顺序生成。结果总数为 P(n, r) = n! / (n-r)!,其中 n 为输入元素个数。


五、代码示例

示例1:全排列

代码示例

import itertools

# 3个元素的全排列
perms = list(itertools.permutations([1, 2, 3]))
print("全排列:")
for p in perms:
    print(p)
print(f"总数: {len(perms)}")

# 输出:
# 全排列:
# (1, 2, 3)
# (1, 3, 2)
# (2, 1, 3)
# (2, 3, 1)
# (3, 1, 2)
# (3, 2, 1)
# 总数: 6

3 个元素的全排列有 3! = 6 种。permutations 按照字典序生成排列,保证结果的可预测性。

示例2:部分排列

代码示例

import itertools

# 从4个元素中取2个排列
perms = list(itertools.permutations('ABCD', 2))
print("取2个排列:", perms)
print(f"总数: {len(perms)}")

# 输出:
# 取2个排列: [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C')]
# 总数: 12

从 4 个元素中取 2 个排列,结果为 P(4,2) = 4! / (4-2)! = 12 种。注意 ('A', 'B')('B', 'A') 是不同的排列。

示例3:实际应用——旅行商问题

代码示例

import itertools

# 旅行商问题:找出访问所有城市的最短路径
cities = ['北京', '上海', '广州', '深圳']
distances = {
    ('北京', '上海'): 1200, ('北京', '广州'): 2100, ('北京', '深圳'): 2200,
    ('上海', '广州'): 1300, ('上海', '深圳'): 1400,
    ('广州', '深圳'): 140,
}

def get_distance(a, b):
    return distances.get((a, b), distances.get((b, a), float('inf')))

# 穷举所有路径(不含起点)
best_route = None
min_dist = float('inf')
for perm in itertools.permutations(cities[1:]):
    route = [cities[0]] + list(perm)
    total = sum(get_distance(route[i], route[i+1]) for i in range(len(route)-1))
    if total < min_dist:
        min_dist = total
        best_route = route

print(f"最短路线: {' -> '.join(best_route)}")
print(f"总距离: {min_dist} km")

# 输出:
# 最短路线: 北京 -> 上海 -> 广州 -> 深圳
# 总距离: 2640 km

这是 permutations 的经典应用:旅行商问题(TSP)。通过穷举所有可能的访问顺序,找出最短路径。对于少量城市,这种方法简单有效。


六、实际应用场景

  • 路径规划:穷举所有可能的访问顺序,寻找最短路径(旅行商问题)

  • 密码学:生成所有可能的排列组合用于密码分析

  • 赛程安排:生成所有可能的比赛对阵顺序


七、注意事项

注意1:排列数量随元素个数呈阶乘增长,P(10,10) = 3628800,P(15,15) 约为 1.3 万亿。对于较大的 n,请谨慎使用。

注意2permutations 基于元素的位置进行排列,而非元素的值。如果输入中有重复元素,结果中也会出现"重复"的排列(它们在值上相同,但来自不同位置)。

注意3:如果 r 大于输入元素个数,则返回空迭代器。

提示:如果需要去重排列(输入有重复元素时),可以用 set() 去重:set(permutations(iterable, r))


八、相关方法对比

特性 itertools.permutations itertools.combinations itertools.product
是否考虑顺序
元素是否可重复选取
结果数量 n!/(n-r)! C(n,r) m^n
典型用途 排列问题、路径规划 组合问题、选择 笛卡尔积、全组合
输入重复元素处理 产生值重复的排列 产生值重复的组合 正常处理

九、小结

  • permutations 生成所有排列,考虑顺序,不允许重复选取同一元素

  • 不指定 r 时生成全排列,指定 r 时生成部分排列

  • 结果数量为阶乘级增长,大数据集需谨慎

  • 输入有重复元素时,结果中可能包含值相同的排列


十、练习题

练习1

使用 permutations 生成字符串 'LOCK' 中所有 3 个字母的排列,并统计总数。

练习2

给定列表 [1, 1, 2],使用 permutations 生成全排列,然后用 set() 去重,观察去重前后的数量差异。

练习3

有 5 名选手参加百米赛跑,使用 permutations 生成所有可能的领奖台组合(前3名),并输出总数。

常见问题

permutations 和 product 有什么区别?

permutations 不允许元素重复选取,从同一集合中选取不同位置的元素。而 product 允许同一元素多次出现,因为它将输入集合与自身做笛卡尔积。

输入有重复元素时,如何得到唯一的排列?

permutations 基于元素位置排列,所以输入 [1, 1, 2] 会生成重复的排列。用 set(permutations([1, 1, 2])) 可以去除值相同的重复排列。

r 参数可以大于输入元素个数吗?

如果 r 大于输入元素个数,permutations 会返回空迭代器,因为无法从 n 个元素中选出超过 n 个不同位置的元素。

permutations 可以处理无限迭代器吗?

不可以。permutations 需要先确定输入的元素个数来计算排列,因此不能直接用于无限迭代器。如果必须使用,请先用 islice 截取有限部分。

标签: itertools permutations 排列 旅行商问题 全排列 Python教程 路径规划

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: itertools.product详解 - Python笛卡尔积与全组合 下一篇: itertools.combinations详解 - Python组合与概率计算

poll相关推荐