python实现汉诺塔算法


Posted in Python onMarch 01, 2021

题目:

汉诺塔给出最优解,如果对汉诺塔的定义有不了解,请翻看数据结构教材。

除了最基本的之外,还有一题,给定一个数组,arr=[2,3,1,2,3],其含义是这是一个有5个圆盘的汉诺塔,每一个数字代表这个圆盘所在的位置,1代表左边的柱子,2代表中间,3代表右边。给出这个序列代表了汉诺塔移动的第几步,如果该步骤是错误的,则返回-1,所谓错误,是指该步骤不是最简便的得到汉诺塔序列的操作步骤。

分析:

1、 算法当然还是递归解了,即把n个汉诺塔盘子分解成 n - 1 个盘子的移动和一个底层盘子的移动,这样一来,问题就成了一连串的递归,然后就可以逐步求解了。
当然了,汉诺塔还有进阶问题,此处先不讨论,随后补上吧。

2、 这个步骤的循环是从最右边开始的,考察最大的圆盘,因为数组的索引值越大,其圆盘的半径越大。
这样一来,如果最大的圆盘的值为3,说明已经移动到位了,如果为1,说明还没有开始移动底层圆盘,如果为2,说明圆盘移动到了中间,表示移动错误,因为根本不需要移动到中间,这个步骤是多余的。

代码:

#!usr/bin/python2.7
# -*- coding=utf8 -*-
# @Time : 18-1-3 下午9:52
# @Author : Cecil Charlie


class Hanoi(object):
 """
 汉诺塔问题,给定三个盘子,用计算机计算出来将所有的盘子从左移动到右的所有的操作。
 """
 def __init__(self):
 self.place = ["left", "middle", "right"]
 self.num = 0 # 表示所有操作的总次数

 def hanoi(self, n):
 """
  给定一个n,即汉诺塔的盘子数量,返回所有的从左移动到右侧的具体操作步数
 :param n: 盘子数
 :return: 具体操作
 """
 self.num = 0
 if n > 0:
  self.__move(n, "left", "middle", "right")

 def __move(self, n, start, mid, end):
 if n == 1:
  print "move from " + start + " to " + end
  self.num += 1
 else:
  self.__move(n-1, start, end, mid)
  self.__move(1, start, mid, end)
  self.__move(n-1, mid, start, end)

 def step(self, arr):
 """
  求解针对arr的圆盘,所对应的最优解到底是第几步。解题的核心在于从右向左考察圆盘到底在不在3位置,如果在,则说明已经移动成功了;
  如果在中间,说明移动出现了错误,因为不需要移动到中间,如果还在左边,则仍需要考虑。
 :param arr: 列表中每一项表示该项的圆盘在哪个柱子上,取值包括1,2,3。1表示左,2表示中,3表示右,索引值越大,表示的圆盘的半径越大。
 :return: 属于最优解的第几步
 """
 if arr is None:
  return -1
 for i in xrange(len(arr) - 1):
  if arr[i] != 1 and arr[i] != 2 and arr[i] != 3:
  return -1
 return self.__process(arr, len(arr)-1, 1, 2, 3)

 def __process(self, arr, i, start, mid, end):
 """
  具体操作得到arr属于第几步
 :param arr: 圆盘对应的位置数组列表
 :param i: 考察arr圆盘的第几个,最大值是 len(arr)-1
 :return: 返回步数,如果给出的arr的位置不是移动的最优解,则返回 -1。
 """
 if i == -1:
  return 0
 if arr[i] != start and arr[i] != end:
  return -1
 if arr[i] == start:
  return self.__process(arr, i-1, start, end, mid) # 说明其值还未过半,直接找之前的就好
 else: # 说明步数已经过半了。
  count = self.__process(arr, i-1, mid, start, end)
  if count == -1:
  return -1
  return (i * 2) + count

h = Hanoi()
h.hanoi(4)
print h.num
print h.step([3,3,2,1])

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python常用的日期时间处理方法示例
Feb 08 Python
Python实现自动添加脚本头信息的示例代码
Sep 02 Python
Python简单实现网页内容抓取功能示例
Jun 07 Python
python中使用 xlwt 操作excel的常见方法与问题
Jan 13 Python
Python基于机器学习方法实现的电影推荐系统实例详解
Jun 25 Python
使用pyqt 实现重复打开多个相同界面
Dec 13 Python
python文件读取失败怎么处理
Jun 23 Python
tensorflow 2.1.0 安装与实战教程(CASIA FACE v5)
Jun 30 Python
python实现数字炸弹游戏程序
Jul 17 Python
python zip()函数的使用示例
Sep 23 Python
Pycharm github配置实现过程图解
Oct 13 Python
Python游戏开发实例之graphics实现AI五子棋
Nov 01 Python
Python3中bytes类型转换为str类型
Sep 27 #Python
python求解数组中两个字符串的最小距离
Sep 27 #Python
Python开发的十个小贴士和技巧及长常犯错误
Sep 27 #Python
详解django中使用定时任务的方法
Sep 27 #Python
Python高级特性切片(Slice)操作详解
Sep 27 #Python
Python初学者需要注意的事项小结(python2与python3)
Sep 26 #Python
使用 Python 实现微信群友统计器的思路详解
Sep 26 #Python
You might like
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
2017/11/13 PHP
PHP实现用session来实现记录用户登陆信息
2018/10/15 PHP
thinkphp5 模型实例化获得数据对象的教程
2019/10/18 PHP
prototype.js的Ajax对象
2006/09/23 Javascript
JavaScript效率调优经验
2009/06/04 Javascript
JQuery autocomplete 使用手册
2010/04/01 Javascript
基于jquery的给文章加入关键字链接
2010/10/26 Javascript
JQuery+CSS提示框实现思路及代码(纯手工打造)
2013/05/07 Javascript
js 遍历json返回的map内容示例代码
2013/10/29 Javascript
Js获取数组最大和最小值示例代码
2013/10/29 Javascript
zeroclipboard 单个复制按钮和多个复制按钮的实现方法
2014/06/14 Javascript
input:checkbox多选框实现单选效果跟radio一样
2014/06/16 Javascript
jQuery添加options点击事件并传值实例代码
2016/05/18 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
浅谈struts1 & jquery form 文件异步上传
2017/05/25 jQuery
JS实现留言板功能[楼层效果展示]
2017/12/27 Javascript
webpack实现一个行内样式px转vw的loader示例
2018/09/13 Javascript
[00:32]2018DOTA2亚洲邀请赛Newbee出场
2018/04/03 DOTA
[46:44]VG vs TNC Supermajor小组赛B组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
10款最好的Web开发的 Python 框架
2015/03/18 Python
python使用Tkinter显示网络图片的方法
2015/04/24 Python
在Python的Django框架中创建语言文件
2015/07/27 Python
Python切换pip安装源的方法详解
2016/11/18 Python
Python基于回溯法子集树模板解决数字组合问题实例
2017/09/02 Python
更换Django默认的模板引擎为jinja2的实现方法
2018/05/28 Python
python爬虫正则表达式之处理换行符
2018/06/08 Python
Python装饰器简单用法实例小结
2018/12/03 Python
Django框架教程之中间件MiddleWare浅析
2019/12/29 Python
《王二小》教学反思
2014/02/27 职场文书
小班上学期评语
2014/05/05 职场文书
个人求职信范文
2014/05/24 职场文书
物流管理专业推荐信
2014/09/06 职场文书
网络工程专业大学生求职信
2014/10/01 职场文书
合伙开公司协议书范本
2014/10/28 职场文书
2015大学生党员自我评价范文
2015/03/03 职场文书
MySQL磁盘碎片整理实例演示
2022/04/03 MySQL