我正在尝试构建一个关于Dynamic room pricing model for hotel revenue management systems的白皮书的实现。如果将来此链接失效,我将在此处的相关部分粘贴:
到目前为止,我目前的实现是相当失败的,因为我真的不完全理解如何求解非线性最大化方程。在
# magical lookup table that returns demand based on those inputs
# this will eventually be a db lookup against past years rental activity and not hardcoded to a specific value
def demand(dateFirstNight, duration):
return 1
# magical function that fetches the price we have allocated for a room on this date to existing customers
# this should be a db lookup against previous stays, and not hardcoded to a specific value
def getPrice(date):
return 75
# Typical room base price
# Defined as: Nominal price of the hotel (usually the average historical price)
nominalPrice = 89
# from the white paper, but perhaps needs to be adjusted in the future using the methods they explain
priceElasticity = 2
# this is an adjustable constant it depends how far forward we want to look into the future when optimizing the prices
# likely this will effect how long this will take to run, so it will be a balancing game with regards to accuracy vs runtime
numberOfDays = 30
def roomsAlocated(dateFirstNight, duration)
roomPriceSum = 0.0
for date in range(dateFirstNight, dateFirstNight+duration-1):
roomPriceSum += getPrice(date)
return demand(dateFirstNight, duration) * (roomPriceSum/(nominalPrice*duration))**priceElasticity
def roomsReserved(date):
# find all stays that contain this date, this
def maximizeRevenue(dateFirstNight):
# we are inverting the price sum which is to be maximized because mystic only does minimization
# and when you minimize the inverse you are maximizing!
return (sum([getPrice(date)*roomsReserved(date) for date in range(dateFirstNight, dateFirstNight+numberOfDays)]))**-1
def constraint(x): # Ol - totalNumberOfRoomsInHotel <= 0
return roomsReserved(date) - totalNumberOfRoomsInHotel
from mystic.penalty import quadratic_inequality
@quadratic_inequality(constraint, k=1e4)
def penalty(x):
return 0.0
from mystic.solvers import diffev2
from mystic.monitors import VerboseMonitor
mon = VerboseMonitor(10)
bounds = [0,1e4]*numberOfDays
result = diffev2(maximizeRevenue, x0=bounds, penalty=penalty, npop=10, gtol=200, disp=False, full_output=True, itermon=mon, maxiter=M*N*100)
熟悉神秘主义的人能给我一些建议吗?在
很抱歉,我来不及回答这个问题,但我认为公认的答案并没有完全解决问题,而且还没有正确地解决问题。注意在局部极小化中,求解接近名义价格并不能给出最佳解决方案。在
让我们首先构建一个
hotel
类:以下是一种使用
^{pr2}$mystic
解决问题的方法:结果:
这里再次使用全局优化器:
结果:
我认为为了使定价更合理,我应该将
P_bounds
的值改为更合理的值。在虽然您要求使用库
mystic
,但在开始非线性优化时,您可能不需要这种细粒度的控制。模块scipy
应该足够了。以下是一个或多或少完整的解决方案,纠正了我认为原始白皮书中有关定价界限的错误:有几点值得一提:
与原始白皮书中引用的最大化相比,目标函数有一个附加的减号,用于scipy的
minimize()
例程。这将导致result.fun
为负数,而不是显示总收入。这个公式似乎对参数有点敏感。最小化是正确的(至少,当它说它正确地执行check
result.success
)时是正确的,但是如果输入值与实际值相差太远,那么您可能会发现价格远高于预期。您可能还希望使用比下面示例中更多的天数。你的白皮书似乎引发了周期性的影响。我不是白皮书的命名方案的真正粉丝,因为它与可读代码有关。我改变了一些东西,但是有些东西确实很糟糕,应该被替换,比如小写字母l,它很容易被数字1混淆。
我确实设定了界限,所以价格是正的而不是负的。根据您的领域专业知识,您应该验证这是正确的决定。
你可能更喜欢比我指定的更严格的公差。这在某种程度上取决于您希望运行时是什么。请随意使用
tol
参数。另外,对于更严格的公差,您可能会发现options
参数中的'maxiter'
必须增加,才能使minimize()
正确收敛。我很确定
total_rooms
应该是酒店中尚未预订的房间数,因为白皮书的索引是字母l,而不是像原来代码中那样的常量。为了测试的目的,我将它设置为一个常量列表。方法必须是“SLSQP”,以处理价格和房间数量的界限。注意不要换这个。
如何计算
O_l()
存在着巨大的低效。如果运行时是个问题,那么我要做的第一步是找出如何缓存/记忆对X()
的调用。所有这些实际上只是第一次通过,概念证明。它应该是合理的无缺陷和正确的,但是它几乎是直接从白皮书中提取出来的,并且可以进行一些重新分解。任何人,玩得开心,并随时评论/下午/等任何进一步的问题。在
相关问题 更多 >
编程相关推荐