例4.2:
杰克管理一个全国性汽车出租公司的两个地点。每天一些顾客到这两个地点租车。如果有车可租,杰克就将车租出并从公司得到10美元的回扣。如果这个地点没车,杰克就失去了这笔生意。还回的车第二天就可以出租。为了使需要车的地点有车可租,每天晚上,杰克可以在两个地点间移动车辆,移动每辆车的费用是2美元。我们假设每个地点的车的需求量和归还量都是泊松分布变量。假设租车的期望值是3和4,还车的期望值是3和2。
为了简化问题,我们假设每个地点的车不多于20辆(多于的车被还回公司,在此问题中消失了)并且一晚上最多移动5辆车。折扣率为0.9,并描述为一个有限MDP问题,时刻按天计算,状态是每天结束时两个地点的车辆数,动作是晚上在两个地点间移动的车辆数。 ?
一,求动力(dynamics)P(s',r|s,a)
首先困扰我的是动作发生时间,顺序是 移车-借车-还车,还是 借车-还车-移车。顺序不同,车辆数不同。 反复读题后选择了“ 移车-借车-还车” 的顺序。
第二个困扰我的是,如何统计状态转移概率?参考大佬代码后明白,分为以下几步
??????? 先由泊松分布公式,计算出A,B两地借还车数量的概率
def poisson_calculator(Lambda=3):
result = {}
for i in range(0, 21):
result[i] = max(np.finfo(float).eps, abs((np.power(Lambda, i) / (np.math.factorial(i))) * np.exp(-Lambda)))#防止result中出现0
return result
customer_A = poisson_calculator(3)
customer_B = poisson_calculator(4)
return_A = poisson_calculator(3)
return_B = poisson_calculator(2)
?????? 假设两地借还车相互独立,即可计算出所有借还车情况的概率p(customer_A,return_A,customer_B,return_B)
??????? 则p(s',r|s,a)可由模拟实际情况求得。
??????? 从状态(0,0)开始,遍历所有可能情况,累加所有符合P(s',r|(0,0),a) 的概率并命名储存备用
for state_value_A in range(21): # car left at the end of the day at A
print("State " + str(state_value_A))
for state_value_B in range(21): # car left at the end of the day at B
P = {}#字典类型的P
for action in range(-5, 6): # action range is from -5 to 5
temp = {}
#problem: action=-5 A=1 B=10
#action要合理,不合理的不考虑
if action <= state_value_A and -action <= state_value_B and action + state_value_B <= 20 and -action + state_value_A <= 20:
for customer_A in range(21): # total customers come at the end of the day at A
for customer_B in range(21): # total customers come at the end of the day at B
for returned_car_A in range(21): # total cars returned at the end of the day at A
for returned_car_B in range(21): # total cars returned at the end of the day at B
#value_a_changed 指当天用户还完车时所余车辆与晚上移车,再到第二天还车 正确
#情况一:value_A_Changed=20 当结束时车辆大于20
#情况二:value_A_Changed=state_value_A -customer_A+ returned_car_A - action 当用户需求 < state_value_A- action
#情况三value_A_Changed= returned_car_A 当用户需求 > state_value_A- action
value_A_Changed = min(20, state_value_A - min(customer_A,
state_value_A- action) + returned_car_A - action)
value_B_Changed = min(20, state_value_B - min(customer_B,
state_value_B+ action) + returned_car_B + action)
#state_value_A 是上一天运车前的车数,state_value_A - action就是下一天所拥有的车数
reward = 10 * min(customer_A, state_value_A - action ) + \
10 * min(customer_B, state_value_B + action) - \
abs(action) * 2 #动作费用 the reason for action here is the current action change the next stroes
二,策略评估
代码参考https://github.com/LyWangPX/Reinforcement-Learning-2nd-Edition-by-Sutton-Exercise-Solutions
|