普林斯顿算法课作业的python实现(四)8 Puzzle
8 Puzzle
- 问题
- 思路
- 代码
- 结果
问题
这一次的编程作业是完成一个类似于“华容道”的游戏——8 puzzle:
给定一个 N×NN\times NN×N 的网格图,其中有一个网格被挖空,其余网格标记为 1,2,3,⋯,N×N−11,2,3,\cdots, N\times N-11,2,3,⋯,N×N−1。每次可以将被挖空的网格与相邻被标记数字的网格交换,目标是移至成 1,2,3,4⋯,N×N−11,2,3,4\cdots, N\times N-11,2,3,4⋯,N×N−1 依次排列,最后一个网格被挖空的情况。
原题链接
思路
首先定义一个数据类型 Board,储存 N×NN\times NN×N 的二维数组,用 0 表示被挖空的网格,找出其相邻的 Board。定义每一个 Board 与目标 Board 之间的 Hamming 距离和 Manhattan 距离。定义一个新的数据类型 State,用来储存 Board、移动步数、前一个State。
接下来可以利用 A* search algorithm 来解决这个问题:先把初始 State 加入优先队列,然后每次删去 Manhattan 最小的 State,加入其相邻的 State(如果该 State 不曾在优先队列中出现过),直至删去的 State 的 Manhattan 距离为 0。
注意到,任意给定一个初始状态,未必能达到目标状态。可以利用逆序数来判断:当且仅当原初始状态在一维数组下是偶排列时,该问题是可行的。
代码
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 10 16:34:21 2020@author: zxw
"""
import numpy as np
import timeN = 3
goal = [i+1 for i in range(N*N)]
goal[N*N-1] = 0class Board:
#construct a board from an N-by-N array of tilesdef __init__(self, tiles):self.Array = np.array(tiles).reshape(N,N)
# return number of blocks out of placedef hamming(self):temp = N*N-1-sum(sum(self.Array == Board(goal).Array))if sum(sum(np.argwhere(self.Array == 0))) == 2*(N-1): return temp+1else:return temp# return sum of Manhattan distances between blocks and goaldef manhattan(self):manhattan_i = []for i in range(N*N-1):manhattan_i.append(sum(sum(abs(np.argwhere(self.Array == i+1)-np.argwhere(Board(goal).Array == i+1)))))return sum(manhattan_i) # does this board equal ydef equals(self,y):return sum(sum(self.Array == y.Array)) == N*N# return an Iterable of all neighboring board positionsdef neighbours(self):location = np.argwhere(self.Array==0)[0]x = location[0]y = location[1]neighbors = []copies= [self.Array.copy() for i in range(4)]if x != 0:copies[0][x][y] = self.Array[x-1][y]copies[0][x-1][y] = 0neighbors.append(Board(copies[0]))if x != N-1:copies[1][x][y] = self.Array[x+1][y]copies[1][x+1][y] = 0neighbors.append(Board(copies[1]))if y != 0:copies[2][x][y] = self.Array[x][y-1]copies[2][x][y-1] = 0neighbors.append(Board(copies[2]))if y != N-1:copies[3][x][y] = self.Array[x][y+1]copies[3][x][y+1] = 0 neighbors.append(Board(copies[3]))return neighbors
# return a string representation of the boarddef toString(self):for i in range(N):for j in range(N):if self.Array[i][j] != 0:print(str(self.Array[i][j])+' ',end="")else:print(' ',end="")print('\n')class State:def __init__(self,board,move,pre):self.Board = boardself.Move = moveself.Pre = pre class MinPQ:def __init__(self):self.states = []self.states.append(0)self.n = 0def insert(self, newstate):self.n = self.n+1self.states.append(newstate)self.swim(self.n)def delMin(self):Min = self.states[1]self.exch(1, self.n)self.n = self.n-1del self.states[self.n + 1]self.sink(1)return Mindef swim(self,k):if k <= 1:returnwhile (k > 1) & (self.states[int(k/2)].Board.manhattan() > self.states[k].Board.manhattan()):self.exch(int(k/2) , k)k = int(k/2)if k <= 1:returndef sink(self,k):while (2*k <= self.n):j = 2*kif (j < self.n):if (self.states[j].Board.manhattan() > self.states[j+1].Board.manhattan()):j = j+1if not self.states[k].Board.manhattan() > self.states[j].Board.manhattan():breakself.exch(k, j)k = jdef exch(self,i,j):t = self.states[i]self.states[i] = self.states[j]self.states[j] = tclass Solver:def __init__(self, board):self.initial_state = State(board,0,None)self.pq = MinPQ()self.pq.insert(self.initial_state)if self.isSolvable(): while self.pq.states[1].Board.manhattan() != 0:dequeue = self.pq.delMin()for neighbor in dequeue.Board.neighbours():if dequeue.Pre is None:self.pq.insert(State(neighbor,dequeue.Move+1,dequeue))elif not neighbor.equals(dequeue.Pre.Board):Flag = 1for state in self.pq.states:if state == 0:passelif state.Board.equals(neighbor):Flag = 0if Flag == 1: self.pq.insert(State(neighbor,dequeue.Move+1,dequeue))else:print("It is not solvable!")def isSolvable(self):List = list(self.initial_state.Board.Array.reshape(1,N*N)[0])k = 0for i in range(1,N*N-1):for j in range(0,i):if List[j] > List[i]:k = k+1return k%2 == 0def moves(self):return self.pq.states[1].Movedef toString(self):Move_list = []Move_list.append(self.pq.states[1])while Move_list[-1].Pre != None:Move_list.append(Move_list[-1].Pre)Move_list.reverse()for each in Move_list:each.Board.toString()print('\n')if __name__ == '__main__':a = [0,1,3,4,2,5,7,8,6]test = Board(a)solve = Solver(test)solve.toString()b = [1,2,3,4,5,6,8,7,0]test = Board(b)solve = Solver(test)
结果
注:该算法仍有一个小问题:对于某些较复杂的初识状态(比如[2,1,3,4,5,6,8,7,0]),运行时间过久。不知可否能进一步改进?
普林斯顿算法课作业的python实现(四)8 Puzzle相关推荐
- 普林斯顿算法课作业的python实现(三)Collinear Points
Collinear Points 问题 思路 代码 结果 问题 这一次的编程作业是判断共线点. 问题大致描述如下: 给定平面上一些点,判断其中是否有四个及以上的点共线,把所有这些点找出来并连线.原题链 ...
- 普林斯顿算法课作业 part II 的python实现(四)Boggle
Boggle 问题 思路 代码 结果 总结 问题 原问题网页:Boggle 问题大致描述如下: 有一个 4×44\times44×4 的方格图,每一个格子上标有一个英文字母,现要从中寻找出英文单词. ...
- 「数据结构」普林斯顿算法课第二周作业
「数据结构」普林斯顿算法课第二周作业 Algorithm I, Princeton 编程作业: Deques and Randomized Queues 思路 Deque.java Randomize ...
- 「数据结构」普林斯顿算法课第一周作业
「数据结构」普林斯顿算法课第一周作业 Algorithm I, Princeton 编程作业: Percolation 思路 第一部分代码展示 第二部分代码展示 编程作业: Percolation P ...
- 普林斯顿算法课Part2第四周作业_Boggle
作业地址:http://coursera.cs.princeton.edu/algs4/assignments/boggle.html 作业难点: 1.如何保证求解速度,满分要求是求解速度 >= ...
- 算法第四版课后习题答案 西安电子科技大学 计算机学院 算法课
来源于西电计算机15级学长学姐,算法第四版课后习题答案 西安电子科技大学 计算机学院 算法课. 再推荐一个好的看答案的地方,每一题都有,只是还没有更新完成. 地址:https://alg4.ike ...
- WordNet 普林斯顿 算法第四版
普林斯顿 算法第四版 本文的代码以及之前的作业代码可通过一下github链接获得 https://github.com/Changjing-Liu/algorithm_lab 文章目录 普林斯顿 算法 ...
- BoggleSolver 普林斯顿 算法第四版
BoggleSolver 普林斯顿 算法第四版 文章目录 BoggleSolver 普林斯顿 算法第四版 一. 引言 1. Boggle 2. 计分 3. Qu特殊情况 4. 任务要求 二.分析 1. ...
- AcWing提高算法课Level-3 第四章 高级数据结构
AcWing提高算法课Level-3 第四章 高级数据结构 并查集 AcWing 1250. 格子游戏1167人打卡 AcWing 1252. 搭配购买1064人打卡 AcWing 237. 程序自动 ...
最新文章
- html,css,js,反弹的js效果
- TP自动生成模块目录
- 史上最全的Chrome使用技巧集锦
- SAP Spartacus org unit table不同区域focus然后回车的行为差异
- mysql 字符转换函数是_MySQL日期和字符串转换函数
- 修改php上传限制 (phpmyadmin 限制)
- 深入解析MVVM架构
- IE7下JSON不能有多余的逗号,IE8下创建IMG节点的BUG
- java for mat,在Java绑定中通过OpenCV Mat进行循环
- Mysql中的日期及时间相关函数
- 山东理工计算机组成原理试题,山东理工计算机组成原理试题
- 废旧笔记本打造黑群晖NAS,docker,软路由,实现我心目中的all in one,包含fx n1,玩客云老母鸡玩法
- Launcher3 翻页动画详解与修改
- 什么是时间复杂度和空间复杂度
- 不懂英语怎么做亚马逊_亚马逊的回声秀可以做的一切其他回声都做不到
- 瀚高数据库故障诊断指导方案
- 计算机操作系统 - 目录1
- 三个变量存在一个协整方程_计量经济学最基本的31个问题
- 阿里巴巴数学竞赛详细解答(据说晋级的直接P8岗)
- 蚂蚁金服 Service Mesh 实践探索 | Qcon 实录
热门文章
- deepin深度系统安装方法
- 基于php+mysql购物商城 校园二手商品 图书鲜花商城 毕业设计(9)商品评论
- 北大软微和北邮计算机,各校MBA录取成绩分析,你的竞争者考得都挺高!
- 2023考研|上海财经大学MBA/EMBA招生录取流程正式发布-文都管联院
- 基础算法题——城市间最短路程(Floyd算法)
- 网站推广之搜索引擎篇(转)
- php 图片 字母识别,php实现ocr文字识别
- Ubuntu下安装Microsoft Teams
- 2022阿里云码上公益“第益课”大学生技术公益实践计划活动说明
- python爬虫入门(一)爬取钓鱼吧