Q-Learning解决最短路径问题

紧接着使用Q-Learning实现了一维环境里的寻宝问题,以及二维世界里的寻宝问题,将实现模板应用于最短路问题。

环境说明

最短路径问题的环境如下图,起点为A,终点为G,选择最短的路线完成A->G。节点之间的连线表示节点相联通,其上数值表示奖励。若节点之间无法联通,则奖励为-99。
在这里插入图片描述

Q-Learning流程

实现流程:(1)设置初始状态;(2)选择动作;(3)获取状态反馈;(4)更新Q表;(5)更新状态;(6)设置终止条件
在这里插入图片描述

状态动作说明

状态(state):节点编号
动作(action):节点编号

参数设置

初始化时需要设置环境状态,动作列表以及算法的参数。

class TwoDimensionQTable:
    def __init__(self, states,actions,rewords,learningRate=0.1, rewarddecay=0.9, eGreedy=0.9,episode=100):
        #状态列表
        self.states=states
        #动作列表
        self.actions = actions
        #奖励列表
        self.rewords=rewords
        #学习率
        self.lr = learningRate
        #奖励衰减率
        self.gamma = rewarddecay
        #贪婪策略
        self.epsilon = eGreedy
        #训练次数
        self.episode=episode
        #空Q表
        self.qTable = pd.DataFrame(columns=self.actions, dtype=np.float64)

由于初始设置Q表为空,在算法进行过程中需要将探索得到的新状态添加进入Q表并更新Q表的行列。

    #遇到新状态后添加到Q表,行索引:状态;列索引:动作
    def stateExist(self, state):
        if str(state) not in self.qTable.index:
            self.qTable = self.qTable.append(
                pd.Series(
                    [0]*len(self.actions),
                    index=self.qTable.columns,
                    name=state,
                    )
            )

动作选择

在动作选择部分,算法根据当前状态(state)选择动作(action)。选择动作过程中的策略是:90%的概率根据Q表最优值进行选择;10%的概率随机选择;

    #根据状态从qTable选择动作
    def chooseAction(self,state):
        #判断状态是否存在Q表中
        self.stateExist(state)
        #选择采取的动作
        #90%的概率按照Q表最优进行选择
        if np.random.uniform()<self.epsilon:
            stateActionList=self.qTable.loc[state,:]
            #若存在多个最好动作,则随机选择其中一个
            action=np.random.choice(stateActionList[stateActionList==np.max(stateActionList)].index)
        #10%的概率随机选择一个动作
        else:
           action=np.random.choice(self.actions)
        return action

状态反馈

#根据状态和动作返回下一个状态和当前的奖励
    def feedBack(self,state,action):
        nextState=action
        reword=self.rewords.loc[state][nextState]
        return nextState,reword

更新Q表

    #根据当前状态、动作、下一状态、奖励更新Q表
    def updateTable(self,state,action,nextState,reword):
        #判断状态是否存在Q表中
        self.stateExist(nextState)
        #当前状态值
        qPredict=self.qTable.loc[state,action]
        #下一状态值
        if nextState=='G':
            qTarget=reword
        else:
            qTarget=reword+self.gamma*self.qTable.loc[nextState,:].max()
        #print("qTarget:",qTarget)
        #更新
        self.qTable.loc[state,action]+=self.lr*(qTarget-qPredict)

主循环

   #主循环
    def mainCycle(self):
        for episode in range(self.episode):
            #初始状态
            state='A'
            actionStr=""
            while True:
                #选择动作
                action=self.chooseAction(state)
                if episode==self.episode-1:
                    actionStr+=str(state)+"->"
                #状态反馈
                nextState,reword=self.feedBack(state,action)
                #更新Q表
                self.updateTable(state,action,nextState,reword)
                #更新状态
                state=nextState
                #终止条件
                if state=='G':
                    if episode==self.episode-1:
                        print(actionStr)
                    break

求解结果

在这里插入图片描述
求解结果为:A->C->F->E->G

完整代码

import numpy as np
import pandas as pd
class TwoDimensionQTable:
    def __init__(self, states,actions,rewords,learningRate=0.1, rewarddecay=0.9, eGreedy=0.9,episode=100):
        #状态列表
        self.states=states
        #动作列表
        self.actions = actions
        #奖励列表
        self.rewords=rewords
        #学习率
        self.lr = learningRate
        #奖励衰减率
        self.gamma = rewarddecay
        #贪婪策略
        self.epsilon = eGreedy
        #训练次数
        self.episode=episode
        #空Q表
        self.qTable = pd.DataFrame(columns=self.actions, dtype=np.float64)
    #遇到新状态后添加到Q表,行索引:状态;列索引:动作
    def stateExist(self, state):
        if str(state) not in self.qTable.index:
            self.qTable = self.qTable.append(
                pd.Series(
                    [0]*len(self.actions),
                    index=self.qTable.columns,
                    name=state,
                    )
            )
    #根据状态从qTable选择动作
    def chooseAction(self,state):
        #判断状态是否存在Q表中
        self.stateExist(state)
        #选择采取的动作
        #90%的概率按照Q表最优进行选择
        if np.random.uniform()<self.epsilon:
            stateActionList=self.qTable.loc[state,:]
            #若存在多个最好动作,则随机选择其中一个
            action=np.random.choice(stateActionList[stateActionList==np.max(stateActionList)].index)
        #10%的概率随机选择一个动作
        else:
           action=np.random.choice(self.actions)
        return action
    #根据状态和动作返回下一个状态和当前的奖励
    def feedBack(self,state,action):
        nextState=action
        reword=self.rewords.loc[state][nextState]
        return nextState,reword
    #根据当前状态、动作、下一状态、奖励更新Q表
    def updateTable(self,state,action,nextState,reword):
        #判断状态是否存在Q表中
        self.stateExist(nextState)
        #当前状态值
        qPredict=self.qTable.loc[state,action]
        #print("qPredict:",qPredict)
        #下一状态值
        if nextState=='G':
            qTarget=reword
        else:
            qTarget=reword+self.gamma*self.qTable.loc[nextState,:].max()
        #print("qTarget:",qTarget)
        #更新
        self.qTable.loc[state,action]+=self.lr*(qTarget-qPredict)
    #主循环
    def mainCycle(self):
        for episode in range(self.episode):
            #初始状态
            state='A'
            actionStr=""
            while True:
                #选择动作
                action=self.chooseAction(state)
                if episode==self.episode-1:
                    actionStr+=str(state)+"->"
                #状态反馈
                nextState,reword=self.feedBack(state,action)
                #print("nextState:",nextState,"  ","reword:",reword)
                #更新Q表
                self.updateTable(state,action,nextState,reword)
                #更新状态
                state=nextState
                #终止条件
                if state=='G':
                    if episode==self.episode-1:
                        print(actionStr)
                    break
                #break

if __name__=="__main__":
    states=['A','B','C','D','E','F','G']
    rewords=[
        [-99,4,6,6,-99,-99,-99],
        [-99,-99,1,-99,7,-99,-99],
        [-99,-99,-99,-99,6,4,-99],
        [-99,-99,2,-99,-99,5,-99],
        [-99,-99,-99,-99,-99,-99,6],
        [-99,-99,-99,-99,1,-99,8],
        [-99,-99,-99,-99,-99,-99,-99],
        ]
    rewords=pd.DataFrame(rewords,columns=states,index=states)
    actions=['A','B','C','D','E','F','G']
    RL = TwoDimensionQTable(states=states,actions=actions,rewords=rewords)
    RL.mainCycle()
    print(RL.qTable)

===========================================
今天到此为止,后续记录其他强化学习技术的学习过程。
以上学习笔记,如有侵犯,请立即联系并删除!

以下是一个简单的q-learning算法栅格最短路径的MATLAB代码示例: ``` clear all; clc; %定义初始状态和目标状态 start_state = [1,1]; goal_state = [10,10]; %定义行动空间和奖励矩阵 action_space = ['N','S','E','W']; reward_matrix = -ones(10,10); reward_matrix(goal_state(1),goal_state(2)) = 100; %定义Q矩阵和学习参数 Q = zeros(10,10,4); alpha = 0.5; gamma = 0.9; epsilon = 0.1; %开始训练 for episode = 1:10000 %将智能体放在起点 current_state = start_state; while (~isequal(current_state,goal_state)) %选择行动 if rand < epsilon action = randi(4); else [~,action] = max(Q(current_state(1),current_state(2),:)); end %执行行动 next_state = current_state + [0,-1;0,1;1,0;-1,0](action,:); next_state = min(max(next_state,1),10); %更新Q矩阵 Q(current_state(1),current_state(2),action) = (1-alpha)*Q(current_state(1),current_state(2),action) + alpha*(reward_matrix(next_state(1),next_state(2))+gamma*max(Q(next_state(1),next_state(2),:))); %更新当前状态 current_state = next_state; end end %使用Q矩阵执行最短路径 current_state = start_state; path = [current_state]; while (~isequal(current_state,goal_state)) [~,action] = max(Q(current_state(1),current_state(2),:)); next_state = current_state + [0,-1;0,1;1,0;-1,0](action,:); next_state = min(max(next_state,1),10); path = [path;next_state]; current_state = next_state; end %绘制结果 figure(); plot(path(:,2),path(:,1),'-o'); grid on; xlim([0.5 10.5]); ylim([0.5 10.5]); xlabel('X'); ylabel('Y'); title('Q-Learning Algorithm for Shortest Path Problem in Grid World'); ``` 该代码使用了一个简单的4个行动空间(北、南、东、西)和一个-1的奖励矩阵,表示无论走哪个方向都会受到一点惩罚。Q矩阵是一个三维矩阵,其中前两个维度表示状态,第三个维度表示行动。在训练过程中,智能体随机选择行动或者根据当前Q值选择最优行动,并更新Q矩阵。在执行最短路径时,智能体根据当前Q值选择最优行动,直到到达目标状态。最终,代码将路径可视化并绘制出来。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南音小榭

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

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

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

打赏作者

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

抵扣说明:

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

余额充值