Commit ebad3ba3 authored by abdelgalil's avatar abdelgalil Committed by Ahmad Reza
Browse files

Created new global communication solution. Locations will now be marked ONLY...

Created new global communication solution. Locations will now be marked ONLY if they are unmarked in all solutions.
parent 66dcf293
[Simulator] [Simulator]
## Seedvalue for the same random sequence ## Seedvalue for the same random sequence
## Different number creates a different random sequence ## Different number creates a different random sequence
seedvalue = 12
seedvalue = 3
;seedvalue = 12
## Maximum round number in swarm-sim ## Maximum round number in swarm-sim
max_round = 30 max_round = 1000
# Visualization 1 = On, 0 = Off # Visualization 1 = On, 0 = Off
visualization = 1 visualization = 1
## 1 = Call of particles in randmom order ## 1 = Call of particles in randmom order
## 0 = Call of particles in added order in scenario ## 0 = Call of particles in added order in scenario
random_order = 1 random_order = 1
## Viewing window size in pixels ## Viewing window size in pixels
window_size_x = 600 window_size_x = 600
window_size_y = 800 window_size_y = 600
## 0 = Unlimited sim size ## 0 = Unlimited sim size
## 1 = limited sim size ## 1 = limited sim size
...@@ -23,8 +25,8 @@ border = 0 ...@@ -23,8 +25,8 @@ border = 0
## Swarm-Sim sim size in points ## Swarm-Sim sim size in points
## Works only with border flag set on 1 ## Works only with border flag set on 1
size_x = 20 size_x = 15
size_y = 20 size_y = 15
## Maximum number of particles that can be created while simulating ## Maximum number of particles that can be created while simulating
max_particles = 10000 max_particles = 10000
...@@ -33,38 +35,22 @@ max_particles = 10000 ...@@ -33,38 +35,22 @@ max_particles = 10000
## with memory (mm) limitation 1=Yes 0=No ## with memory (mm) limitation 1=Yes 0=No
mm_limitation = 0 mm_limitation = 0
## mm size in quantity ## mm size in quantity
## Works only with mm_limitation flag set on 1 ## Works only with mm_limitation flag set on 1
location_mm_size = 2 location_mm_size = 2
particle_mm_size = 2 particle_mm_size = 2
tile_mm_size = 2 tile_mm_size = 2
[File] [File]
##Examples## ##Marking
;scenario = square_terrain.py
##Moving scenario = edgy_terrain.py
#scenario = lonely_particle ;scenario = cressent_terrain.py
#solution = random_walk ;scenario = constricted_terrain.py
#solution = round_walk
## Creating and Deleting
scenario = lonely_particle
solution = create_delete
## Take and Drop
#scenario = between_particle_one_tile_particle
#solution= take_drop_aims
## Read and Write solution = marking_local.py
#scenario = two_particles_tiles_locations ;solution = marking_global.py
#solution = read_write
## Scanning for matters
#scenario = particles_tiles_locations_ring
#solution= scanning_for_all_aims
## All interfaces
#scenario = test_interfaces
#solution = test_all_the_interfaces
import random
from random import randint
import math
E = 0
SE = 1
SW = 2
W = 3
NW = 4
NE = 5
# S = 6 # S for stop and not south
black = 1
gray = 2
red = 3
green = 4
blue = 5
yellow = 6
orange = 7
cyan = 8
violet = 9
dirs = [E, SE, SW, W, NW, NE]
x_offset = [0.5, 1, 0.5, -0.5, -1, -0.5]
y_offset = [1, 0, -1, -1, 0, 1]
dirs_array = [[E, SE, SW, W, NW, NE],
[SE, SW, W, NW, NE, E],
[SW, W, NW, NE, E, SE],
[W, NW, NE, E, SE, SW],
[NW, NE, E, SE, SW, W],
[NE, E, SE, SW, W, NW],
[E, NE, NW, W, SW, SE],
[NE, NW, W, SW, SE, E],
[NW, W, SW, SE, E, NE],
[W, SW, SE, E, NE, NW],
[SW, SE, E, NE, NW, W],
[SE, E, NE, NW, W, SW]]
# -1 = DFS, 0 = BFS
search_algorithms = [-1, 0]
graph = []
visited = []
class Location:
def __init__(self, coords):
self.coords = coords
self.adjacent = []
self.visited = False
def __eq__(self, other):
return self.coords == other.coords
def __str__(self):
return str(self.coords) + ' | Adjacent: ' + str([item.coords for item in self.adjacent])
# Checks if a location exists in a graph
def location_exists(graph, coords):
for location in graph:
if location.coords == coords:
return True
return False
# Returns the location from a graph given the coordinates
def get_location_with_coords(graph, coords):
for location in graph:
if location.coords == coords:
return location
return False
# Returns the direction of a location relative to the current location
def get_dir(current_location, target_location):
if target_location.coords[0] == current_location.coords[0] + x_offset[0] and target_location.coords[1] == current_location.coords[1] + y_offset[0]:
return 0
if target_location.coords[0] == current_location.coords[0] + x_offset[1] and target_location.coords[1] == current_location.coords[1] + y_offset[1]:
return 1
if target_location.coords[0] == current_location.coords[0] + x_offset[2] and target_location.coords[1] == current_location.coords[1] + y_offset[2]:
return 2
if target_location.coords[0] == current_location.coords[0] + x_offset[3] and target_location.coords[1] == current_location.coords[1] + y_offset[3]:
return 3
if target_location.coords[0] == current_location.coords[0] + x_offset[4] and target_location.coords[1] == current_location.coords[1] + y_offset[4]:
return 4
if target_location.coords[0] == current_location.coords[0] + x_offset[5] and target_location.coords[1] == current_location.coords[1] + y_offset[5]:
return 5
# Adds a new location to a graph
def add_location_to_graph(sim, graph, location):
if location in graph:
return
graph.append(location)
for direction in dirs:
adjacent_location_coords = sim.get_coords_in_dir(location.coords, direction)
if location_exists(graph, adjacent_location_coords):
if location in get_location_with_coords(graph, adjacent_location_coords).adjacent:
continue
get_location_with_coords(graph, adjacent_location_coords).adjacent.append(location)
def random_walk(particle):
dir = dirs.copy()
new_dir = random.choice(dir)
particle.move_to_in_bounds(new_dir)
# Checks if the given coordinates are valid simulator coordinates
def valid_sim_coords(sim, coords):
if sim.check_coords(coords[0], coords[1]):
sim_coord = sim.coords_to_sim(coords)
if sim.get_sim_x_size() >= abs(sim_coord[0]) and sim.get_sim_y_size() >= abs(sim_coord[1]):
return True
return False
# Checks if the location at the given coordinates is a border or not
def is_border(sim, coords):
for location in sim.get_location_list():
if coords == location.coords:
if location.color == [0, 0, 0]:
return True
return False
# Initializes the new custom particle attributes
def set_particle_attributes(particle):
directions = dirs_array.copy()
search_algo = search_algorithms.copy()
direction = random.choice(directions)
search_algorithm = random.choice(search_algo)
setattr(particle, "direction", direction)
setattr(particle, "search_algorithm", search_algorithm)
setattr(particle, "unvisited_queue", [])
setattr(particle, "origin_coords", particle.coords)
setattr(particle, "start_location", Location(particle.origin_coords))
setattr(particle, "current_location", particle.start_location)
setattr(particle, "target_location", particle.start_location) # just marks origin position for now
setattr(particle, "last_visited_locations", [])
setattr(particle, "stuck_locations", [])
setattr(particle, "stuck", False)
setattr(particle, "done", False)
# Discovers the adjacent (Neighbour) locations relative to the particle's current location
def discover_adjacent_locations(sim, particle):
global graph
global visited
for direction in particle.direction:
adjacent_location_coords = sim.get_coords_in_dir(particle.current_location.coords, direction)
if not valid_sim_coords(sim, adjacent_location_coords):
continue
if is_border(sim, adjacent_location_coords):
continue
if location_exists(graph, adjacent_location_coords):
if get_location_with_coords(graph, adjacent_location_coords) in particle.current_location.adjacent:
continue
particle.current_location.adjacent.append(get_location_with_coords(graph, adjacent_location_coords))
continue
new_location = Location(adjacent_location_coords)
particle.create_location_on(adjacent_location_coords[0], adjacent_location_coords[1], color=blue)
particle.current_location.adjacent.append(new_location)
particle.unvisited_queue.append(new_location)
add_location_to_graph(sim, graph, new_location)
# Marks the particle's current location as visited and removes it from the particle's unvisited queue
def mark_location(sim, particle):
global visited
particle.current_location.visited = True
visited.append(particle.current_location)
particle.last_visited_locations.append(particle.current_location)
particle.unvisited_queue = [location for location in particle.unvisited_queue if location not in visited]
current_location = sim.get_location_map_coords()[particle.coords]
if current_location.color == [0.0, 0.8, 0.8]:
return
particle.delete_location()
particle.create_location(color=cyan)
# Returns the distance between 2 locations
# TODO(CORE) Is the usage of this distance function considered a GPS tier ability?
def get_distance(location1, location2):
x1 = location1.coords[0]
x2 = location2.coords[0]
y1 = location1.coords[1]
y2 = location2.coords[1]
return abs(math.sqrt(((x2 - x1)**2) + ((y2 - y1)**2)))
# Returns the nearest location in the particle's unvisited queue relative to the particle's current location
def get_nearest_unvisited(particle):
possible_unvisited_locations = []
for location in particle.unvisited_queue:
possible_unvisited_locations.append((round(get_distance(particle.current_location, location)), location))
return min(possible_unvisited_locations, key=lambda t: t[0])[1]
# Returns the next best possible move if the particle's target location is not adjacent to it (path generator)
def get_next_best_location(current_location, target_location, stuck_locations):
possible_moves = []
for location in current_location.adjacent:
if location in stuck_locations:
continue
else:
possible_moves.append((get_distance(location, target_location), location))
if len(possible_moves) is 0:
return current_location.adjacent[randint(0, len(current_location.adjacent) - 1)]
best_location = min(possible_moves, key=lambda t: t[0])[1]
return best_location
# Returns the next closest unvisited location relative to the particle's current location
def get_next_unvisited(particle):
if particle.unvisited_queue[particle.search_algorithm] not in particle.current_location.adjacent:
return get_next_best_location(particle.current_location, get_nearest_unvisited(particle), particle.stuck_locations)
else:
return particle.unvisited_queue[particle.search_algorithm]
# Checks if the particle's next location is in a stuck cycle or not
def next_location_in_stuck_nodes(particle, next_location):
if next_location in particle.last_visited_locations:
if next_location in particle.stuck_locations:
particle.stuck = True
return True
else:
particle.stuck_locations.append(next_location)
return False
else:
particle.last_visited_locations.append(next_location)
return False
def solution(sim):
global graph
global visited
done_particles = 0
# ***** Research Variables ***** #
clear_cycle_frequency = 20
for particle in sim.get_particle_list():
if sim.get_actual_round() == 1:
set_particle_attributes(particle)
particle.create_location_on(particle.origin_coords[0], particle.origin_coords[1], color=blue)
add_location_to_graph(sim, graph, particle.current_location)
discover_adjacent_locations(sim, particle)
else:
# TODO(OPTIMIZATION) How many locations should form the stuck cycle? Is there a better solution?
# if len(particle.stuck_locations) >= clear_cycle_frequency:
if sim.get_actual_round() % clear_cycle_frequency == 0:
particle.stuck_locations.clear()
try:
next_location = get_next_unvisited(particle) # 0 for BFS, -1 for DFS
if next_location_in_stuck_nodes(particle, next_location):
next_location = particle.current_location.adjacent[
randint(0, len(particle.current_location.adjacent) - 1)]
next_direction = get_dir(particle.current_location, next_location)
particle.current_location = next_location
discover_adjacent_locations(sim, particle)
mark_location(sim, particle)
particle.move_to(next_direction)
except ValueError:
discover_adjacent_locations(sim, particle)
except IndexError:
particle.current_location = get_location_with_coords(graph, particle.coords)
discover_adjacent_locations(sim, particle)
mark_location(sim, particle)
if particle.current_location.coords == particle.target_location.coords:
particle.stuck_locations.clear()
done_particles += 1
particle.done = True
continue
else:
particle.current_location = get_location_with_coords(graph, particle.coords)
discover_adjacent_locations(sim, particle)
mark_location(sim, particle)
try:
next_location = get_next_best_location(particle.current_location, particle.target_location, particle.stuck_locations)
if next_location_in_stuck_nodes(particle, next_location):
next_location = particle.current_location.adjacent[
randint(0, len(particle.current_location.adjacent) - 1)]
next_direction = get_dir(particle.current_location, next_location)
particle.current_location = next_location
discover_adjacent_locations(sim, particle)
if location_exists(graph, next_location.coords):
particle.move_to(next_direction)
except ValueError:
discover_adjacent_locations(sim, particle)
# TODO(OPTIMIZATION) Should the simulation succeed when all locations have been marked or when all particles are back to nest?
if done_particles == len(sim.get_particle_list()):
print(sim.get_actual_round())
sim.success_termination()
...@@ -204,11 +204,16 @@ def discover_adjacent_locations(sim, particle): ...@@ -204,11 +204,16 @@ def discover_adjacent_locations(sim, particle):
# Marks the particle's current location as visited and removes it from the particle's unvisited queue # Marks the particle's current location as visited and removes it from the particle's unvisited queue
def mark_location_as_visited(particle): def mark_location(sim, particle):
particle.current_location.visited = True particle.current_location.visited = True
particle.visited.append(particle.current_location) particle.visited.append(particle.current_location)
particle.last_visited_locations.append(particle.current_location) particle.last_visited_locations.append(particle.current_location)
particle.unvisited_queue = [location for location in particle.unvisited_queue if location not in particle.visited] particle.unvisited_queue = [location for location in particle.unvisited_queue if location not in particle.visited]
current_location = sim.get_location_map_coords()[particle.coords]
if current_location.color == [0.0, 0.8, 0.8]:
return
particle.delete_location() particle.delete_location()
particle.create_location(color=cyan) particle.create_location(color=cyan)
...@@ -275,7 +280,7 @@ def communicate(particle, communication_range): ...@@ -275,7 +280,7 @@ def communicate(particle, communication_range):
particle.write_to_with(particle, particle.get_id(), packet) particle.write_to_with(particle, particle.get_id(), packet)
# Enables the particle to extend its own data with the data recieved from other particles # Enables the particle to extend its own data with the data received from other particles
def analyse_memory(sim, particle): def analyse_memory(sim, particle):
if particle.read_whole_memory(): if particle.read_whole_memory():
for particle_id in particle.read_whole_memory(): for particle_id in particle.read_whole_memory():
...@@ -306,8 +311,10 @@ def next_location_in_stuck_nodes(particle, next_location): ...@@ -306,8 +311,10 @@ def next_location_in_stuck_nodes(particle, next_location):
def solution(sim): def solution(sim):
done_particles = 0 done_particles = 0
communication = True
# ***** Research Variables ***** # # ***** Research Variables ***** #
start_communication_round = 35 start_communication_round = 30
communication_frequency = 15 communication_frequency = 15
communication_range = 5 communication_range = 5
clear_cycle_frequency = 20 clear_cycle_frequency = 20
...@@ -323,9 +330,9 @@ def solution(sim): ...@@ -323,9 +330,9 @@ def solution(sim):
else: else:
# TODO(OPTIMIZATION) How often should the particles communicate if they are within range? # TODO(OPTIMIZATION) How often should the particles communicate if they are within range?
if sim.get_actual_round() > start_communication_round: if sim.get_actual_round() > start_communication_round:
if sim.get_actual_round() % communication_frequency == 0: if communication:
communicate(particle, communication_range) if sim.get_actual_round() % communication_frequency == 0:
# pass communicate(particle, communication_range)
analyse_memory(sim, particle) analyse_memory(sim, particle)
...@@ -344,21 +351,22 @@ def solution(sim): ...@@ -344,21 +351,22 @@ def solution(sim):
next_direction = get_dir(particle.current_location, next_location) next_direction = get_dir(particle.current_location, next_location)
particle.current_location = next_location particle.current_location = next_location
discover_adjacent_locations(sim, particle) discover_adjacent_locations(sim, particle)
mark_location_as_visited(particle) mark_location(sim, particle)
particle.move_to(next_direction) particle.move_to(next_direction)
except ValueError: except ValueError:
discover_adjacent_locations(sim, particle) discover_adjacent_locations(sim, particle)
except IndexError: except IndexError:
mark_location_as_visited(particle)
particle.current_location = get_location_with_coords(particle.graph, particle.coords) particle.current_location = get_location_with_coords(particle.graph, particle.coords)
discover_adjacent_locations(sim, particle) discover_adjacent_locations(sim, particle)
mark_location(sim, particle)
if particle.current_location is particle.target_location: if particle.current_location is particle.target_location:
particle.stuck_locations.clear() particle.stuck_locations.clear()
done_particles += 1 done_particles += 1
particle.done = True particle.done = True
# particle.csv_particle_writer.success()
continue continue
else: else:
...@@ -383,6 +391,5 @@ def solution(sim): ...@@ -383,6 +391,5 @@ def solution(sim):
# TODO(OPTIMIZATION) Should the simulation succeed when all locations have been marked or when all particles are back to nest? # TODO(OPTIMIZATION) Should the simulation succeed when all locations have been marked or when all particles are back to nest?
if done_particles == len(sim.get_particle_list()): if done_particles == len(sim.get_particle_list()):
print(sim.get_actual_round()) print(sim.get_actual_round())
sim.csv_round_writer.success() sim.success_termination()
sim.set_end()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment