系列文章
补充发两篇文章记录一下之前用到的宽度优先算法
给定两个水壶,一个可以装4升水,一个能装3升水,水壶上没有任何度量标记。有一水龙头可以用来往壶中灌水。问题是怎样在能装4升的水壶里面恰好只装2升水。
(x,y)
本道题的操作也不难,倒来倒去也就这么几种
# -*- coding: utf-8 -*-
# @Time : 2020/10/15 19:12
# @Author : Tong Tianyu
# @File : chapter1_1.py
import queue
import numpy as np
# 定义水壶类对象
class Kettle:
def __init__(self):
self.x = 0 # 三升的水壶
self.y = 0 # 四升的水壶
self.state_space = np.zeros((4, 5)) # 定义状态空间
self.q_tmp = queue.Queue() # 定义队列
self.final = [] # 定义结果
self.final_only_data = [[0, 0]] # 便于操作的结果
def BFS(self):
# con = 1
self.q_tmp.put([0, 0])
self.final.append([[0, 0], 'none', [0]])
self.state_space[0][0] = 1
while len(self.q_tmp.queue) != 0:
a, b = self.q_tmp.get()
if a == 2 or b == 2:
continue
pre = [a, b]
# print('----------------', con, '------------------')
self.x, self.y = a, b
self.Pour_X()
self.update(pre, a, b, 'Pour_X')
self.Pour_Y()
self.update(pre, a, b, 'Pour_Y')
self.Empty_X()
self.update(pre, a, b, 'Empty_X')
self.Empty_Y()
self.update(pre, a, b, 'Empty_Y')
self.Pour_X_To_Y()
self.update(pre, a, b, 'Pour_X_To_Y')
self.Pour_Y_To_X()
self.update(pre, a, b, 'Pour_Y_To_X')
# con += 1
return self.final, self.final_only_data
def update(self, pre, a, b, name):
if self.state_space[self.x][self.y] == 0:
self.state_space[self.x][self.y] = 1
self.q_tmp.put([self.x, self.y])
self.final_only_data.append([self.x, self.y])
self.final.append([[self.x, self.y], name, pre])
self.x, self.y = a, b
def Pour_X(self):
'''倒满三升的水壶X'''
self.x = 3
return True
def Pour_Y(self):
'''倒满四升的水壶Y'''
self.y = 4
return True
def Empty_X(self):
'''清空三升的水壶X'''
self.x = 0
return True
def Empty_Y(self):
'''清空四升的水壶Y'''
self.y = 0
return True
def Pour_X_To_Y(self):
'''三升的水壶x倒入四升y中'''
if (self.x + self.y) <= 4: # 可以完全倒入四升水壶Y中
self.y = self.x + self.y
self.x = 0
else: # 倒满四升壶y之后还有余量
self.x = self.x - (4 - self.y)
self.y = 4
return True
def Pour_Y_To_X(self):
'''四升水壶y倒入三升水壶x中'''
if (self.x + self.y) <= 3: # 可以完全倒入三升水壶x中
self.x = self.x + self.y
self.y = 0
else: # 倒满四升壶y之后还有余量
self.y = self.y - (3 - self.x)
self.x = 3
return True
if __name__ == '__main__':
kettle = Kettle()
final_list, tmp_list = kettle.BFS()
result = []
for i in range(len(final_list)):
if i == 0:
continue
data = final_list[i]
print('每行的数据为:', data)
pre = data[2]
print('当前的父节点为:', pre)
pre_index = tmp_list.index(pre)
print('当前父节点在列表中的位置为:', pre_index)
result = final_list[pre_index][-1]
print('当前父节点的路径为:', result)
# md这里被深浅复制搞死了
a = result.copy()
a.append(i)
final_list[i][-1] = a
print('*********************************************')
def output(order):
print('x' + '\t' + 'y' + '\t' + 'method')
for i in order:
print(*final_list[i][0], sep='\t', end='\t')
print(final_list[i][1])
con = 0
for i in range(len(tmp_list)):
if 2 in tmp_list[i]:
print(f'-------------方法{con}--------------')
order = final_list[i][-1]
output(order)
con += 1