首页 > 编程语言 >强化学习——价值迭代算法 悬崖漫步为例 C++

强化学习——价值迭代算法 悬崖漫步为例 C++

时间:2022-09-07 10:11:43浏览次数:76  
标签:cout 迭代 为例 int double C++ next State pair

#include<bits/stdc++.h>
using namespace std;
#define N 100
#define cliff cliff_map
int row,col;
struct State{
    int next_i,next_j,flag;
    double reward;
    State(){
        next_i=next_j=flag=0;
        reward=0;
    }
};
double pi[N][N][4];
State P[N][N][4];
int cliff_map[N][N];
int direction[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
double theta,gamma;
double V[N][N],V_new[N][N];
pair<int,int> change_position(pair<int,int> a,int oper){
    return make_pair(a.first+direction[oper][0],a.second+direction[oper][1]);
}
void whether_valid(int &i,int &j){
    i=min(row-1,max(0,i));
    j=min(col-1,max(0,j));
}
void input_value(State &x,int i,int j,double re,int f){
    x.flag=f;
    x.next_i=i;
    x.next_j=j;
    x.reward=re;
}
void initialization_P(){
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            if(cliff_map[i][j]==0||cliff_map[i][j]==2){
                for(int k=0;k<4;k++)input_value(P[i][j][k],i,j,0,1);
                continue;
            }
            for(int k=0;k<4;k++){
                pair<int,int> a=change_position(make_pair(i,j),k);            
                int new_i=a.first,new_j=a.second;
            //    cout<<"i="<<i<<"  j="<<j<<"  k="<<k<<'\n';
                whether_valid(new_i,new_j);
            //    cout<<new_i<<' '<<new_j<<'\n';
                if(cliff[new_i][new_j]==1)
                    input_value(P[i][j][k],new_i,new_j,-1,0);
                else if(cliff[new_i][new_j]==0)
                    input_value(P[i][j][k],new_i,new_j,-100,1);
                else
                    input_value(P[i][j][k],new_i,new_j,-1,1);
            }
        }
    }
}
void policy_initialization(){
    for(int i=0;i<row;i++)
        for(int j=0;j<col;j++){
            for(int k=0;k<4;k++)
                pi[i][j][k]=0;
            V[i][j]=0;
        }
}
void clear_vnew(){
    for(int i=0;i<row;i++)
        for(int j=0;j<col;j++)
            V_new[i][j]=0;
}
void copy(){
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            V[i][j]=V_new[i][j];
            cout<<V[i][j]<<' ';
        }
        cout<<'\n';
    }
    cout<<'\n';
}
void policy_evaluation(){
    policy_initialization();
    int cnt=0;
    while(1){
        double max_diff=-9999999999;
        clear_vnew();
        for(int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                double MAX_QSA=-999999999;
                for(int k=0;k<4;k++){
                    MAX_QSA=max(MAX_QSA,P[i][j][k].reward+\
                    gamma*V[P[i][j][k].next_i][P[i][j][k].next_j]*\
                    (1-P[i][j][k].flag));
                }
                V_new[i][j]=MAX_QSA;
                max_diff=max(max_diff,fabs(V_new[i][j]-V[i][j]));
            }
        }
        copy();
    //    cout<<max_diff<<' ';
        if(max_diff<theta)break;
        cnt++;
    }
    cout<<"\n经过"<<cnt<<"次迭代处理"<<'\n';
}
void get_policy(){
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            double MAX_QSA=-9999999;
            for(int k=0;k<4;k++){
                MAX_QSA=max(MAX_QSA,P[i][j][k].reward+\
                gamma*V[P[i][j][k].next_i][P[i][j][k].next_j]*\
                (1-P[i][j][k].flag));
            }
            int cntq=0;
            for(int k=0;k<4;k++){
                double QSA=P[i][j][k].reward+\
                gamma*V[P[i][j][k].next_i][P[i][j][k].next_j]*\
                (1-P[i][j][k].flag);
                if(QSA==MAX_QSA)cntq++;
            }
            for(int k=0;k<4;k++){
                double QSA=P[i][j][k].reward+\
                gamma*V[P[i][j][k].next_i][P[i][j][k].next_j]*\
                (1-P[i][j][k].flag);
                if(QSA==MAX_QSA)cntq++;
            }
            for(int k=0;k<4;k++){
                double QSA=P[i][j][k].reward+\
                gamma*V[P[i][j][k].next_i][P[i][j][k].next_j]*\
                (1-P[i][j][k].flag);
                if(QSA==MAX_QSA)pi[i][j][k]=1.0/cntq;
            }
        }
    }
}
void print_policy(){
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            if(cliff_map[i][j]==0){
                cout<<"**** ";
                continue;
            }
            if(cliff_map[i][j]==2){
                cout<<"eeee ";
                continue;
            }
            if(pi[i][j][1])cout<<'^';else cout<<'o'; 
            if(pi[i][j][0])cout<<'v';else cout<<'o';
            if(pi[i][j][3])cout<<'<';else cout<<'o';
            if(pi[i][j][2])cout<<'>';else cout<<'o';
            cout<<' ';
        }
        cout<<endl;
    }
}
int main(){
    cout<<"row=";
    cin>>row;
    cout<<"col=";
    cin>>col;
    cout<<"map\n";
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            cin>>cliff_map[i][j];
        }
    }
    theta=0.0001;gamma=0.9;
    initialization_P();
//    for(int i=0;i<row;i++){
//        for(int j=0;j<col;j++){
//            for(int k=0;k<4;k++)
//                cout<<P[i][j][k].reward;
//            cout<<" ";            
//        }
//        cout<<'\n';
//    }
    policy_evaluation();
    get_policy();
    print_policy();
}
/*
6
6
1 1 1 1 1 1
1 1 0 1 2 1
1 0 1 1 1 0
1 1 0 1 1 1
1 0 0 0 2 1
1 1 1 1 0 0
*/

 

标签:cout,迭代,为例,int,double,C++,next,State,pair
From: https://www.cnblogs.com/saionjisekai/p/16664313.html

相关文章

  • vc++ get random via random_device,mt19937
     #include<ctime>#include<iostream>#include<random>usingnamespacestd;staticrandom_devicerd;staticmt19937mt{rd()};template<typenameT>vo......
  • [C++]类名加个括号是什么东东
    先考考大家,下面的代码,编译得过吗?classMyClass{public:MyClass(){printf("MyClass\n");}};int_tmain(intargc,_TCHAR*argv[]){......
  • Java调用C++动态链接库——Jni
    最近项目需要,将C++的算法工程编译成动态链接库,交给Java后台当作函数库调用。就去了解了下Jni。使用起来还是比较方便的。1.  首先编写Java的调用类。例如:  public......
  • 记刷题过程中发现的C++与C的差异
    前言上大学了,学c。标题嫖自@快乐永恒正题01#include<stdio.h>intmain(){longlonga,b;scanf("%lld%lld",&a,&b);printf("%lld%lld%lld%lld%l......
  • conda环境报错:libgomp.so.1: version `GOMP_4.0' not found?libstdc++.so.6: version `
    问题之前的conda环境好好地,最近不知为何被破坏了,运行即报错:/miniconda3/opt/lib/R/bin/exec/R:/miniconda3/opt/lib/R/bin/exec/../../lib/../../libgomp.so.1:version......
  • C++ 初识函数模板
    1.前言什么是函数模板?理解什么是函数模板,须先搞清楚为什么需要函数模板。如果现在有一个需求,要求编写一个求2个数字中最小数字的函数,这2个数字可以是int类型,可以......
  • c++STL用法总结
    一、vector的用法vectorvet;1、排序:sort(vet.begin(),vet.end()),时间复杂度O(nlogn)2、查找:if(find(vet.begin(),vet.end(),x)!=vet.end()),时间复杂度O(n)......
  • C++ vector的reserve和resize详解
    vector的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!原因如下:     reserve是容器预留空间,但在空间......
  • C++字符串转换(stoi;stol;stoul;stoll;stoull;stof;stod;stold)
    1、C/C++:longint与longlong的区别在实际的使用中,long与int几乎没有区别:原因是早期的C编译器定义了longint占用4个字节,int占用2个字节,longint是名副其实的长整型。在AN......
  • Python3中二叉树前序遍历的迭代解决方案
    Python3中二叉树前序遍历的迭代解决方案ABinaryTree二叉树是分层数据结构,其中每个父节点最多有2个子节点。在今天的文章中,我们将讨论一个在大量技术编码面试中出现......