diff --git a/23ss_MiM_Bonus_01.pdf b/23ss_MiM_Bonus_01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9f6bc5da322a4ed0cd96496911a55661dfcfd99a Binary files /dev/null and b/23ss_MiM_Bonus_01.pdf differ diff --git a/Acht-Damen.py b/Acht-Damen.py new file mode 100644 index 0000000000000000000000000000000000000000..2fa708495c37521db703c1b9d29f1f3033dfa3d3 --- /dev/null +++ b/Acht-Damen.py @@ -0,0 +1,87 @@ +import numpy as np +from copy import deepcopy + + +class Board: + blocked = 0 + allowed = 1 + queen = 2 + + def __init__(self, x: int, y: int): + self.board = np.ones((x, y), dtype=int) + self.dimX = x + self.dimY = y + + def copy(self): + return deepcopy(self) + + def toConsole(self) -> None: + for y in range(self.dimY): + line = "" + for x in range(self.dimX): + if self.board[x, y] == self.blocked: + line += "X" + if self.board[x, y] == self.allowed: + line += "O" + if self.board[x, y] == self.queen: + line += "@" + print(line) + print("") + + def print(self) -> None: + self.toConsole() + + def get_allowed_fields(self): + allowed_fields = [] + for x in range(self.dimX): + for y in range(self.dimY): + if self.board[x, y] == self.allowed: + allowed_fields.append((x, y)) + return allowed_fields + + def get_queen_fields(self): + queen_fields = [] + for x in range(self.dimX): + for y in range(self.dimY): + if self.board[x, y] == self.allowed: + queen_fields.append((x, y)) + return queen_fields + + def put_queen(self, x: int, y: int) -> bool: + if self.board[x, y] == self.allowed: + for _x in range(self.dimX): + self.board[_x, y] = self.blocked + for _y in range(self.dimY): + self.board[x, _y] = self.blocked + + _x = x + _y = y + while _x > 0 and _y > 0: + _y -= 1 + _x -= 1 + self.board[_x, _y] = self.blocked + + _x = x + _y = y + while _x < self.dimX-1 and _y < self.dimY-1: + _y += 1 + _x += 1 + self.board[_x, _y] = self.blocked + self.board[x, y] = self.queen + return True + else: + return False + + +if __name__ == "__main__": + board = Board(8, 8) + + saved_boards = [] + iters = 0 + while board.get_allowed_fields().__len__() > 0: + board.put_queen(board.get_allowed_fields()[0][0], + board.get_allowed_fields()[0][1]) + iters += 1 + board.toConsole() + saved_boards.append(board.copy()) + print("Queens: " + str(iters)) diff --git a/TravellingSalesman.py b/TravellingSalesman.py index 137ea479fce93ddbf06c6df4b01593b1d7b71af6..faf277b61b9c52aa387e249537813fd3fdd26a23 100644 --- a/TravellingSalesman.py +++ b/TravellingSalesman.py @@ -4,16 +4,17 @@ from random import randint from string import ascii_uppercase from itertools import permutations # config: -brute_force = True -num_nodes = 9 -do_plot = True +brute_force = False +optimize = True +num_nodes = 10 +do_plot = False pause = 1 class Node: x: int y: int name: str - def __init__(self, x: int, y: int, name: str): + def __init__(self, x: int, y: int, name: str = ""): self.x = x self.y = y self.name = name @@ -46,24 +47,27 @@ class Path: plt.plot([this.A.x, this.B.x], [this.A.y, this.B.y], 'go-') -def plot_route(route: list) -> None: +def plot_route(route: list, nodes: list = [], circle: bool = False) -> None: plt.close("all") for i in range(len(route)): - if i == len(route) - 1: + if i == len(route) - 1 and circle: Path(A=route[i], B=route[0]).plot() else: Path(A=route[i], B=route[i+1]).plot() + for node in nodes: + node.plot() plt.show() plt.pause(pause) -def brute(nodes: list): +def brute(nodes: list) -> list: if len(nodes) <= 1: return best_route = nodes best_route_length = total_distance(nodes) if do_plot: plot_route(best_route) +#TODO Noch nicht rekursiv! for i, route in enumerate(permutations(nodes, len(nodes))): route_length = total_distance(route) if route_length < best_route_length: @@ -76,6 +80,36 @@ def brute(nodes: list): return best_route +def get_closest_node(current_node: Node, nodes: list) -> Node: + if len(nodes) == 0: + return + closest_node = nodes[0] + closest_distance = distance(current_node, nodes[0]) + for node in nodes: + dist = distance(current_node, node) + if dist < closest_distance: + closest_node = node + closest_distance = dist + return closest_node + +def nearest_neighbour(_nodes: list) -> list: + remaining_nodes = _nodes.copy() + route = [] + if len(remaining_nodes) == 0: + return route + route.append(remaining_nodes[0]) + last_node = remaining_nodes[0] + remaining_nodes.remove(last_node) + while(len(remaining_nodes) > 0): + next_node = get_closest_node(last_node, remaining_nodes) + remaining_nodes.remove(next_node) + route.append(next_node) + last_node = next_node + if do_plot: + plot_route(route, _nodes) + return route + + def generate_paths(nodes: list) -> list: _nodes = nodes.copy() paths = [] @@ -94,16 +128,74 @@ def generate_paths(nodes: list) -> list: return paths +#TODO Zuweisungen brechen die Kette! +def optimize_2opt(_route: list) -> list: + route = _route.copy() + + for i in range(len(route)-1): + a = route[i] + b = route[i+1] + ab = distance(a, b) + + for j in range(2, len(route)-1): + swapped = False + c = route[j] + d = route[j+1] + + cd = distance(c, d) + abcd = ab + cd + + ac = distance(a, c) + db = distance(d, b) + acdb = ac + db + + ad = distance(a, d) + cb = distance(c, b) + adcb = ad + cb + + if adcb < acdb: + if adcb < abcd: + #adcb + #swap d & b + route[i+1] = d + route[j+1] = b + #abcd + swapped = True + else: + if acdb < abcd: + #acdb + #swap c & b + route[j] = b + route[i+1] = c + #abdc + #swap c & d + route[j] = d + route[j+1] = c + #abcd + swapped = True + if swapped: + break + + + return route + + if __name__ == "__main__": nodes = [] for i in range(num_nodes): - nodes.append(Node(x=randint(0, 100), y=randint(0, 100), name=ascii_uppercase[i])) + nodes.append(Node(x=randint(0, 100), y=randint(0, 100), name=str(hex(i)))) plt.ion() - best_route = brute(nodes) + if brute_force: + best_route = brute(nodes) + else: + best_route = nearest_neighbour(nodes) + if optimize: + best_route = optimize_2opt(best_route) + - plot_route(best_route) + plot_route(best_route, nodes, circle=True) plt.show(block=True)