import matplotlib.pyplot as plt
# retrieve dictionaries from ampl with the solution
def retrieve_solution(model):
# open facilities
open = model.var["y"].to_dict()
rounded_open = {key: int(round(value)) for key, value in open.items()}
costs = model.getData(
"{i in CUSTOMERS, j in FACILITIES} cost[i,j] * x[i,j]"
).to_dict()
rounded_costs = {
key: float(round(value, 2))
for key, value in costs.items()
if costs[key] >= 5e-6
}
return rounded_open, rounded_costs
# plot the solution given the nodes, which facilities are open, and the costs
def plot_graph(
customers, facilities, open_facilities, connection_costs, title="p-median problem"
):
# Extract customer and facility coordinates and plot nodes
customer_x, customer_y = zip(*customers.values())
plt.scatter(customer_x, customer_y, color="blue", label="Customers", s=150)
for id, xy in customers.items():
plt.text(xy[0], xy[1], id, color="white", fontsize=10, ha="center", va="center")
open_facilities_coords = [
(xy[0], xy[1]) for f, xy in facilities.items() if open_facilities[f] == 1
]
open_facilities_x, open_facilities_y = zip(*open_facilities_coords)
plt.scatter(
open_facilities_x,
open_facilities_y,
color="green",
label="Open Facilities",
s=170,
)
close_facilities_coords = [
(xy[0], xy[1]) for f, xy in facilities.items() if open_facilities[f] == 0
]
close_facilities_x, close_facilities_y = zip(*close_facilities_coords)
plt.scatter(
close_facilities_x,
close_facilities_y,
color="red",
label="Unused Facilities",
s=170,
)
for id, xy in facilities.items():
plt.text(xy[0], xy[1], id, color="white", fontsize=12, ha="center", va="center")
# Plot edges and label them with costs
for edge, cost in connection_costs.items():
c, f = edge
plt.plot(
[customers[c][0], facilities[f][0]],
[customers[c][1], facilities[f][1]],
color="grey",
linewidth=1,
alpha=0.5,
)
plt.text(
(customers[c][0] + facilities[f][0]) / 2,
(customers[c][1] + facilities[f][1]) / 2,
str(cost),
fontsize=8,
color="black",
)
# Set labels and title
plt.xlabel("X")
plt.ylabel("Y")
plt.title(title)
# Show legend
plt.legend()
# Show plot
plt.grid(True)
plt.show()
open_facilities, costs = retrieve_solution(ampl)
# Plot the graph
plot_graph(customer_coordinates, facility_coordinates, open_facilities, costs)