Pyomo/CPLEX: Остановить решение, записанное в файл ‘C:Users……tmp4ge49sy8.cplex.sol» для CPLEX API в Pyomo на Python

#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, я добавил больше кодов. Спасибо за уведомление.