Возможно, вам будет проще следовать приведенному ниже коду, поскольку он не опирается на индексы и списки индексов.
Ключом к этому подходу является то, что вы можете использовать объект в качестве ключа словаря.
Таким образом, словарь переменных (здесь x) состоит из пар ключ-значение объекта Facility, LPVariable.
from pulp import *
class Facility():
def __init__(self, cost, profit, city):
self.cost = cost
self.profit = profit
self.city = city
def __str__(self):
return f"Facility(city={self.city}, profit={self.profit}, cost={self.cost})"
# PROBLEM DATA:
max_cost = 200
max_to_pick = 4
costs = [15, 25, 35, 40, 45, 55]
profits = [1.7, 2, 2.4, 3.2, 5.6, 6.2]
cities = ["NYC","SF","LA","SF","NYC","LA"]
facilities = [Facility(cost, profit, city) for cost, profit, city in
zip(costs, profits, cities)]
# DECLARE PROBLEM OBJECT:
prob = LpProblem("Mixed Problem", LpMaximize)
# VARIABLES
x = LpVariable.dicts('facility', facilities, cat="Binary")
# OBJECTIVE
prob += lpSum([facility.profit * x[facility] for facility in facilities])
# CONSTRAINTS
# number of facilities
prob += lpSum(x.values()) <= max_to_pick # Limit number to include
# maximum cost
prob += lpSum([facility.cost * x[facility] for facility in facilities]) <= max_cost
# no city more than once
# loop through unique city names
# add a constraint that the sum of matching facilities <= 1
unique_cities = set([facility.city for facility in facilities])
for city in unique_cities:
prob += lpSum([x[facility] for facility in facilities if facility.city == city]) <= 1
# solve the problem
prob.solve()
# identify the chosen facilities
# object_variable_d swaps keys and values
# so you can find the Facility object from the LpVariable
# all of the LpVariables are unique, so this should work
object_variable_d = {v: k for k, v in x.items()}
chosen_facilities = [object_variable_d[var]
for var in prob.variables()
if var.value() == 1]
# print out results
print(LpStatus[prob.status])
print(f'Profit = {value(prob.objective)}')
print(f'Cost = {sum([facility.cost for facility in chosen_facilities])}')
for facility in chosen_facilities:
print(facility)