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中使用smtplib和email模块发送邮件实例
Apr 22 Python
python打开url并按指定块读取网页内容的方法
Apr 29 Python
python获取指定路径下所有指定后缀文件的方法
May 26 Python
详解在Python程序中解析并修改XML内容的方法
Nov 16 Python
python3操作mysql数据库的方法
Jun 23 Python
深入理解Django中内置的用户认证
Oct 06 Python
Python线性方程组求解运算示例
Jan 17 Python
python的Crypto模块实现AES加密实例代码
Jan 22 Python
python+opencv实现高斯平滑滤波
Jul 21 Python
python 获取图片分辨率的方法
Jan 08 Python
python多进程(加入进程池)操作常见案例
Oct 21 Python
python 网络编程要点总结
Jun 18 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
人工智能开始玩《星际争霸2》 你的操作跟得上吗?
2017/08/11 星际争霸
轻松入门: 煮好咖啡的七个诀窍
2021/03/03 冲泡冲煮
提升PHP执行速度全攻略(下)
2006/10/09 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
PHP 利用Mail_MimeDecode类提取邮件信息示例
2014/01/26 PHP
php中限制ip段访问、禁止ip提交表单的代码分享
2014/08/22 PHP
php+mysql查询实现无限下级分类树输出示例
2016/10/03 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
PHP设计模式之适配器模式(Adapter)原理与用法详解
2019/12/12 PHP
firefox中JS读取XML文件
2006/12/21 Javascript
javascript动画效果类封装代码
2007/08/28 Javascript
加载jQuery后$冲突的解决办法
2010/07/09 Javascript
分享14个很酷的jQuery导航菜单插件
2011/04/25 Javascript
jQuery Tools tab使用介绍
2012/07/14 Javascript
js实现div拖动动画运行轨迹效果代码分享
2015/08/27 Javascript
JavaScript操作URL的相关内容集锦
2015/10/29 Javascript
基于jQuery的checkbox全选问题分析
2016/11/18 Javascript
vue实现单选和多选功能
2017/08/11 Javascript
jquery之基本选择器practice(实例讲解)
2017/09/30 jQuery
JS+Canvas绘制动态时钟效果
2017/11/10 Javascript
基于Vue2x实现响应式自适应轮播组件插件VueSliderShow功能
2018/05/16 Javascript
layui 图片上传+表单提交+ Spring MVC的实例
2019/09/21 Javascript
vue 关闭浏览器窗口的时候,清空localStorage的数据示例
2019/11/06 Javascript
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
Python Queue模块详解
2014/11/30 Python
Using Django with GAE Python 后台抓取多个网站的页面全文
2016/02/17 Python
django2用iframe标签完成网页内嵌播放b站视频功能
2018/06/20 Python
Python3 批量扫描端口的例子
2019/07/25 Python
Python时间序列缺失值的处理方法(日期缺失填充)
2019/08/11 Python
简单了解django文件下载方式
2020/02/10 Python
Windows 下更改 jupyterlab 默认启动位置的教程详解
2020/05/18 Python
HTML5中的Web Notification桌面右下角通知功能的实现
2018/04/19 HTML / CSS
网络程序员自荐信
2014/01/25 职场文书
班主任寄语大全
2014/04/04 职场文书
国贸专业毕业求职信
2014/06/11 职场文书
springboot项目以jar包运行的操作方法
2021/06/30 Java/Android