1. 马尔可夫决策过程(MDP)定义
1.1 基本概念
马尔可夫决策过程(MDP)是一种数学框架,用于建模在不确定环境中的决策制定问题。它特别适用于那些决策结果部分依赖于随机因素的场景。MDP的核心思想是,系统的状态转移只依赖于当前状态和所选择的行动,而与过去的状态历史无关,这被称为“马尔可夫性质”。
1.2 组成元素
MDP主要由以下几个元素构成:
- 状态(State):系统可能处于的状态集合,表示为
。
- 行动(Action):在给定状态下可采取的行动集合,表示为
。对于每个状态
,可行的行动集合表示为
。
- 转移概率(Transition Probability):对于每个状态
和行动
,执行该行动后转移到新状态
的概率,表示为
。
- 奖励(Reward):在状态
采取行动
后获得的即时奖励,表示为
。
- 折扣因子(Discount Factor):
,介于 0 到 1 之间的数值,用于对未来奖励进行折扣,以反映未来奖励的不确定性和时间价值。
在MDP中,一个策略 是从状态到行动的映射,它可以是确定性的
:
或是随机性的
:
。策略的目标是最大化期望回报,这通常通过价值函数来评估。价值函数
表示在状态
下遵循策略
的预期回报,而动作价值函数
表示在状态
采取行动
并遵循策略
的预期回报。
贝尔曼方程是MDP中的核心,它递归地定义了价值函数:
2. 马尔可夫性质与状态转移
2.1 马尔可夫性质
马尔可夫性质是马尔可夫决策过程(MDP)的核心特征之一,它指的是未来的状态转移只依赖于当前状态和当前采取的动作,而与之前的状态历史无关。这种性质可以用以下公式表示:
这意味着,给定当前状态 ,下一个状态
的概率分布与之前的状态序列无关。
2.2 状态转移矩阵与概率
状态转移矩阵是描述MDP中状态之间转移概率的工具。对于有限状态集合 和有限动作集合
,状态转移矩阵
可以表示为一个
的矩阵,其中每个元素
表示在状态
下采取动作
转移到状态
的概率。具体地,状态转移矩阵可以表示为:
其中,每一行的元素之和为1,即对于任意状态 和动作
,有:

此外,状态转移概率也可以通过状态转移矩阵来计算,即:
这里, 是在状态
下采取动作
的策略概率。通过这种方式,可以计算在给定策略
下,从一个状态转移到另一个状态的概率。
3. 价值函数与贝尔曼方程
3.1 状态价值函数
状态价值函数是衡量从状态
开始,遵循某个策略
所能获得的期望回报。它反映了在策略
下,状态
的“价值”。数学上,状态价值函数可以递归地定义为:
其中, 是在时间
获得的即时奖励,
是折扣因子,
,用于平衡即时奖励与未来奖励的重要性。
3.2 动作价值函数
动作价值函数衡量的是在状态
下采取动作
,并遵循策略
所能获得的期望回报。它可以用来评估特定状态下执行特定动作的“质量”。数学定义如下:
动作价值函数是状态价值函数的扩展,它不仅考虑了起始状态,还考虑了起始动作。
3.3 贝尔曼方程
贝尔曼方程是一组递归方程,用于描述价值函数的递归关系。贝尔曼方程是理解和解决MDP的关键工具,它将一个状态或动作的价值表达为其后续状态或动作价值的函数。
状态价值函数的贝尔曼方程如下:
动作价值函数的贝尔曼方程如下:
这两个方程体现了MDP中的递归结构,即当前状态或动作的价值依赖于从该状态或动作出发所能获得的即时奖励以及未来状态或动作的期望价值。
贝尔曼方程的求解通常需要通过迭代方法,如值迭代(Value Iteration)或策略迭代(Policy Iteration),这些方法在求解MDP时寻找最优策略,该策略能够最大化状态或动作的期望回报。
4. 策略与优化
4.1 策略定义
策略(Policy)在马尔可夫决策过程中是代理在给定状态下选择动作的规则或函数。它可以是确定性的,即对于每个状态,策略都指定一个单一的动作;也可以是随机性的,即对于每个状态,策略定义了一个动作的概率分布。
策略可以用函数 表示,其中
是状态空间,
是动作空间。对于随机性策略,可以表示为
,即在状态
下选择动作
的概率。
4.2 最优策略
最优策略 是指在所有可能的策略中,能够最大化期望回报的策略。根据贝尔曼最优方程,最优策略可以通过以下方式定义:
其中, 是最优状态下的价值函数,
是从状态
通过动作
转移到状态
的概率,
是与此转移相关联的奖励,
是折扣因子。
4.3 策略迭代与价值迭代
策略迭代和价值迭代是两种求解MDP问题的主要算法。
-
策略迭代:此算法通过迭代改进策略来收敛到最优策略。在每一步中,先计算给定策略下的值函数,然后更新策略以最大化该值函数。
-
价值迭代:此算法通过迭代改进值函数来收敛到最优值函数。在每一步中,更新每个状态的价值函数,直到收敛。一旦得到最优值函数,可以通过选择使得该值函数最大化的动作来获得最优策略。
策略迭代和价值迭代的更新规则可以分别表示为:
其中, 是按照策略
获得的在状态
下的期望回报,
是第
次迭代的价值函数。通过这些迭代过程,可以逐步逼近最优策略和最优价值函数。
MDP应用案例
假设有一个机器人在一个网格世界中寻找宝藏。状态集合 包括网格中的每个单元格,动作集合
包括向上、向下、向左和向右移动。转移概率
定义了机器人在每个方向上移动时到达新位置的概率,奖励函数
定义了机器人在找到宝藏时获得的奖励。
#include <iostream> // 标准输入输出库
#include <vector> // 动态数组容器
#include <map> // 关联容器
#include <random> // 随机数生成
// 定义状态类型,这里简单地用整数表示状态
typedef int State;
// 定义动作类型,这里定义了四个基本方向的动作
enum Action { UP, DOWN, LEFT, RIGHT };
// 定义奖励类型,奖励用双精度浮点数表示
typedef double Reward;
// 定义转移概率函数类型,这是一个函数对象,接受当前状态、动作和下一个状态作为参数,并返回转移概率
typedef std::function<double(State, Action, State)> TransitionProbability;
// 定义MDP类
class MDP {
private:
// 转移概率映射,从当前状态和动作映射到下一个状态的转移概率函数
std::map<State, std::vector<std::pair<Action, std::map<State, TransitionProbability>>>> transition_probabilities;
// 奖励映射,从状态和动作映射到奖励
std::map<State, Reward> rewards;
public:
// 向MDP中添加转移概率
void add_transition(State current_state, Action action, State next_state, double probability) {
// 在映射中为当前状态和动作添加一个新的转移概率条目
transition_probabilities[current_state].push_back({action, {
{next_state, [probability](State s, Action a, State ns) { return probability; }}}});
}
// 向MDP中添加奖励
void add_reward(State state, Action action, Reward reward) {
// 为给定的状态和动作添加奖励
rewards[state] = reward;
}
// 模拟MDP的一步过程
std::pair<State, Reward> step(State current_state, Action action) {
std::random_device rd; // 随机数生成器的种子
std::mt19937 gen(rd()); // 以随机设备种子初始化Mersenne Twister引擎
// 根据当前状态和动作获取转移概率分布
std::discrete_distribution<> dd(transition_probabilities[current_state][0].second.begin(), transition_probabilities[current_state][0].second.end());
// 根据转移概率分布随机选择下一个状态
State next_state = dd(gen);
// 获取当前状态的奖励
Reward reward = rewards[current_state];
// 返回下一个状态和奖励
return {next_state, reward};
}
};
int main() {
MDP myMDP; // 创建MDP实例
// 添加一些转移概率和奖励到MDP实例
myMDP.add_transition(0, UP, 1, 0.7); // 从状态0向上移动到状态1的概率是0.7
myMDP.add_transition(0, UP, 0, 0.3); // 从状态0向上移动但留在状态0的概率是0.3
myMDP.add_reward(0, UP, 10.0); // 从状态0向上移动的奖励是10
// 模拟MDP过程,从状态0开始,执行向上动作
State current_state = 0;
Action action = UP;
// 执行一步MDP过程,并获取结果
auto result = myMDP.step(current_state, action);
// 输出下一个状态和获得的奖励
std::cout << "Next state: " << result.first << ", Reward: " << result.second << std::endl;
return 0; // 程序结束
}