Finish Discrete Optimization.
This commit is contained in:
41
tsp/map.py
41
tsp/map.py
@@ -6,10 +6,9 @@ class Map(object):
|
||||
# and neighbor regions. We can actually cluster in O(n) when we know how
|
||||
# high and wide the clusters are. Once we have that working we go from
|
||||
# there
|
||||
CLUSTERS_X = 4 # How many points we want per cluster.
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self, n_clusters):
|
||||
self.CLUSTERS_X = n_clusters
|
||||
|
||||
def calc_corners(self, points):
|
||||
x_min, x_max = float("inf"), float("-inf")
|
||||
@@ -95,26 +94,30 @@ class Map(object):
|
||||
self.add_neighbors_to_points(points)
|
||||
return points
|
||||
|
||||
def plot(self, points):
|
||||
def plot_grid(self, plt):
|
||||
if plt is None:
|
||||
return
|
||||
for x_i in range(self.clusters_x + 1):
|
||||
x_1 = self.x_min + x_i * self.cluster_x_dim
|
||||
x_2 = x_1
|
||||
y_1 = self.y_min
|
||||
y_2 = self.y_max
|
||||
plt.plot([x_1, x_2], [y_1, y_2], 'y:', linewidth=0.1)
|
||||
for y_i in range(self.clusters_y + 1):
|
||||
x_1 = self.x_min
|
||||
x_2 = self.x_max
|
||||
y_1 = self.y_min + y_i * self.cluster_y_dim
|
||||
y_2 = y_1
|
||||
plt.plot([x_1, x_2], [y_1, y_2], 'y:', linewidth=0.1)
|
||||
|
||||
def plot(self, points, plt):
|
||||
if plt is None:
|
||||
return
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
except ModuleNotFoundError:
|
||||
return
|
||||
|
||||
def plot_grid():
|
||||
for x_i in range(self.clusters_x + 1):
|
||||
x_1 = self.x_min + x_i * self.cluster_x_dim
|
||||
x_2 = x_1
|
||||
y_1 = self.y_min
|
||||
y_2 = self.y_max
|
||||
plt.plot([x_1, x_2], [y_1, y_2], 'b:')
|
||||
for y_i in range(self.clusters_y + 1):
|
||||
x_1 = self.x_min
|
||||
x_2 = self.x_max
|
||||
y_1 = self.y_min + y_i * self.cluster_y_dim
|
||||
y_2 = y_1
|
||||
plt.plot([x_1, x_2], [y_1, y_2], 'b:')
|
||||
|
||||
def plot_arrows():
|
||||
for i in range(len_points):
|
||||
p1 = points[i - 1]
|
||||
@@ -140,6 +143,6 @@ class Map(object):
|
||||
|
||||
len_points = len(points)
|
||||
plot_points()
|
||||
plot_grid()
|
||||
self.plot_grid(plt)
|
||||
plot_arrows()
|
||||
plt.show()
|
||||
|
||||
39
tsp/tsp.py
39
tsp/tsp.py
@@ -2,7 +2,11 @@ import math
|
||||
import time
|
||||
from functools import lru_cache
|
||||
from random import shuffle, choice, uniform
|
||||
from map import Map
|
||||
from map import Map as ClusterMap
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
except ModuleNotFoundError:
|
||||
plt = None
|
||||
|
||||
|
||||
@lru_cache(maxsize=100000)
|
||||
@@ -53,12 +57,6 @@ class Point(object):
|
||||
neighbors = [(n, distance(self, n)) for n in neighbors]
|
||||
self.neighbors = sorted(neighbors, key=lambda t: t[1])
|
||||
|
||||
def copy(self):
|
||||
p = Point(self.id, self.x, self.y)
|
||||
p.index = self.index
|
||||
p.neighbors = self.neighbors
|
||||
return p
|
||||
|
||||
def __str__(self):
|
||||
# m = "P_{}({}, {})".format(self.index, self.x, self.y)
|
||||
# m = "P_{}({}, {})".format(self.index, self.cluster_x, self.cluster_y)
|
||||
@@ -120,7 +118,7 @@ def swap_edges(i, j, points, current_distance=0):
|
||||
def k_opt(p1, route):
|
||||
steps = []
|
||||
ignore_set = set()
|
||||
for _ in range(5):
|
||||
for _ in range(10):
|
||||
p2 = route.points[(p1.index + 1) % route.len_points]
|
||||
dist_p1p2 = distance(p1, p2)
|
||||
ignore_set.add(p2)
|
||||
@@ -177,6 +175,7 @@ def local_search_k_opt(route, goal, m):
|
||||
|
||||
no_improvement_iterations += 1
|
||||
if no_improvement_iterations > 10:
|
||||
break
|
||||
# print("[random k-opt] current_total={}".format(current_total))
|
||||
while True:
|
||||
point = choice(route.points)
|
||||
@@ -190,7 +189,7 @@ def local_search_k_opt(route, goal, m):
|
||||
|
||||
if current_total < goal:
|
||||
return
|
||||
|
||||
#
|
||||
|
||||
class Route(object):
|
||||
def __init__(self, points):
|
||||
@@ -324,9 +323,18 @@ class Route(object):
|
||||
p.index = i
|
||||
|
||||
|
||||
def solve_it_(input_data):
|
||||
def solve_tsp(points):
|
||||
r = Route(points)
|
||||
m = ClusterMap(2)
|
||||
m.cluster(r.points)
|
||||
r.route_from_clusters(m)
|
||||
local_search_k_opt(r, 0, m)
|
||||
return r.points
|
||||
|
||||
|
||||
def solve_it(input_data):
|
||||
r = Route(parse_input_data(input_data))
|
||||
m = Map()
|
||||
m = ClusterMap(4)
|
||||
m.cluster(r.points)
|
||||
|
||||
goal = {51: 429, # 4
|
||||
@@ -340,12 +348,13 @@ def solve_it_(input_data):
|
||||
|
||||
r.route_from_clusters(m)
|
||||
local_search_k_opt(r, goal, m)
|
||||
m.plot(r.points)
|
||||
m.plot(r.points, plt)
|
||||
|
||||
r.verify_total_distance()
|
||||
return prepare_output_data(r.points)
|
||||
|
||||
def solve_it(input_data):
|
||||
|
||||
def solve_it_(input_data):
|
||||
r = Route(parse_input_data(input_data))
|
||||
n = len(r.points)
|
||||
if n == 51:
|
||||
@@ -369,11 +378,11 @@ def solve_it(input_data):
|
||||
|
||||
if __name__ == "__main__":
|
||||
# file_location = "data/tsp_6_1"
|
||||
# file_location = "data/tsp_51_1"
|
||||
file_location = "data/tsp_51_1"
|
||||
# file_location = "data/tsp_100_3"
|
||||
# file_location = "data/tsp_200_2"
|
||||
# file_location = "data/tsp_574_1"
|
||||
file_location = "data/tsp_1889_1"
|
||||
# file_location = "data/tsp_1889_1"
|
||||
# file_location = "data/tsp_33810_1"
|
||||
with open(file_location, 'r') as input_data_file:
|
||||
input_data = input_data_file.read()
|
||||
|
||||
Reference in New Issue
Block a user