问题描述

K-摇臂赌博机算法与实现_python

可以计算出,这种情况下:

  1. 如果每次都选期望价值最高的4号赌博机,可以获得的最高总价值为2800000。
  2. 如果每次都选期望价值最低的2号赌博机,可以获得的最低总价值为300000。
  3. 如果随机选取赌博机,可以获得的期望总价值为1540000。

探索与利用算法

原理

“仅探索”(exploration-only)算法就是将机会平均分配给每一个赌博机,随机挑选赌博机。

“仅利用”(exploitation-only)算法就是选取当前平均价值最高的那台赌博机。

但是由于尝试的次数有限,所以要在探索与利用之间进行权衡,这也是强化学习面临的一大问题:探索-利用窘境(Exploration-Exploitation dilemma)。

实现代码


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import random
import numpy as np

def R(k, P, V):
if random.random() < P[k]:
return V[k]
else:
return 0

def exploration_bandit(K, P, V, R, T):
r = 0
for t in range(T):
k = random.randint(0, K - 1)
v = R(k, P, V)
r += v
return r

def main():
K = 5
P = np.array([0.1, 0.9, 0.3, 0.2, 0.7])
V = np.array([5, 3, 1, 7, 4])
T = 1000000
print exploration_bandit(K, P, V, R, T)

if __name__ == '__main__':
main()


代码运行结果为:获得总价值1538893。这里只实现了仅探索方法,结果和预估的情况3还是比较接近的。


贪心算法

原理

K-摇臂赌博机算法与实现_python_02

实现代码

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import random
import numpy as np

def R(k, P, V):
if random.random() < P[k]:
return V[k]
else:
return 0

def eplison_bandit(K, P, V, R, T):
r = 0
Q = np.zeros(K)
count = np.zeros(K)
for t in range(T):
eplison = 1. / np.sqrt(t + 1)
if random.random() < eplison:
k = random.randint(0, K - 1)
else:
k = np.argmax(Q)
v = R(k, P, V)
r += v
Q[k] += (v - Q[k]) / (count[k] + 1)
count[k] += 1
return r

def main():
K = 5
P = np.array([0.1, 0.9, 0.3, 0.2, 0.7])
V = np.array([5, 3, 1, 7, 4])
T = 1000000
print eplison_bandit(K, P, V, R, T)

if __name__ == '__main__':
main()


K-摇臂赌博机算法与实现_Soft_03

K-摇臂赌博机算法与实现_python_04

实现代码


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import random
import numpy as np

def softmax(x):
return np.exp(x) / np.sum(np.exp(x))

def R(k, P, V):
if random.random() < P[k]:
return V[k]
else:
return 0

def eplison_bandit(K, P, V, R, T, tau=0.1):
r = 0
Q = np.zeros(K)
count = np.zeros(K)
for t in range(T):
p = softmax(Q / tau)
rand = random.random()
total = 0.0
for i in range(K):
total += p[i]
if total >= rand:
k = i
break
v = R(k, P, V)
r += v
Q[k] += (v - Q[k]) / (count[k] + 1)
count[k] += 1
return r

def main():
K = 5
P = np.array([0.1, 0.9, 0.3, 0.2, 0.7])
V = np.array([5, 3, 1, 7, 4])
T = 1000000
tau = 0.1
print eplison_bandit(K, P, V, R, T, tau)

if __name__ == '__main__':
main()

K-摇臂赌博机算法与实现_贪心算法_05