Как реализовать ограничение спроса в Pyomo для этой проблемы ценовой эластичности? - PullRequest
0 голосов
/ 11 октября 2019

В настоящее время я пользователь SAS, переходящий на Python, и пытаюсь преобразовать программу, которая оптимизирует цену с учетом предыдущих коэффициентов спроса, цены и эластичности.

Однако я столкнулся с некоторыми проблемамиформулировка ограничения спроса.

В этой задаче я продаю яблоки и / или апельсины;тем не менее, я могу продать только 100 предметов вместе. Кроме того, цена для обоих предметов должна быть одинаковой, потому что мне разрешена только одна цена.

Ранее я продал 60 яблок по 5,00 долл. США и 30 апельсинов по 5,00 долл. США, а коэффициенты эластичности были -2,5 и -1,5;Тем не менее, я ранее продал 90 фруктов, но мне разрешено продавать 100 фруктов вместе. Так какая цена нужна для оптимизации дохода?

Я использую pyomocontrib-simplemodel из https://pyomocontrib -simplemodel.readthedocs.io / en / latest / и решатель, которым я являюсьиспользуется двоичный файл Ipopt из https://www.coin -or.org / download / binary / Ipopt / , и я выполнил пример проблем без проблем.

Я тестировал различные типовые проблемыи я могу их нормально запускать.

В SAS формула, которая используется для ограничения, изначально пришла отсюда: http://support.sas.com/documentation/cdl/en/ormpex/66104/HTML/default/viewer.htm#ormpex_ex21_sect009.htm

Я изменил код SAS для своих нуждчтобы выглядеть так (я проверил, что он работает в SAS):

   con Demand_con {i in PRODUCTS}:
      (Demand[i] - prev_demand[i]) / prev_demand[i]  
     = sum {PRODUCTS} elasticity[i] * (Price - prev_price[i]) / prev_price[i];

Однако я пытался воспроизвести это ограничение, используя пакет pyomocontrib-simplemodel в Python.

ВPyomo, моя попытка выглядит следующим образом:

m += ((demand[i]-prev_demand[i])/prev_demand[i] for i in products) == sum(elasticity[i] * ( price - prev_price[i]) / prev_price[i] for i in products)

Вот полный код:

# Price Elasticity
from pyomo.contrib.simplemodel import *

# Input Variables
products = {'Apples','Oranges'}
prev_demand = {'Apples':60, 'Oranges':30}
elasticity = {'Apples':-2.5, 'Oranges':-1.5}
prev_price = {'Apples':5.00, 'Oranges':5.00}
supply = 100

# Create empty model
m = SimpleModel(maximize=True)

# Variables
price = m.var('price', within=NonNegativeReals)
demand = m.var('demand', products, within=NonNegativeReals)

# Objective
m += sum(price*demand[i] for i in products)

# Demand Constraint - Broken
m += ((demand[i]-prev_demand[i])/prev_demand[i] for i in products) == sum(elasticity[i] * ( price - prev_price[i]) / prev_price[i] for i in products) 

#Supply Constraint
m += sum(demand[i] for i in products) <= supply

# Optimize
status = m.solve('ipopt')

# Print the status of the solved NLP
print("Objective = %f" % value(m.objective()))

Вот ошибка, которую я получаю при формулировании ограничения требования: AttributeError: 'генератор 'объект не имеет атрибута' is_expression_type '

Я также пытался этоСинтаксис s:

# Demand Constraint - Broken
for i in products:
    m += ((demand[i]-prev_demand[i])/prev_demand[i]) == sum(elasticity[i] * ( price - prev_price[i]) / prev_price[i])

Я получаю ошибку: TypeError: объект 'ProductExpression' не повторяется

Правильный ответ должен заключаться в том, что яблоки и апельсины должны стоить около $ 4,87.

1 Ответ

0 голосов
/ 11 октября 2019
    # Price Elasticity
    from pyomo.contrib.simplemodel import *

    # Input Variables
    products = {'Apples','Oranges'}
    prev_demand = {'Apples':60, 'Oranges':30}
    elasticity = {'Apples':-2.5, 'Oranges':-1.5}
    prev_price = {'Apples':5.00, 'Oranges':5.00}
    supply = 100

    # Create empty model
    m = SimpleModel(maximize=True)

    # Variables
    price = m.var('price', within=NonNegativeReals)
    demand = m.var('demand', products, within=NonNegativeReals)

    # Objective
    m += sum(price*demand[i] for i in products)


    # Demand Constraint - Broken
    for i in products:
        m += (demand[i]-prev_demand[i])/prev_demand[i] == sum(elasticity[i]  * ( price - prev_price[i])  / prev_price[i] for i in products)


    #Supply Constraint
    m += sum(demand[i] for i in products) <= supply

    # Optimize
    status = m.solve('ipopt')

    # Print the status of the solved NLP
    print("Status = %s" % status.solver.termination_condition)
    print("Objective = %f" % value(m.objective()))
    for i in products:
        print("%s = %f" % (demand[i], value(demand[i])))
    print("%s = %f" % (price, value(price)))

Это дало мне такой вывод:

Статус = Оптимальный, Цель = 486.111115, Спрос [Яблоки] = 66.666667, Спрос [Апельсины] = 33.333334, Цена = 4.86111

Достаточно близко, и я уверен, что коммерческие решатели любят XPRES, а не IPOPT, потенциально могут вывести другой ответ.

...