Головоломка с блоком поиска в ширину

Я создаю программу, которой будет предоставлен текстовый файл в качестве вывода с размером платы и идентификатором части, а также шириной и длиной части. Цель состоит в том, чтобы правильно расположить все блоки на доске. В настоящее время моей программе требуется целая вечность, чтобы найти решение. Мне нужна помощь в оптимизации или в выяснении того, что мне нужно исправить. Я пытаюсь реализовать поиск в ширину, чтобы сделать это правильно. Прикреплю текстовый файл и исходный файл. Я добавил изображения внизу, чтобы показать ввод и то, каким должен быть вывод. ТЕКСТОВЫЙ ФАЙЛ — первая строка — это размеры платы, остальные — ID куска, ширина куска, длина куска.

10,10
1,10,1
2,1,10
3,1,5
4,3,5
5,20,2
6,1,5
7,1,5
8,2,5

ИСХОДНЫЙ ФАЙЛ Метод Solve выполняет всю тяжелую работу и реализует BFS.

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):
        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

        #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
        

        return True

    # Input: piece - PuzzlePiece object
    # Insert piece into the next available position on the board and update state
    def place(self, piece):
        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):
        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) :

    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, l, 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=[]):
    # 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, remaining, 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():
    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()

введите описание изображения здесь
введите описание изображения здесь

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *