Compare commits
1 Commits
Knapsack-b
...
A-gwiazdka
Author | SHA1 | Date | |
---|---|---|---|
|
2e383d95f1 |
103
main.py
103
main.py
@ -0,0 +1,103 @@
|
||||
import heapq
|
||||
from itertools import chain
|
||||
|
||||
|
||||
class Puzzle:
|
||||
def __init__(self, board, moves=0):
|
||||
self.board = board
|
||||
self.moves = moves
|
||||
self.sequence = []
|
||||
self.parent = None
|
||||
self.cost = 0
|
||||
self.mode = 0 # 0 - Manhattan, 1 - Na dobrych miejscach
|
||||
|
||||
def ustal_koszt(self):
|
||||
if self.mode == 0:
|
||||
self.cost = self.moves + self.manhattan_distance()
|
||||
elif self.mode == 1:
|
||||
self.cost = self.moves + self.na_dobrych_miejscach()
|
||||
return self.cost
|
||||
|
||||
def dodaj_ruch(self, ruch):
|
||||
if self.parent is not None:
|
||||
for move in self.parent.sequence:
|
||||
self.sequence.append(move)
|
||||
if ruch == (1, 0):
|
||||
self.sequence.append("D")
|
||||
elif ruch == (-1, 0):
|
||||
self.sequence.append("U")
|
||||
elif ruch == (0, 1):
|
||||
self.sequence.append("R")
|
||||
elif ruch == (0, -1):
|
||||
self.sequence.append("L")
|
||||
|
||||
def znajdz_puste(self):
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
if self.board[i][j] == 0:
|
||||
return i, j
|
||||
|
||||
def manhattan_distance(self):
|
||||
distance = 0
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
if self.board[i][j] != 0:
|
||||
x, y = divmod(self.board[i][j]-1, 4)
|
||||
distance += abs(x - i) + abs(y - j)
|
||||
return distance
|
||||
|
||||
def na_dobrych_miejscach(self):
|
||||
heurystyka = 16
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
if self.board[i][j] != 0:
|
||||
x, y = divmod(self.board[i][j]-1, 4)
|
||||
if x == i and y == j:
|
||||
heurystyka -= 1
|
||||
return heurystyka
|
||||
|
||||
def sasiedzi(self):
|
||||
i, j = self.znajdz_puste()
|
||||
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
|
||||
x, y = i + dx, j + dy
|
||||
if 0 <= x < 4 and 0 <= y < 4:
|
||||
board_copy = [row.copy() for row in self.board]
|
||||
board_copy[i][j], board_copy[x][y] = board_copy[x][y], board_copy[i][j]
|
||||
sasiad = Puzzle(board_copy, self.moves + 1)
|
||||
sasiad.parent = self
|
||||
sasiad.dodaj_ruch((dx, dy))
|
||||
yield sasiad
|
||||
|
||||
def cel(self):
|
||||
return self.board == [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]]
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.ustal_koszt() < other.ustal_koszt()
|
||||
|
||||
|
||||
def solve(puzzle):
|
||||
heap = [puzzle]
|
||||
visited = {tuple(chain(*puzzle.board))}
|
||||
while heap:
|
||||
node = heapq.heappop(heap)
|
||||
if node.cel():
|
||||
return node.moves, node.sequence
|
||||
for sasiad in node.sasiedzi():
|
||||
flat_board = tuple(chain(*sasiad.board))
|
||||
# print(flat_board not in visited)
|
||||
if flat_board not in visited:
|
||||
visited.add(flat_board)
|
||||
# print("pushuje sąsiada")
|
||||
heapq.heappush(heap, sasiad)
|
||||
return -1
|
||||
|
||||
|
||||
tablica = [
|
||||
[2, 11, 8, 3],
|
||||
[1, 6, 4, 12],
|
||||
[5, 0, 14, 7],
|
||||
[9, 10, 13, 15]
|
||||
]
|
||||
|
||||
puzzle = Puzzle(tablica)
|
||||
print(solve(puzzle))
|
Loading…
Reference in New Issue
Block a user