python实现全排列代码(回溯、深度优先搜索)


Posted in Python onFebruary 26, 2020

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

公式:全排列数f(n)=n!(定义0!=1)

1 递归实现全排列(回溯思想)

1.1 思想

举个例子,比如你要对a,b,c三个字符进行全排列,那么它的全排列有abc,acb,bac,bca,cba,cab这六种可能就是当指针指向第一个元素a时,它可以是其本身a(即和自己进行交换),还可以和b,c进行交换,故有3种可能,当第一个元素a确定以后,指针移向第二位置,第二个位置可以和其本身b及其后的元素c进行交换,又可以形成两种排列,当指针指向第三个元素c的时候,这个时候其后没有元素了,此时,则确定了一组排列,输出。但是每次输出后要把数组恢复为原来的样子。

python实现全排列代码(回溯、深度优先搜索)

1.2 python实现

def permutations(arr, position, end):
  if position == end:
    print(arr)
  else:
    for index in range(position, end):
      arr[index], arr[position] = arr[position], arr[index]
      permutations(arr, position + 1, end)
      arr[index], arr[position] = arr[position], arr[index] # 还原到交换前的状态,为了进行下一次交换
 
 
arr = [1, 2, 3, 4]
permutations(arr, 0, len(arr))

2 深度优先搜索(DFS)实现全排列

2.1 思想

定义全排列问题:输入一个长度为n的列表arr,输出arr的全排列。

(1)首先可以确定的是,每一种全排列的结果中包含的列表长度均是n。想象面前有n个空盒子,现在要把这n个数放到这些空盒子里去,每个盒子只能放一个数。那么第一个盒子中可以放的选择是n种,可以使用一个循环来逐个尝试。

for index in range(0, len(arr)):
temp[position] = arr[index]

(2)第一个盒子放完后,就该往第二个盒子里放了。假设第一个盒子里放的是arr的第一个数,那么第二个盒子就只能放第2~n个数了(不能重复)。为此引入visit列表用来标记arr中哪些数字被使用过了。初始化:

visit = [True, True, True, True]

这样,当第一个位置已经使用过时,就在visit里做标记:visit = [False, True, True, True]

因此放第一个盒子的代码可以改写如下:

for index in range(0, len(arr)):
    if visit[index] == True:
      temp[position] = arr[index]
      visit[index] = False

(3)当第k个盒子处理完毕后,处理下一个盒子直接调用dfs(k+1)即可,也就是递归调用。解决了当下该如何做,下一步也就知道怎么做了。

(4)递归调用的一定要注意的问题是递归调用的出口,否则循环调用下去程序会崩溃无法运行。在这个问题中什么时候结束递归调用呢?答案是当这n个盒子都放满了,即处理到第n+1个盒子时结束调用,同时输出此时的排列结果。

2.2 python实现

visit = [True, True, True, True]
temp = ["" for x in range(0, 4)]
 
 
def dfs(position):
  # 递归出口
  if position == len(arr):
    print(temp)
    return
  # 递归主体
  for index in range(0, len(arr)):
    if visit[index] == True:
      temp[position] = arr[index]
      visit[index] = False # 试探 
      dfs(position + 1)
      visit[index] = True # 回溯。非常重要
 
 
arr = [1, 2, 3, 4]
dfs(0)

注释了“非常重要”的语句是不能省略的,省略后仅出现[1, 2, 3, 4]一条结果。dfs(k+1)前后的两条语句分别称之为试探和回溯。

3 combination和permutations函数的区别

permutations方法重在排列:

import itertools
n=3
a=[str(i) for i in range(n)]
s=""
s=s.join(a)
for i in itertools.permutations(s,n):
  print (''.join(i))
 
# 结果  
012
021
102
120
201
210

combinations方法重在组合:

import itertools
n=3
a=[str(i) for i in range(n)]
s=""
s=s.join(a)
for i in itertools.combinations(s,n):
  print (''.join(i))
 
# 结果  
012

以上这篇python实现全排列代码(回溯、深度优先搜索)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
浅谈Python 字符串格式化输出(format/printf)
Jul 21 Python
Python 正则表达式的高级用法
Dec 04 Python
Python开发中爬虫使用代理proxy抓取网页的方法示例
Sep 26 Python
python批量替换页眉页脚实例代码
Jan 22 Python
windows下安装python的C扩展编译环境(解决Unable to find vcvarsall.bat)
Feb 21 Python
Python生成器generator用法示例
Aug 10 Python
详解Python的三种可变参数
May 08 Python
Python日志无延迟实时写入的示例
Jul 11 Python
python代码实现逻辑回归logistic原理
Aug 07 Python
python属于解释型语言么
Jun 15 Python
keras 回调函数Callbacks 断点ModelCheckpoint教程
Jun 18 Python
Django如何在不停机的情况下创建索引
Aug 02 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
Feb 26 #Python
python 使用递归回溯完美解决八皇后的问题
Feb 26 #Python
基于Python数据结构之递归与回溯搜索
Feb 26 #Python
深度学习入门之Pytorch 数据增强的实现
Feb 26 #Python
Python基于Dlib的人脸识别系统的实现
Feb 26 #Python
python 回溯法模板详解
Feb 26 #Python
python实现信号时域统计特征提取代码
Feb 26 #Python
You might like
两个强悍的php 图像处理类1
2009/06/15 PHP
php数组函数序列之array_keys() - 获取数组键名
2011/10/30 PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
2013/06/20 PHP
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
2011/06/28 Javascript
js对象与打印对象分析比较
2013/04/23 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
两种方法解决javascript url post 特殊字符转义 + & #
2016/04/13 Javascript
Vue.js组件使用开发实例教程
2016/11/01 Javascript
JS创建对象的写法示例
2016/11/04 Javascript
jquery 通过ajax请求获取后台数据显示在表格上的方法
2018/08/08 jQuery
vue 项目地址去掉 #的方法
2018/10/20 Javascript
vue车牌号校验和银行校验实战
2019/01/23 Javascript
Vue 后台管理类项目兼容IE9+的方法示例
2019/02/20 Javascript
9个JavaScript日常开发小技巧
2020/10/06 Javascript
[44:04]OG vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
[45:59]EG vs OG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python 获取文件下所有文件或目录os.walk()的实例
2018/04/23 Python
Python基于jieba库进行简单分词及词云功能实现方法
2018/06/16 Python
使用Selenium破解新浪微博的四宫格验证码
2018/10/19 Python
Python3.6安装卸载、执行命令、执行py文件的方法详解
2020/02/20 Python
python用WxPython库实现无边框窗体和透明窗体实现方法详解
2020/02/21 Python
Keras load_model 导入错误的解决方式
2020/06/09 Python
利用Python优雅的登录校园网
2020/10/21 Python
HTML5实现移动端点击翻牌功能
2020/10/23 HTML / CSS
设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
2014/12/30 面试题
英语翻译系毕业生求职信
2013/09/29 职场文书
连锁经营管理专业大学生求职信
2013/10/30 职场文书
外语专业毕业生个人的自荐信
2013/11/19 职场文书
贷款委托书怎么写
2014/08/02 职场文书
运动会搞笑广播稿
2014/10/14 职场文书
安全生产工作汇报材料
2014/10/28 职场文书
迎新生欢迎词
2015/01/23 职场文书
redis连接被拒绝的解决方案
2021/04/12 Redis
windows下快速安装nginx并配置开机自启动的方法
2021/05/11 Servers
使用Navicat Premium工具将oracle数据库迁移到MySQL
2021/05/27 Oracle