praca_magisterska/dataset/generate_grid.py

170 lines
6.7 KiB
Python
Raw Normal View History

import random as rand
from pathlib import Path
def generate_grid(height: int, width: int, fill_percent: int = 70):
"""
Generates grid with a simple maze. Path is signed as 'p' and walls as 'w'. It always has walls surrounding it.
:param height: height of the grid.
:param width: width of the grid.
:param fill_percent: percentage of walls in the maze (not counting surrounding walls).
:return:
"""
grid = []
for i in range(height):
grid.append([])
for j in range(width):
grid[i].append('w')
path_percent = (100. - float(fill_percent)) / 100.
grid_size = float((height-2) * (width-2))
paths_number = int(path_percent * grid_size)
start_point_y = height // 2
start_point_x = width // 2
grid[start_point_y][start_point_x] = 'p'
set_paths = 1
path_list = [(start_point_y, start_point_x)]
while set_paths < paths_number:
chosen_position = rand.randint(0, len(path_list)-1)
random_growth = rand.randint(0, 3)
if random_growth == 0:
if path_list[chosen_position][0]+1 == height-1:
continue
else:
new_y = path_list[chosen_position][0] + 1
new_x = path_list[chosen_position][1]
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x-1] == 'p' or grid[new_y][new_x+1] == 'p' or grid[new_y+1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
elif random_growth == 1:
if path_list[chosen_position][1]-1 == 0:
continue
else:
new_y = path_list[chosen_position][0]
new_x = path_list[chosen_position][1] - 1
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x-1] == 'p' or grid[new_y-1][new_x] == 'p' or grid[new_y+1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
elif random_growth == 2:
if path_list[chosen_position][0]-1 == 0:
continue
else:
new_y = path_list[chosen_position][0]-1
new_x = path_list[chosen_position][1]
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x+1] == 'p' or grid[new_y][new_x-1] == 'p' or grid[new_y-1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
elif random_growth == 3:
if path_list[chosen_position][1] + 1 == width-1:
continue
else:
new_y = path_list[chosen_position][0]
new_x = path_list[chosen_position][1] + 1
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x+1] == 'p' or grid[new_y-1][new_x] == 'p' or grid[new_y+1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
return grid
def write_grid_as_graph_to_file(grid, filename, path="grids/"):
"""
Writes generated grid to file as a graph with weights
:param grid: grid generated by function generate_grid
:param filename: name of the file to save the graph to
:param path: path to save the file in
:return: None
"""
with open(path + filename, 'w') as file:
for i in range(1, len(grid)-1):
for j in range(1, len(grid[i])-1):
if grid[i][j] == 'p':
if grid[i-1][j] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i-1) + " " + str(j) + "," + "1" + "\n")
if grid[i+1][j] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i+1) + " " + str(j) + "," + "1" + "\n")
if grid[i][j-1] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i) + " " + str(j-1) + "," + "1" + "\n")
if grid[i][j+1] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i) + " " + str(j+1) + "," + "1" + "\n")
def read_grid_graph_from_file(filename, path="grids/"):
N = set()
A = {}
A_b = {}
w = {}
with open(path + filename, "r") as file:
line = file.readline()
while line != '':
split = line.strip("\n").split(",")
fist_node_str_list = split[0].split(" ")
second_node_str_list = split[1].split(" ")
weight = int(split[2])
first_node = (int(fist_node_str_list[0]), int(fist_node_str_list[1]))
second_node = (int(second_node_str_list[0]), int(second_node_str_list[1]))
N.add(first_node)
N.add(second_node)
if first_node not in A.keys():
A[first_node] = [second_node]
else:
A[first_node].append(second_node)
if second_node not in A_b.keys():
A_b[second_node] = [first_node]
else:
A_b[second_node].append(first_node)
w[(first_node, second_node)] = weight
line = file.readline()
return N, A, A_b, w
if __name__ == "__main__":
n = [(20, 20), (50, 50), (100, 100), (150, 150), (250, 250), (500, 500)]
for i in range(1, len(n)+1):
p = "grids/" + str(n[i-1][0]) + "x" + str(n[i-1][1]) + "/"
print("generating graphs group:", n[i - 1])
for j in range(1, 51):
f = "grid" + str(j)
print(f)
g = generate_grid(n[i-1][0]+2, n[i-1][1]+2)
Path(p).mkdir(parents=True, exist_ok=True)
write_grid_as_graph_to_file(g, f, p)
print()