add the TSM problem altogyrtm
This commit is contained in:
@@ -0,0 +1,108 @@
|
|||||||
|
from math import sqrt as wurzel
|
||||||
|
from math import factorial
|
||||||
|
import sys
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
if sys.argv[1] == "--mode":
|
||||||
|
mode = sys.argv[2]
|
||||||
|
else:
|
||||||
|
mode = "normal"
|
||||||
|
|
||||||
|
|
||||||
|
points = []
|
||||||
|
|
||||||
|
def get_possbile_ways():
|
||||||
|
x=len(points)
|
||||||
|
return factorial(x)
|
||||||
|
|
||||||
|
def get_distance_point(p1, p2):
|
||||||
|
dx = p2["x"] - p1["x"]
|
||||||
|
dy = p2["y"] - p1["y"]
|
||||||
|
|
||||||
|
return wurzel(dx**2 + dy**2)
|
||||||
|
|
||||||
|
def get_distance_points(p):
|
||||||
|
distance = 0
|
||||||
|
for i in range(len(p) - 1):
|
||||||
|
distance += get_distance_point(p[i], p[i + 1])
|
||||||
|
return distance
|
||||||
|
|
||||||
|
def add_point(x=None, y=None):
|
||||||
|
if x is None or y is None:
|
||||||
|
try:
|
||||||
|
x = int(input("Whats the x coodinate\n>"))
|
||||||
|
except ValueError:
|
||||||
|
print("Invalid input")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
y = int(input("Whats the y coodinate\n>"))
|
||||||
|
except ValueError:
|
||||||
|
print("Invalid input")
|
||||||
|
return
|
||||||
|
points.append({"x": x, "y": y})
|
||||||
|
|
||||||
|
def generate_points():
|
||||||
|
try:
|
||||||
|
n = int(input("How many points?\n>"))
|
||||||
|
except ValueError:
|
||||||
|
print("Invalid input")
|
||||||
|
return
|
||||||
|
for _ in range(n):
|
||||||
|
add_point(x=random.randint(0, 100 if n < 50 else 1000), y=random.randint(0, 100 if n < 50 else 1000))
|
||||||
|
|
||||||
|
def bruteforce():
|
||||||
|
max_ways = get_possbile_ways()
|
||||||
|
if mode == "verbose":
|
||||||
|
print(f"Possible ways: {max_ways}")
|
||||||
|
time.sleep(2)
|
||||||
|
ways = []
|
||||||
|
for i in range(max_ways):
|
||||||
|
new_way = []
|
||||||
|
while len(new_way) < len(points):
|
||||||
|
n = random.choice(points)
|
||||||
|
if n not in new_way:
|
||||||
|
new_way.append(n)
|
||||||
|
distance = get_distance_points(new_way)
|
||||||
|
if mode == "verbose":
|
||||||
|
print(f"\r{i + 1}: {new_way}, distance: {distance}", end="")
|
||||||
|
ways.append({"way": new_way, "distance": distance})
|
||||||
|
return ways
|
||||||
|
|
||||||
|
def start():
|
||||||
|
print("TSM algorithm")
|
||||||
|
start = time.monotonic()
|
||||||
|
ways = bruteforce()
|
||||||
|
end = time.monotonic()
|
||||||
|
print(f"Took: {end - start}")
|
||||||
|
distances = []
|
||||||
|
for i in range(len(ways)):
|
||||||
|
distances.append(ways[i]["distance"])
|
||||||
|
print(f"Fastest: {min(distances)}, slowest: {max(distances)}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
while True:
|
||||||
|
print("1: add point")
|
||||||
|
print("2: generate points")
|
||||||
|
print("3: start")
|
||||||
|
print("q: quit")
|
||||||
|
cmd = input("> ").strip().lower()
|
||||||
|
if cmd in ["1", "add point"]:
|
||||||
|
add_point()
|
||||||
|
elif cmd in ["2", "generate points"]:
|
||||||
|
generate_points()
|
||||||
|
elif cmd in ["3", "start"]:
|
||||||
|
if len(points) < 2:
|
||||||
|
print("Not enough points")
|
||||||
|
else:
|
||||||
|
start()
|
||||||
|
elif cmd in ["q", "quit"]:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user