<p>很抱歉,我来不及回答这个问题,但我认为公认的答案并没有完全解决问题,而且还没有正确地解决问题。注意在局部极小化中,求解接近名义价格并不能给出最佳解决方案。在</p>
<p>让我们首先构建一个<code>hotel</code>类:</p>
<pre><code>"""
This file is 'hotel.py'
"""
import math
class hotel(object):
def __init__(self, rooms, price_ave, price_elastic):
self.rooms = rooms
self.price_ave = price_ave
self.price_elastic = price_elastic
def profit(self, P):
# assert len(P) == len(self.rooms)
return sum(j * self._reserved(P, i) for i,j in enumerate(P))
def remaining(self, P): # >= 0
C = self.rooms
# assert len(P) == C
return [C[i] - self._reserved(P, i) for i,j in enumerate(P)]
def _reserved(self, P, day):
max_days = len(self.rooms)
As = range(0, day)
return sum(self._allocated(P, a, L) for a in As
for L in range(day-a+1, max_days+1))
def _allocated(self, P, a, L):
P_nom = self.price_ave
e = self.price_elastic
return math.ceil(self._demand(a, L)*(sum(P[a:a+L])/(P_nom*L))**e)
def _demand(self, a,L): #XXX: fictional non-constant demand function
return abs(1-a)/L + 2*(a**2)/L**2
</code></pre>
<p>以下是一种使用<code>mystic</code>解决问题的方法:</p>
^{pr2}$
<p>结果:</p>
<pre><code>>$ python local.py
Generation 0 has Chi-Squared: -4930.000000
Generation 100 has Chi-Squared: -22353.444547
Generation 200 has Chi-Squared: -22410.402420
Generation 300 has Chi-Squared: -22411.780268
Generation 400 has Chi-Squared: -22413.908944
Generation 500 has Chi-Squared: -22477.869093
Generation 600 has Chi-Squared: -22480.144244
Generation 700 has Chi-Squared: -22480.280379
Generation 800 has Chi-Squared: -22485.563188
Generation 900 has Chi-Squared: -22485.564265
Generation 1000 has Chi-Squared: -22489.341602
Generation 1100 has Chi-Squared: -22489.345912
Generation 1200 has Chi-Squared: -22489.351219
Generation 1300 has Chi-Squared: -22491.994305
Generation 1400 has Chi-Squared: -22491.994518
Generation 1500 has Chi-Squared: -22492.061127
Generation 1600 has Chi-Squared: -22492.573672
Generation 1700 has Chi-Squared: -22492.573690
Generation 1800 has Chi-Squared: -22492.622064
Generation 1900 has Chi-Squared: -22492.622230
Optimization terminated successfully.
Current function value: -22492.622230
Iterations: 1926
Function evaluations: 3346
STOP("CandidateRelativeTolerance with {'xtol': 1e-08, 'ftol': 1e-08}")
[1.15, 20.42, 20.7, 248.1, 220.56, 41.4, 160.09]
</code></pre>
<p>这里再次使用全局优化器:</p>
<pre><code>"""
This file is 'global.py'
"""
n_days = 7
n_rooms = 50
P_nom = 85
P_bounds = 0,None
P_elastic = 2
import hotel
h = hotel.hotel([n_rooms]*n_days, P_nom, P_elastic)
def objective(price, hotel):
return -hotel.profit(price)
def constraint(price, hotel): # <= 0
return -min(hotel.remaining(price))
bounds = [P_bounds]*n_days
guess = [P_nom]*n_days
import mystic as my
@my.penalty.quadratic_inequality(constraint, kwds=dict(hotel=h))
def penalty(x):
return 0.0
# try again using a global optimizer
solver = my.solvers.diffev
mon = my.monitors.VerboseMonitor(100)
kwds = dict(disp=True, full_output=True, itermon=mon, npop=40,
args=(h,), gtol=250, ftol=1e-8, maxfun=30000, maxiter=2000)
result = solver(objective, bounds, bounds=bounds, penalty=penalty, **kwds)
print([round(i,2) for i in result[0]])
</code></pre>
<p>结果:</p>
<pre><code>>$ python global.py
Generation 0 has Chi-Squared: 3684702.124765
Generation 100 has Chi-Squared: -36493.709890
Generation 200 has Chi-Squared: -36650.498677
Generation 300 has Chi-Squared: -36651.722841
Generation 400 has Chi-Squared: -36651.733274
Generation 500 has Chi-Squared: -36651.733322
Generation 600 has Chi-Squared: -36651.733361
Generation 700 has Chi-Squared: -36651.733361
Generation 800 has Chi-Squared: -36651.733361
STOP("ChangeOverGeneration with {'tolerance': 1e-08, 'generations': 250}")
Optimization terminated successfully.
Current function value: -36651.733361
Iterations: 896
Function evaluations: 24237
[861.07, 893.88, 398.68, 471.4, 9.44, 0.0, 244.67]
</code></pre>
<p>我认为为了使定价更合理,我应该将<code>P_bounds</code>的值改为更合理的值。在</p>