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的Zato发送AMQP消息的教程
Apr 16 Python
Python3.2中Print函数用法实例详解
May 19 Python
python字符串,数值计算
Oct 05 Python
Python元组操作实例分析【创建、赋值、更新、删除等】
Jul 24 Python
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
Jul 07 Python
Django Admin后台添加数据库视图过程解析
Apr 01 Python
解决TensorFlow程序无限制占用GPU的方法
Jun 30 Python
基于python实现判断字符串是否数字算法
Jul 10 Python
详解Python 函数参数的拆解
Sep 02 Python
Python基于Webhook实现github自动化部署
Nov 28 Python
Elasticsearch 索引操作和增删改查
Apr 19 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 危险函数全解析
2009/09/09 PHP
php下保存远程图片到本地的办法
2010/08/08 PHP
php递归获取目录内文件(包含子目录)封装类分享
2013/12/25 PHP
php设计模式之命令模式使用示例
2014/03/02 PHP
php简单创建zip压缩文件的方法
2016/04/30 PHP
PHP编写文件多服务器同步程序
2016/07/02 PHP
Laravel框架中Blade模板的用法示例
2017/08/30 PHP
基于jquery的动态创建表格的插件
2011/04/05 Javascript
JS、CSS以及img对DOMContentLoaded事件的影响
2014/08/12 Javascript
Jquery动态替换div内容及动态展示的方法
2015/01/23 Javascript
整理Javascript事件响应学习笔记
2015/12/02 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
JavaScript中数组slice和splice的对比小结
2016/09/22 Javascript
javascript的函数劫持浅析
2016/09/26 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
2016/10/28 Javascript
jQuery得到多个值只能用取Class ,不能用取ID的方法
2016/12/04 Javascript
详解VUE 对element-ui中的ElTableColumn扩展
2018/03/28 Javascript
vue和webpack打包项目相对路径修改的方法
2018/06/15 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
layui use 定义js外部引用函数的方法
2019/09/26 Javascript
uniapp微信小程序:key失效的解决方法
2021/01/20 Javascript
Python标准库之循环器(itertools)介绍
2014/11/25 Python
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
Python3中bytes类型转换为str类型
2018/09/27 Python
python 使用re.search()筛选后 选取部分结果的方法
2018/11/28 Python
Python3并发写文件与Python对比
2019/11/20 Python
django有外键关系的两张表如何相互查找
2020/02/10 Python
Django --Xadmin 判断登录者身份实例
2020/07/03 Python
Python如何读写CSV文件
2020/08/13 Python
python 对一幅灰度图像进行直方图均衡化
2020/10/27 Python
Python运算符+与+=的方法实例
2021/02/18 Python
python解决OpenCV在读取显示图片的时候闪退的问题
2021/02/23 Python
戴森香港官方网站:Dyson香港
2021/02/11 全球购物
城管执法人员纪律作风整顿思想汇报
2014/09/13 职场文书
外贸采购员岗位职责
2015/04/03 职场文书
爱国主义教育基地观后感
2015/06/18 职场文书