问题描述
你的朋友给你买了新年礼物,这是一个谜题!谜题由许多 不同长度和宽度的木制矩形块和一块板。目标是定位 以适合所有木块的方式将木块放在板上。
我有这个程序,我需要帮助修复我的广度优先搜索算法。 现在它非常慢并且使用大量内存。我想是因为我多次深度复制。解决功能是主要功能,将完成繁重的工作。 我添加了一个文本文件,它的第一行是拼图的尺寸,其余的行分别是pieceID、pieceWidth 和pieceLength。 这是输入文件。非常感谢。
10,10
1,10,1
2,1,10
3,5
4,3,5
5,20,2
6,5
7,5
8,2,5
import argparse,copy
import queue
import copy
import numpy as np
class PuzzleBoard():
def __init__(self,board_length,board_width ):
self.l = board_length
self.w = board_width
self.state = [[0 for _ in range(board_width)] for _ in range(board_length)]
self.used_piece = []
# Input: point - tuple cotaining (row_index,col_index) of point in self.state
# Returns true if point is out of bounds; otherwise,returns false
def __out_of_bounds(self,point):
# Todo: Implement this function
if(point < 0 or point > (len(self.state)) or (point > (self.state[0]))):
return True
return False
# Finds the next available open space in the PuzzleBoard (looking from the top-left in row-major order)
def __next(self):
for i in range(len(self.state)) :
for j in range(len(self.state[0])):
if (self.state[i][j] == 0):
return (i,j)
return False
# Input: piece - PuzzlePiece object
# Check if piece fits in the next available space (determined by __next method above)
def fits(self,piece):
position = self.__next()
if not position:
return False
#Todo: Check if any part of the piece is out of bounds
#if piece will be out bounds when place rotate to see if that helps
if((( piece.w + position[0] ) > len( self.state )) or (( piece.l + position[1] )> len( self.state[0] ))):
piece.rotate()
if((( piece.w + position[0] ) > len( self.state )) or (( piece.l + position[1] )> len( self.state[0] ))):
return False
#Todo: Check if piece can be placed without intersecting another placed piece
return True
# Input: piece - PuzzlePiece object
# Insert piece into the next available position on the board and update state
def place(self,piece):
# Todo: Bug in this function. Pieces not being placed correctly.
position = self.__next()
if self.fits(piece):
for i in range(position[0],position[0] + piece.w ):
for j in range(position[1],position[1] + piece.l):
if((( piece.w + position[0] ) > len( self.state )) or (( piece.l + position[1] )> len( self.state[0] ))):
return
if(self.state[i][j]== 0):
#self.used_piece.append(piece)
self.state[i][j] = piece.id
else:
continue
return position
def check(self,piece):
position = self.__next()
if(position[0] + piece.w > self.w or position[1] + piece.l > self.l):
return False
return True
# Returns whether the board has been filledwith pieces
def completed(self):
return True if not self.__next() else False
def copy(self):
copied = PuzzleBoard(self.l,self.w)
copied.state = copy.deepcopy(self.state)
return copied
class PuzzlePiece():
def __init__(self,pid,length,width):
self.id = pid
self.l = length
self.w = width
itfits = False
def rotate(self):
#Todo: Bug in this function. Pieces are not rotating correctly
temp = self.l
self.l = self.w
self.w = temp
def orientation(self):
return "H" if self.w >= self.l else "V"
def __str__(self):
return f"ID: {self.id},LENGTH: {self.l},WIDTH: {self.w},ROTATED: {self.rotated}"
def parse_input(filepath) :
#Todo: Bug in this function. Error raised when called
parsed = {'board' : {},'pieces' : {}}
with open(filepath,'r') as f:
file_contents = f.read().strip().split("\n")
board_length,board_width = file_contents[0].strip().split(",")
parsed['board']['length'] = int(board_length)
parsed['board']['width'] = int(board_width)
for i in range(1,len(file_contents)):
#FIX: the issue was fix
pid,l,w = file_contents[i].strip().split(",")
pid,w = int(pid),int(l),int(w)
parsed['pieces'][pid] = {}
parsed['pieces'][pid]['length'] = l
parsed['pieces'][pid]['width'] = w
return parsed
def helper(board,piece):
unused = []
#for piece in pieces:
if board.fits(piece):
position = board.place(piece)
board.used_piece.append((piece,position))
return board
def solve(board,remaining,used_pieces=[]):
# Todo: Implement a solution for a variable amount of pieces and puzzle board size.
# HINT: Recursion might help.7
poss = queue.Queue()
poss.put(board)
currboard = PuzzleBoard(len(board.state),len(board.state[0]))
while not currboard.completed():
currboard = poss.get()
#print(currboard.state)
for piece in remaining:
fakeboard = copy.deepcopy(currboard)
if(not (piece.id in np.array(fakeboard.state))):
#if( fakeboard.check(piece)):
poss.put(helper(fakeboard,piece))
print("Suff done")
return currboard
'''if(len(remaining) != 0):
board,used_pieces,unused_pieces = helper(board,used_pieces)
if board.completed():
return board,used_pieces
for i in board.state:
print(i)
print("\n \n")
return solve(board,unused_pieces,used_pieces)
return board'''
def main():
#Todo: Bug in this function. Positions are not correct after solution is found.
parser = argparse.ArgumentParser()
parser.add_argument('input')
args = parser.parse_args()
parsed = parse_input(args.input)
board = PuzzleBoard(parsed['board']['length'],parsed['board']['width'])
pieces = []
for k,v in parsed['pieces'].items():
pieces.append(PuzzlePiece(k,v['length'],v['width']))
solved = solve(board,pieces)
if not solved:
print("No solution found for given input.")
else:
print("Solution found.")
board = solved
for u,position in solved.used_piece:
print(f"Piece ID: {u.id},Position:{position},Orientation: {u.orientation()}")
if __name__ == "__main__":
main()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)