Add support for opening facilities.

main
Felix Martin 2020-01-06 17:18:30 -05:00
parent 13104943ca
commit c3d6863ab6
1 changed files with 32 additions and 22 deletions

View File

@ -182,12 +182,12 @@ class Solution(object):
x, y = f.location
color = 'ro' if f.is_open else 'go'
plt.plot(x, y, color)
plt.text(x, y, f"{f}")
# plt.text(x, y, f"{f}")
for c in self.cs:
x, y = c.location
plt.plot(x, y, 'bx')
plt.text(x, y, f"{c}")
# plt.text(x, y, f"{c}")
if (f := c.facility) is not None:
x_f, y_f = f.location
@ -245,7 +245,8 @@ class Solution(object):
return f.add(customer)
elif new_length > current_length:
return 0
not_connected.append(customer)
if not customer.facility:
not_connected.append(customer)
return 0
delta += sum([connect_better_facility(c) for c in customers])
return delta, not_connected
@ -265,7 +266,7 @@ class Solution(object):
elif self.cost < original_cost:
delta = original_cost - self.cost
logging.info(f"Close {facility} resulted in improvement {delta}.")
return
return True
else:
logging.debug(f"No improvement. Restore.")
@ -274,43 +275,52 @@ class Solution(object):
self.cost += delta
assert(not not_connected)
assert(abs(original_cost - self.cost) < EPSILON)
return False
def open_facility(self, facility):
raise Exception("Has bugs!")
logging.debug(f"Open {facility}.")
logging.debug(f"Opening {facility}.")
original_cost = self.cost
self.cost += facility.set_open()
delta, not_connected = self.reconnect_greedy(self.cs)
self.cost += delta
if not_connected:
logging.debug("Not all customers connected. Restore.")
elif self.cost < original_cost:
moved = []
for c in self.cs:
if c.demand < facility.remaining_capacity and \
length.get(c, c.facility) > length.get(c, facility):
moved.append({"previous_facility": c.facility, "c": c})
self.cost += facility.add(c)
if self.cost < original_cost:
delta = original_cost - self.cost
logging.info(f"Open {facility} resulted in improvement {delta}.")
return
return True
else:
logging.debug(f"No improvement. Restore.")
self.cost += facility.remove_all_and_close()
delta, not_connected = self.reconnect_greedy(self.cs)
self.cost += delta
for m in moved:
c = m["c"]
f = m["previous_facility"]
self.cost += f.add(c)
self.cost += facility.set_not_open()
assert(not not_connected)
assert(abs(original_cost - self.cost) < EPSILON)
return False
def local_search(self):
fs = [f for f in self.fs if f.is_open]
fs.sort(key=lambda f: len(f.customers))
for f in fs:
self.close_facility(f)
# fs = [f for f in self.fs if not f.is_open]
# fs.sort(key=lambda f: f.setup_cost)
# for f in fs:
# self.open_facility(f)
delta, not_connected = self.reconnect_greedy(self.cs)
if not_connected:
raise Exception(f"{not_connected=}")
self.cost += delta
fs = [f for f in self.fs if not f.is_open]
fs.sort(key=lambda f: f.setup_cost)
for f in fs:
self.open_facility(f)
def solve_it(input_data):
@ -321,7 +331,7 @@ def solve_it(input_data):
solution.build_greedy()
solution.reconnect_greedy(solution.cs)
solution.local_search()
# solution.plot_map()
solution.plot_map()
output_data = solution.to_output_data()
return output_data