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