排列生成算法
排列生成法探讨了排列的组织方式。
参考书目:《卢开澄-组合数学(2006)第四版》
学习目标:
- Python代码实现字典序法、换位法
记录时间:
- 2023.9.27
学习内容:
字典序法
思路
代码
def dict_generate(n):
"""
使用字典序法生成 1-n的所有排列
书p17
"""
arr = []
cnt = 1
# 初始化为 1,2,...,n
for i in range(n):
arr.append(i+1)
print(arr)
while True:
i=-1
for j in range(1,n):
if arr[j-1] < arr[j]:
i = j
if i==-1 : # 找不到这样的i,算法结束
break
h = -1
for k in range(0,n):
if arr[i-1] < arr[k]:
h = k
# 互换
arr[h], arr[i-1] = arr[i-1], arr[h]
# 逆置i之后的
arr[i:] = arr[len(arr)-1:i-1:-1]
print(arr)
cnt += 1
print(f"total:{cnt}")
换位法
思路
代码
def swap_generate(n):
"""
使用换位法生成 1-n的所有排列
书p18
"""
arr = []
cnt = 1
# 生成初始箭头全往左的数组 -1 代表往左, 1 代表往右
for i in range(n):
arr.append([i+1, -1])
print([arr[i][0] for i in range(n)] ) # 打印初始数组
while True:
next_index = -1
m = -1 # 假设这是最小最小的值,因为1-n,最小也才1
for i in range(n): # 找到m
direction = arr[i][1]
if i+direction < 0 or i+direction == n:
continue
if arr[i][0] > arr[i+direction][0]:
if m < arr[i][0]:
m = arr[i][0]
next_index = i
if next_index == -1: # 找不到处于活动状态的数了
break
# 互换
direction = arr[next_index][1]
arr[next_index], arr[next_index + direction] = arr[next_index + direction], arr[next_index]
# 改变比m大的所有数的方向
for i in range(n):
if arr[i][0] > m:
arr[i][1] = -arr[i][1]
print([arr[i][0] for i in range(n)] ) # 打印数组
cnt += 1
print(f"total:{cnt}")
改进
算法思路:
def swap_generate2(n):
学习小结:
提示:这里统计学习计划的总量