#python #mathematical-optimization #cplex #pyomo
Вопрос:
Для настроек по умолчанию с API CPLEX в pyomo на python после каждого запуска на диск записывается файл решения (например, «C:Users…Temptmp4ge49sy8.cplex.sol»). Мой вопрос в том, как настроить параметр CPLEX в pyomo на python, чтобы остановить это.
Причина, по которой я хочу это сделать, заключается в том, что мне нужно многократно запускать модель (например, 1000 раз), и для каждого запуска я записываю только целевое значение. Поэтому запись файла sol за один запуск для меня бесполезна и отнимает много времени.
Вот коды для оптимизационной модели, которую я разработал:
class Farmers_Model(AbstractModel):
def __init__(self):
AbstractModel.__init__(self)
#set
self.FIELDS = pyo.Set()
self.SCENARIOS = pyo.Set()
self.PRODS = pyo.Set()
self.SUSTAINABILITY = pyo.Set()
#parameters
self._area = pyo.Param(self.FIELDS, domain = pyo.NonNegativeReals) #acre
self._unit_cost_scenario = pyo.Param(self.SCENARIOS, domain = pyo.NonNegativeReals) #$/acre
self._inconvience_cost = pyo.Param(domain = pyo.NonNegativeReals) #$/acre
self._yield = pyo.Param(self.FIELDS, self.SCENARIOS, self.PRODS, domain = pyo.NonNegativeReals) #tons
self._price_for_biofuel = pyo.Param(self.PRODS, domain = pyo.NonNegativeReals) #$/tons
self._price_for_other = pyo.Param(self.PRODS, domain = pyo.NonNegativeReals) #$/tons
self._conversion_rate = pyo.Param(self.PRODS, domain = pyo.NonNegativeReals) #gallons/ton
self._biofuel_demand = pyo.Param(domain = pyo.NonNegativeReals, mutable = True) #gallons
self._sustainability = pyo.Param(self.FIELDS, self.SCENARIOS, self.SUSTAINABILITY, domain = pyo.Reals)
self._sustainability_cost = pyo.Param(self.SUSTAINABILITY, domain = pyo.Reals, mutable = True) #$/tons additional subsidy for product for biofuel production
#decisions
self.Scenario_Implement = pyo.Var(self.FIELDS, self.SCENARIOS, bounds = (0, 1), domain = pyo.NonNegativeReals) #if scenario is chosen
self.Production_for_biofuel = pyo.Var(self.FIELDS, self.PRODS, domain = pyo.NonNegativeReals)
self.Production_for_other = pyo.Var(self.FIELDS, self.PRODS, domain = pyo.NonNegativeReals)
def obj_expression(m):
return sum(sum(m._price_for_biofuel[k] * m.Production_for_biofuel[i,k] m._price_for_other[k] * m.Production_for_other[i,k] for k in m.PRODS) -
sum(m._unit_cost_scenario[s] * m._area[i] * m.Scenario_Implement[i,s] for s in m.SCENARIOS) for i in m.FIELDS) sum(sum(sum(m._sustainability_cost[n] * m._sustainability[i,s,n] for n in m.SUSTAINABILITY) * m._area[i] * m.Scenario_Implement[i,s] for s in m.SCENARIOS) for i in m.FIELDS)
self.OBJ = pyo.Objective(rule = obj_expression, sense = pyo.maximize)
@self.Constraint(self.FIELDS)
def constraint_non_negative_profit(m, I):
return sum(m._price_for_biofuel[k] * m.Production_for_biofuel[i,k]
m._price_for_other[k] * m.Production_for_other[i,k] for k in m.PRODS) - sum(m._unit_cost_scenario[s] * m._area[i] * m.Scenario_Implement[i,s] for s in m.SCENARIOS) >= 0
@self.Constraint(self.FIELDS)
def constraint_select_scenario(m, I):
return sum(m.Scenario_Implement[i, s] for s in m.SCENARIOS) == 1
@self.Constraint(self.FIELDS, self.PRODS)
def constraint_split_production(m, i, k):
return m.Production_for_biofuel[i, k] m.Production_for_other[i, k] == sum (m._yield[i, s, k] * m.Scenario_Implement[i, s] for s in m.SCENARIOS)
@self.Constraint()
def constraint_total_fuel_demand(m):
return sum(sum(m._conversion_rate[k] * m.Production_for_biofuel[i, k] for k in m.PRODS) for i in m.FIELDS) == m._biofuel_demand
В классе Farmers_Model у меня есть несколько функций ниже:
генерирующий экземпляр:
def generate_instance(self, data_file):
data = pyo.DataPortal()
data.load(filename=data_file, model=self)
instance = self.create_instance(data)
return instance
решить проблему с экземпляром:
def solve_instance(self, solver, instance):
opt = pyo.SolverFactory(solver)
results = opt.solve(instance, tee=True)
return results
и получите объективную ценность:
def get_OBJ_value(self, instance):
return pyo.value(instance.OBJ)
В главном файле для каждого запуска (для каждого сегмента) Я просто делаю следующее:
for segment in segments:
instance = model.generate_instance("inputs/data_" str(segment) ".json")
results = model.solve_instance("cplex", instance)
print(model.get_OBJ_value(instance))
Для каждой итерации первая строка предназначена для создания экземпляра из файла данных json, вторая строка предназначена для запуска модели, а последняя строка является примером для печати целевого значения. Проблема заключается во второй строке, после каждого запуска она пишет файл sol, что занимает заметное время, и я хотел бы предотвратить это.
Кстати, я новичок в Pyomo. Несмотря на то, что вся программа работоспособна, если кто-нибудь заметит плохой шаблон кодирования, пожалуйста, дайте мне знать. Я очень ценю ваши комментарии!
Комментарии:
1. Вы должны показать часть соответствующего кода, который вы используете в данный момент.
2. Сам CPLEX не пишет файл решения, если ему не будет сказано сделать это с помощью команды или через API. Должно быть, что-то в пьомо делает это. Проверьте документацию pyomo, настройки и т.д.
3. @AKX, я добавил больше кодов. Спасибо за уведомление.