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

博客围绕赌博机选择问题展开,探讨如何在有限次数内使获得的硬币总价值最大。介绍了探索与利用算法、贪心算法和Softmax算法,给出各算法原理、实现代码及运行结果,指出贪心和Softmax算法谁更优取决于具体应用。

问题描述

K 个赌博机,每个赌博机有一定概率 P 吐出硬币,但是我们不知道这个概率是多少,每个赌博机吐出的硬币价值 V 也是不一样的,现在有 T 次机会选择赌博机,怎么选才能使得到的硬币总价值最大?

在下面的不同算法实现中,统一设定

\begin{array}{l}K = 5 \\ P = [0.1,0.9,0.3,0.2,0.7] \\ V = [5,3,1,7,4] \\ T = 1000000\end{array}

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

  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还是比较接近的。

\varepsilon 贪心算法

原理

这个方法原理就是每次以 \varepsilon 的概率来探索,即以均匀概率随机挑选一个摇臂。以 1-\varepsilon 的概率利用,即挑选当前平均价值最高的那个摇臂。

剩下的问题就是如何维护平均价值最高的摇臂了,对于做过算法竞赛的人来说,这都是小菜一碟。

{Q_n}(k) 记录第 k 个摇臂在第 n 次尝试之后的平均价值。那么最高效的算法就是根据 {Q_{n-1}}(k) 来直接推导出{Q_n}(k),如果第 n 次尝试获得的价值为 v_n ,那么 {Q_n}(k) 可以更新为:

{Q_n}(k) = \frac{1}{n}\left( {(n - 1) \times {Q_{n - 1}}(k) + {v_n}} \right)

实现代码

        #!/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()
      

\varepsilon 一般取值为较小值0.1或者0.01,当然也可以随着尝试次数增加而减小,如果尝试次数为 n ,那么设为 \varepsilon = 1/\sqrt n 即可。

代码运行结果为:获得总价值2795546。结果和情况1还是很接近的,说明这种方法基本能达到最优。

Softmax算法

原理

上面的方法是以 \varepsilon 的概率来进行探索利用抉择,而Softmax方法则是根据Boltzmann分布

P(k) = \frac{ { {e^{\frac{ {Q(k)}}{\tau }}}}}{ {\sum\limits_{i = 1}^k { {e^{\frac{ {Q(i)}}{\tau }}}} }}

来进行抉择。其中 \tau > 0 被称作“温度”, \tau 越小的话平均价值越高的摇臂被选取的概率越高, \tau 趋向于无穷大的话选取概率就很均匀了,这时候就变成了仅探索。

实现代码

        #!/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()
      

代码运行结果为: \tau=0.01 时,获得总价值1397795。 \tau=0.1 时,获得总价值2798372。当然随机性很大,每次运行结果都会不同。

\varepsilon 贪心算法和Softmax算法谁更好,取决于具体应用,这里也没有定论。

内容概要:该论文提出了一种低复杂度的离格DOA估计方法,结合了近似消息传递(AMP)和稀疏贝叶斯学习(SBL),并使用酉变换预处理和迭代细化提高精度。该方法首先通过酉变换降低计算复杂度,接着用AMP-SBL获取初步估计,最后通过迭代细化解决离格问题。相比现有方法,该方法不仅显著降低了计算复杂度,而且性能接近克拉美罗界。论文还提供了Python实现代码,并详细解释了每个步骤的原理和实现细节,包括信号生成、酉变换预处理、AMP-SBL算法、迭代细化以及完整的DOA估计流程。适用人群:具备一定信号处理和机器学习基础的研究人员和工程师,尤其是从事无线通信、雷达系统等领域工作的专业人士。使用场景及目标:①适用于均匀线性阵列(ULA)场景下的DOA估计;②用于提高DOA估计精度,特别是在存在离格误差的情况下;③在计算资源有限的情况下,提供一种高效的DOA估计方法;④为实际应用提供完整的端到端解决方案,包括代码实现和性能优化建议。其他说明:该方法通过酉变换预处理显著改善了传统AMP在DOA估计中的稳定性问题,结合迭代细化策略有效解决了离格误差问题。实验表明,在SNR=10dB、快拍数100的条件下,ULA场景的RMSE可达0.1°量级,计算耗时较传统SBL减少约60%。实际部署时可结合GPU加速,将单帧处理时间控制在5ms以内。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法码上来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值