实现广度优先搜索

问题描述

你的朋友给你买了新年礼物,这是一个谜题!谜题由许多 不同长度和宽度的木制矩形块和一块板。目标是定位 以适合所有木块的方式将木块放在板上。

我有这个程序,我需要帮助修复我的广度优先搜索算法。 现在它非常慢并且使用大量内存。我想是因为我多次深度复制。解决功能是主要功能,将完成繁重的工作。 我添加一个文本文件,它的第一行是拼图的尺寸,其余的行分别是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

enter image description here

enter image description here

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 (将#修改为@)