K-摇臂赌博机

目录

 

问题描述

贪心算法

Softmax算法


问题描述

有K个摇臂赌博机,赌徒在投入一个硬币后,从K个摇臂机中随机选择一个按下,每个摇臂机以某概率吐出一定数量的硬币,这个概率赌徒并不知道,赌徒通过多次尝试,获得最大的利益。

贪心算法

1.每次尝试以概率eplison进行探索,即以均匀概率选取一个摇臂机,以1-eplison选取平均奖励最高的摇臂机。

2.再以奖励策略reward输出摇臂机的奖励,用了两个摇臂机,

(1)prob={1:0.4,2:0.2},第一个摇臂机摇出硬币的概率为0.4,摇不出硬币的概率为0.6,第二个摇臂机摇出硬币的概率为0.2,摇不出硬币的概率为0.8

(2)R={1:1,2:1},第一个摇臂机摇出硬币奖励为1,第二个摇出硬币奖励为1

选择出一个摇臂机后,如果选取了第一个摇臂机,取一个随机数random,如果该随机数小于0.4,那么获得奖励,返回奖励R[k]

,否则奖励为0,返回0

3.更新获得的总奖励 r,r+=v,y.append(r/T)记录每次总平均奖励,用以后面画图

4.更新每个摇臂机的平均奖励

Q[k]=\frac{Q[k]*count[k]+v}{count[k]+1}

count[k]为上一次摇臂机K的选中次数,count[k]+1为摇臂机K的本次选中次数,v为本次奖励

5.更新摇臂机K的选中次数,次数加1,count[k]=count[k]+1

Softmax算法

与贪心算法不同的是:当摇臂机的平均奖赏相差不大时,那选择摇臂机的概率相差不大,如果平均奖赏相差大,那么平均奖赏概率大的摇臂机被选中的概率也大,softmax算法的摇臂机概率分布基于Bolzmann分布。

每个摇臂机的选中概率公式为P[k]=\frac{e^{\frac{Q[k]}{\tau }}}{\sum_{k}^{i=1} e^{\frac{Q[i]}{\tau }}},除此之外,两个算法无甚差别。

# -*- coding: UTF-8 -*-
from numpy import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
e=2.17
#奖励函数
def reward(k,prob,R):
    if random.random()<prob[k]:
        return R[k]
    else: return 0
#贪心算法
def greedyAlgorithm(Knum,R,prob,T,eplison,count,Q):
    r=0
    y=[]
    for i in range(T):
        randValue=random.random()
        if randValue<eplison:
            k=random.choice(Knum)
        else:
            k=max(Q,key=Q.get)
        #选择的摇臂机以概率prob[k]获得奖励
        v=reward(k,prob,R)
        r+=v
        y.append((r-v)/T)
        #摇臂k的平均奖赏
        #Q[k]+=(v-Q[k])/(count[k]+1)等同于下式
        Q[k]=(Q[k]*count[k]+v)/(count[k]+1)
        count[k]=count[k]+1
        if i>=100:#当尝试次数很大时,摇臂的奖赏可以很好近似出来,再无需探索,那么可以置eplison为1/根号下i
            eplison=1.0/pow(i,.5)
    print("the total reward is: ",r)
    print("the average reward is: ",r/T)
    print("the times of each machine are :",count)
    print("the even reward of each machine is :",Q)
    return y


def Softmax(T,Q,eplison,count,R,probOfReward):
    r=0
    y=[]
    probK=dict(zip(list(range(1,3)),[0]*2))
    for i in range(T):
        probKTotal=0
        chanceOfRandom=random.random()
        sum=(pow(e,Q[1]/eplison)+pow(e,Q[2]/eplison))
        for n in Q:
            operated=0
            t=pow(e,Q[n]/eplison)
            probK[n]=t/sum
            probKTotal+=probK[n]
            if chanceOfRandom<probKTotal and operated==0:
                kk=n
                operated=1
        v=reward(kk,probOfReward,R)
  
        r+=v
        y.append(r/T)
        Q[kk]=(Q[kk]*count[kk]+v)/(count[kk]+1)
        count[kk]=1+count[kk]
    print("the total reward is: ",r)
    print("the average reward is: ",r/T)
    print("the times of each machine are :",count)
    print("the even reward of each machine is :",Q)
    return y

if __name__=="__main__":
#5个摇臂
    Knum=[i+1 for i in range(2)]
#每个摇臂对应的奖赏
    R={1:1,2:1}
#每个摇臂摇到奖赏的概率
    prob={1:0.4,2:0.2}
#摇臂次数
    T=3000
#探索概率
    eplison=0.01
#每个摇臂奖赏为0
    count=dict(zip(list(range(1,3)),[0]*2))
#每个摇臂机的平均奖励
    Q=dict(zip(list(range(1,3)),[0]*2))
    #zip对应下标打包成元组的形式,而dict为字典,对应的元组成一个字典的一个元素
    print("greedy:")
    GreedyEvenW=greedyAlgorithm(Knum,R,prob,T,eplison,count,Q)
    x=range(1,T+1)
    y1=GreedyEvenW
    plt.plot(x,y1,color='red',label='$greedy$',linewidth=0.8)
    plt.title('rate')
    plt.xlabel('x/times')
    plt.ylabel('y/even reward')
#Softmax
    print("softmax:")
    softmaxEven=Softmax(T,Q,eplison,count,R,prob)
    y2=softmaxEven
    plt.plot(x,y2,color='black',label='$Softmax$',linewidth=0.8)
    plt.legend(('greedy','Softmax'))
    plt.show()

结果如下:

贪心算法和softmax算法的总的平均奖励

如果要看变化率的话,需要求导,这只是5000次的平均奖励变化,多次调试后,贪心算法的平均奖励保持在0.4,而softmax的平均奖励保持在0.2,在最初会有激增。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值