Skip to content

Commit

Permalink
add specification errors and raise when infeasible capacitated p_medi…
Browse files Browse the repository at this point in the history
…an is requested
  • Loading branch information
ljwolf committed Mar 1, 2023
1 parent 47abb42 commit d99315f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
2 changes: 2 additions & 0 deletions spopt/locate/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
-3: "Undefined",
}

class SpecificationError(pulp.PulpError):
pass

class LocateSolver(BaseSpOptExactSolver):
"""Base class for the ``locate`` package."""
Expand Down
7 changes: 4 additions & 3 deletions spopt/locate/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
BackupPercentageMixinMixin,
LocateSolver,
FacilityModelBuilder,
SpecificationError
)
from scipy.spatial.distance import cdist

Expand Down Expand Up @@ -227,7 +228,7 @@ def from_cost_matrix(
lscp = LSCP(name, model)

if demand_quantity_arr is not None and facility_capacity_arr is None:
raise ValueError(
raise SpecificationError(
"Demand quantities supplied with no facility capacities. "
"Model cannot satisfy clients with different "
"demands without facility capacities."
Expand All @@ -250,7 +251,7 @@ def from_cost_matrix(
sum_demand = demand_quantity_arr.sum()
sum_capacity = facility_capacity_arr.sum()
if sum_demand > sum_capacity:
raise ValueError(
raise SpecificationError(
f"Infeasible model. Demand greater than capacity "
f"({sum_demand} > {sum_capacity})."
)
Expand Down Expand Up @@ -404,7 +405,7 @@ def from_geodataframe(
facility_capacity_arr = gdf_fac[facility_capacity_col].to_numpy()

if demand_quantity_arr is not None and facility_capacity_arr is None:
raise ValueError(
raise SpecificationError(
"Demand quantities supplied with no facility capacities. "
"Model cannot satisfy clients with different "
"demands without facility capacities."
Expand Down
10 changes: 10 additions & 0 deletions spopt/locate/p_median.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
LocateSolver,
FacilityModelBuilder,
MeanDistanceMixin,
SpecificationError
)
from scipy.spatial.distance import cdist

Expand Down Expand Up @@ -252,6 +253,15 @@ def from_cost_matrix(
p_median, predefined_facilities_arr
)
if facility_capacities is not None:
sorted_capacities = np.sort(facility_capacities)
highest_possible_capacity = sorted_capacities[-p_facilities:].sum()
if highest_possible_capacity < weights.sum():
raise SpecificationError(f"""
Problem is infeasible. The highest possible capacity
{highest_possible_capacity}, coming from the {p_facilities}
sites with the highest capacity, is smaller than the total demand {weights.sum()}.
"""
)
FacilityModelBuilder.add_facility_capacity_constraint(
p_median,
weights,
Expand Down

0 comments on commit d99315f

Please sign in to comment.