Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions Backend/Classes/Grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ def move_container(self, pos1, pos2):
from_slot = self.get_slot(pos1[0], pos1[1])
to_slot = self.get_slot(pos2[0], pos2[1])
container = from_slot.get_container()
if from_slot.get_position() == (7,11): # without this line the reconstruct_grids function will crash whenever there's a move from truck
self.load_container(pos2)
return
#if from_slot.get_position() == (7,11): # without this line the reconstruct_grids function will crash whenever there's a move from truck
# self.load_container(pos2)
# return

name = container.get_name()
weight = container.get_weight()
Expand Down Expand Up @@ -207,6 +207,25 @@ def get_nearest_slot_on_other_side(self, row, col, target_side):
break

return nearest_slot, min_distance

def get_distance_to_nearest_available_slot(self, pos1):
"""
Finds the Manhattan distance to the nearest available slot from a given position (pos1).
"""
min_distance = float('inf')
pos = (8,0)

for j in range(self.columns):
for i in range(self.rows):
slot = self.slot[i][j]
if slot.state == 1:
distance = abs(pos1[0] - i) + abs(pos1[1] - j)
if distance < min_distance:
min_distance = distance
pos = (i,j)

break
return min_distance, pos

def getPossibleMoves(self, buffer= None):
"""
Expand Down Expand Up @@ -382,7 +401,7 @@ def setup_transferlist(self, transfer_list):
print(command)
parts = command.strip().split(',')
operation = parts[0]
print(operation)
#print(operation)
if operation == 'load':
name = parts[1]
weight = int(parts[2])
Expand Down Expand Up @@ -421,7 +440,6 @@ def get_possible_transfer_moves(self):
possible_moves = []
# Handle load
if self.load_list: # Check if there are items to load
#name, weight = self.load_list[0] # Pick the first item to load
valid_slots = self.get_valid_slots_position_for_loading() # Find all valid slots
for target_position in valid_slots:
move = Movement(from_slot=(-1,-1), to_slot=target_position)
Expand Down
72 changes: 42 additions & 30 deletions Backend/Classes/Pathfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def balanceHelper(self):
crane_to_start_cost = state.calculate_path_cost(state.crane_position, move.from_slot)
move_cost = state.calculate_path_cost(move.from_slot, move.to_slot)
new_g_cost = g_cost + crane_to_start_cost + move_cost
#new_g_cost = g_cost + move.get_cost(child_state)

h_cost = self.balance_heuristic(child_state)
new_f_cost += new_g_cost + h_cost
Expand All @@ -63,14 +62,19 @@ def balance_heuristic(self, state):
#return abs(left_w - right_w)

best_heuristic_value = float('inf')
for goal_combination in self.valid_combinations:
combinations_to_consider = self.valid_combinations[:4]
for goal_combination in combinations_to_consider:
heuristic_value = self.calculate_distance_heuristic(state, goal_combination)
best_heuristic_value = min(best_heuristic_value, heuristic_value)

return best_heuristic_value

def reconstruct_grids_from_path(self, current_grid, path):


if not path:
print("Path is empty. Cannot reconstruct grids.")
return 0

moves_intermediate_grids = []
grid_copy = copy.deepcopy(current_grid)

Expand All @@ -93,40 +97,27 @@ def reconstruct_grids_from_path(self, current_grid, path):
return (moves_intermediate_grids)

def calculate_distance_heuristic(self, state, goal_combination):

side_a_weights, side_b_weights = set(goal_combination[0]), set(goal_combination[1])
side_a_weights = set(goal_combination[0])

distance_1 = 0
distance_2 = 0
total_distance = 0

# Check containers on the left side
for container in state.left_containers:
if container.weight not in side_a_weights:
row, col = container.get_position()
target_position, min_distance = state.get_nearest_slot_on_other_side(row, col , 'right')
if target_position:
distance_1 += min_distance
for container in state.right_containers:
if container.weight not in side_b_weights:
row, col = container.get_position()
target_position, min_distance = state.get_nearest_slot_on_other_side(row, col , 'left')
target_position, min_distance = state.get_nearest_slot_on_other_side(row, col, 'right')
if target_position:
distance_1 += min_distance
total_distance += min_distance

for container in state.left_containers:
if container.weight not in side_b_weights:
row, col = container.get_position()
target_position, min_distance = state.get_nearest_slot_on_other_side(row, col , 'right')
if target_position:
distance_2 += min_distance
# Check containers on the right side to move to the left
for container in state.right_containers:
if container.weight not in side_a_weights:
if container.weight in side_a_weights:
row, col = container.get_position()
target_position, min_distance = state.get_nearest_slot_on_other_side(row, col , 'left')
target_position, min_distance = state.get_nearest_slot_on_other_side(row, col, 'left')
if target_position:
distance_2 += min_distance

total_distance += min_distance

return min(distance_1, distance_2)
return total_distance

def can_balance(self, state):

Expand Down Expand Up @@ -173,7 +164,7 @@ def can_balance(self, state):
if pair not in used_combinations:
self.valid_combinations.append((list(combination), list(side_b)))
used_combinations.add(pair)
#print(f"Balanceable! Combinations: {self.valid_combinations}")
return can_balance

else:
Expand Down Expand Up @@ -317,7 +308,7 @@ def transfer_helper(self):

while self.open_set:
f_cost, g_cost, path,_, state = heapq.heappop(self.open_set)

if not state.unload_list and not state.load_list:

current_grid = self.start_state
Expand All @@ -334,6 +325,7 @@ def transfer_helper(self):
crane_to_start_cost = state.calulate_transfer_path_cost(state.crane_position, move.from_slot)
move_cost = state.calulate_transfer_path_cost(move.from_slot, move.to_slot)
new_g_cost = g_cost + crane_to_start_cost + move_cost

h_cost = self.transfer_heuristic(child_state)
new_f_cost += new_g_cost + h_cost
move.cost = crane_to_start_cost + move_cost
Expand All @@ -345,8 +337,28 @@ def transfer_helper(self):
return None

def transfer_heuristic(self, state):
return 0

"""Heuristic for transfer, return the estimate cost for the rest of the task to finish
1. Sum the Manhattan distance for unloading to truck
2. Sum the Manhattan distance for loading items from truck to the nearest available slots
"""
grid_copy = copy.deepcopy(state) # Create a deep copy of the state

load_cost = 0
unload_cost = 0

while grid_copy.load_list:
pos_1 = (8, 0)
min_distance, to_slot = grid_copy.get_distance_to_nearest_available_slot(pos_1)
load_cost += min_distance
grid_copy.load_container(to_slot)


for container in grid_copy.unload_list:
unload_cost += (8 - container.row) + container.col

cost = 0.5*load_cost + unload_cost
return cost

def get_containers(self, grid):
containers = grid.left_containers.union(grid.right_containers)
# containers = []
Expand Down
88 changes: 88 additions & 0 deletions Data/manifests/10Containers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
[1,01], {00671}, Beacon
[1,02], {00631}, Nimbus
[1,03], {00000}, UNUSED
[1,04], {00000}, UNUSED
[1,05], {00157}, Comet
[1,06], {00930}, Lunar
[1,07], {00312}, Eclipse
[1,08], {00129}, Matrix
[1,09], {00695}, Shadow
[1,10], {00651}, Circuit
[1,11], {00000}, UNUSED
[2,01], {00000}, UNUSED
[2,02], {00959}, Singularity
[2,03], {00000}, UNUSED
[2,04], {00000}, UNUSED
[2,05], {00000}, UNUSED
[2,06], {00000}, UNUSED
[2,07], {00000}, UNUSED
[2,08], {00000}, UNUSED
[2,09], {00000}, UNUSED
[2,10], {00000}, UNUSED
[2,11], {00000}, UNUSED
[3,01], {00000}, UNUSED
[3,02], {00228}, Gravity
[3,03], {00000}, UNUSED
[3,04], {00000}, UNUSED
[3,05], {00000}, UNUSED
[3,06], {00000}, UNUSED
[3,07], {00000}, UNUSED
[3,08], {00000}, UNUSED
[3,09], {00000}, UNUSED
[3,10], {00000}, UNUSED
[3,11], {00000}, UNUSED
[4,01], {00000}, UNUSED
[4,02], {00000}, UNUSED
[4,03], {00000}, UNUSED
[4,04], {00000}, UNUSED
[4,05], {00000}, UNUSED
[4,06], {00000}, UNUSED
[4,07], {00000}, UNUSED
[4,08], {00000}, UNUSED
[4,09], {00000}, UNUSED
[4,10], {00000}, UNUSED
[4,11], {00000}, UNUSED
[5,01], {00000}, UNUSED
[5,02], {00000}, UNUSED
[5,03], {00000}, UNUSED
[5,04], {00000}, UNUSED
[5,05], {00000}, UNUSED
[5,06], {00000}, UNUSED
[5,07], {00000}, UNUSED
[5,08], {00000}, UNUSED
[5,09], {00000}, UNUSED
[5,10], {00000}, UNUSED
[5,11], {00000}, UNUSED
[6,01], {00000}, UNUSED
[6,02], {00000}, UNUSED
[6,03], {00000}, UNUSED
[6,04], {00000}, UNUSED
[6,05], {00000}, UNUSED
[6,06], {00000}, UNUSED
[6,07], {00000}, UNUSED
[6,08], {00000}, UNUSED
[6,09], {00000}, UNUSED
[6,10], {00000}, UNUSED
[6,11], {00000}, UNUSED
[7,01], {00000}, UNUSED
[7,02], {00000}, UNUSED
[7,03], {00000}, UNUSED
[7,04], {00000}, UNUSED
[7,05], {00000}, UNUSED
[7,06], {00000}, UNUSED
[7,07], {00000}, UNUSED
[7,08], {00000}, UNUSED
[7,09], {00000}, UNUSED
[7,10], {00000}, UNUSED
[7,11], {00000}, UNUSED
[8,01], {00000}, UNUSED
[8,02], {00000}, UNUSED
[8,03], {00000}, UNUSED
[8,04], {00000}, UNUSED
[8,05], {00000}, UNUSED
[8,06], {00000}, UNUSED
[8,07], {00000}, UNUSED
[8,08], {00000}, UNUSED
[8,09], {00000}, UNUSED
[8,10], {00000}, UNUSED
[8,11], {00000}, UNUSED
88 changes: 88 additions & 0 deletions Data/manifests/20Containers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
[01,01], {00000}, UNUSED
[01,02], {00504}, Atlas
[01,03], {00392}, Shard
[01,04], {00000}, UNUSED
[01,05], {00407}, Halo
[01,06], {00466}, Vertex
[01,07], {00731}, Atlas
[01,08], {00277}, Orion
[01,09], {00391}, Meteor
[01,10], {00879}, Axis
[01,11], {00645}, Orion
[02,01], {00000}, UNUSED
[02,02], {00751}, Comet
[02,03], {00809}, Nimbus
[02,04], {00000}, UNUSED
[02,05], {00238}, Glider
[02,06], {00000}, UNUSED
[02,07], {00840}, Dynamo
[02,08], {00225}, Vertex
[02,09], {00000}, UNUSED
[02,10], {00751}, Nimbus
[02,11], {00827}, Twilight
[03,01], {00000}, UNUSED
[03,02], {00000}, UNUSED
[03,03], {00000}, UNUSED
[03,04], {00000}, UNUSED
[03,05], {00756}, Shard
[03,06], {00000}, UNUSED
[03,07], {00000}, UNUSED
[03,08], {00253}, Nimbus
[03,09], {00000}, UNUSED
[03,10], {00731}, Spectrum
[03,11], {00000}, UNUSED
[04,01], {00000}, UNUSED
[04,02], {00000}, UNUSED
[04,03], {00000}, UNUSED
[04,04], {00000}, UNUSED
[04,05], {00000}, UNUSED
[04,06], {00000}, UNUSED
[04,07], {00000}, UNUSED
[04,08], {00000}, UNUSED
[04,09], {00000}, UNUSED
[04,10], {00804}, Halo
[04,11], {00000}, UNUSED
[05,01], {00000}, UNUSED
[05,02], {00000}, UNUSED
[05,03], {00000}, UNUSED
[05,04], {00000}, UNUSED
[05,05], {00000}, UNUSED
[05,06], {00000}, UNUSED
[05,07], {00000}, UNUSED
[05,08], {00000}, UNUSED
[05,09], {00000}, UNUSED
[05,10], {00000}, UNUSED
[05,11], {00000}, UNUSED
[06,01], {00000}, UNUSED
[06,02], {00000}, UNUSED
[06,03], {00000}, UNUSED
[06,04], {00000}, UNUSED
[06,05], {00000}, UNUSED
[06,06], {00000}, UNUSED
[06,07], {00000}, UNUSED
[06,08], {00000}, UNUSED
[06,09], {00000}, UNUSED
[06,10], {00000}, UNUSED
[06,11], {00000}, UNUSED
[07,01], {00000}, UNUSED
[07,02], {00000}, UNUSED
[07,03], {00000}, UNUSED
[07,04], {00000}, UNUSED
[07,05], {00000}, UNUSED
[07,06], {00000}, UNUSED
[07,07], {00000}, UNUSED
[07,08], {00000}, UNUSED
[07,09], {00000}, UNUSED
[07,10], {00000}, UNUSED
[07,11], {00000}, UNUSED
[08,01], {00000}, UNUSED
[08,02], {00000}, UNUSED
[08,03], {00000}, UNUSED
[08,04], {00000}, UNUSED
[08,05], {00000}, UNUSED
[08,06], {00000}, UNUSED
[08,07], {00000}, UNUSED
[08,08], {00000}, UNUSED
[08,09], {00000}, UNUSED
[08,10], {00000}, UNUSED
[08,11], {00000}, UNUSED
Loading