一个Q_learning代码的简明教程实现

Flappy Bird

在浏览机器学习相关内容的时候,看到有人通过机器学习玩转一个曾经很火的手机游戏Flappy bird。 其使用的算法是Q_learning。
一个Q_learning代码的简明教程实现_第1张图片

算法如下:

状态矢量空间
在这里一共设计了3个参数:1,小鸟与低管道的垂直距离;2,小鸟与下一个管道出口的水平距离;3,小鸟是否死亡。
行为
对每个状态,我设计了两个可能存在的行为:点击或者是什么都不做。
奖励
奖励完全依赖于“Life”参数,仍然存活则+1,失败则-1000。
学习循环
数组Q初始化为0,同时也总采取最佳操作,这些操作将最大化我的预期奖励。
第一步,观察Flappy Bird所处的状态,并执行可以最大化预期奖励的操作。让游戏引擎执行“tick”操作,随之Flappy Bird进入下一个状态s’。
第二步,观察s’及状态下的奖励,+1则表示小鸟还活着。
第三步,通过Q Learning规则来修改Q数组。Alpha的值被设置成0.7,因为我们需要一个确定的状态,也让学习的可能最大化;同时,Y和lambda都被设置成了1。
第四步,将当前状态设置为s’并重新开始。

原文链接:Flappy Bird hack using Reinforcement Learning
译文链接:亚特兰大极客使用机器学习玩转Flappy Bird

对其所利用的Q_learning进行资料搜索,找到一个简明的教程对Q_Learning进行了介绍。

一个简明教程

具体的教程见链接A Painless Q-learning Tutorial
其解决的问题:利用无监督训练让代理找到走出房间的路线。
一个Q_learning代码的简明教程实现_第2张图片

C++代码

#include 
#include
#include
#include 
using namespace std;

#define ROW    6
#define COLUMN 6
#define STATE_NUM 6
#define ACTION_NUM 6
#define alph 0.8
float a[100][100];
float b[100][100];
/*R(s,a),目标函数*/
float R[100][100]={{-1,-1,-1,-1,0,-1},{-1,-1,-1,0,-1,100},{-1,-1,-1,0,-1,-1},
{-1,0,0,-1,0,-1},{0,-1,-1,0,-1,100},{-1,0,-1,-1,0,100}};
/*Q(s,a),学习函数,初始化为0*/
float Q[100][100];
/*初始化的顺序*/
int initial_can_go[10];//存储可以做的action
int a_can_go[10];//存储可以做的action
int NUM=0;

/*R*/
void get_go_value(float a[100][100],int can_go[10],int state)
{
    NUM=0;
    for(int i=0;iif(a[state][i]>=0)
        {
            can_go[NUM]=i;
            NUM++;
        }
    }
}
float get_max_value(float Q[100][100],int state)
{
    float tempmax=0;
    for(int i=0;iif((R[state][i]>=0)&&(Q[state][i]>tempmax))
            tempmax=Q[state][i];
    }
    return tempmax;
}
int get_max_tab(float Q[100][100],int state)
{
    float tempmax=0;
    int temptab=0;
    for(int i=0;iif((Q[state][i]>tempmax))
        {
            tempmax=Q[state][i];
            temptab=i;
        }
    }
    return temptab;
}
/*initial:初始状态*/
int learning_G(int initial, float R[100][100],float Q[100][100],int flag)
{
    float Q_before,Q_new;
    int a;   //是端点
    float a_2;//是回报值,非端点
    memset(initial_can_go,0,10*sizeof(int));
    get_go_value(R,initial_can_go,initial);//返回了端点和num
    a=initial_can_go[rand()%NUM];
    a_2=get_max_value(Q,a);
    /*initial_can_go数组存放了可以进行的动作*/
    /*a为随机进行的当前action*/
    /*a_2为该action下的最大反馈*/
    /*被更新的是Q(initial,a)*/
    Q_before=Q[initial][a];
    Q[initial][a]=R[initial][a]+alph*a_2;
    Q_new=Q[initial][a];

    if(Q_before==Q_new) flag++;
    else flag=0;
    if(flag==50)     return 0;
    if(Q_new == 100) initial=rand()%STATE_NUM;
    else       initial=a;
    cout<<"initial="<int main()
{

    cout<<"****************R矩阵****************"<for(int i=0; ifor(int j=0; jcout <"\t";
        }
        cout<cout<<"**************Q矩阵*******************"<for(int i=0; ifor(int j=0; jcout <"\t";
        }
        cout<int flag=0;
    int initial=1;
    cout<<"initial="<cout<<"**************shoulianjuzhen**********"<for(int i=0; ifor(int j=0; jcout <"\t";
        }
        cout<int position;
    while(1){
        cout<<"please input<<";
        cin>>position;
        cout<"->";
        while(1)
        {
            int j=get_max_tab(Q,position);
            cout<"->";
            if(R[position][j]==100)
            {
                cout<<"out"<break;
            }
            else
                position=j;
        }
    }
    return 0;
}

运行后得到的收敛矩阵

一个Q_learning代码的简明教程实现_第3张图片

附:

抱歉,写的代码和注释有点乱,两个月前写的代码,现在自己都快忘了。下次有空了再整理。

你可能感兴趣的:(机器学习,机器学习)