【算法】演员~评论家方法

一、引言

        演员-评论家算法(Actors-Critics Method)是一种用于并发编程中的同步机制,用于解决多线程环境下的资源竞争问题。与传统的锁和信号量等同步工具不同,演员-评论家方法采用更加灵活的协作策略。算法结合了策略梯度(Policy Gradient)和价值函数(Value Function)估计的强化学习方法。它包含两个主要组件:演员(Actor)和评论家(Critic)。演员负责根据当前策略选择动作,而评论家评估这些动作的好坏,并提供反馈来改进演员的策略。通过这种方式,演员-评论家算法能够在连续动作空间和复杂任务中表现出色。

二、算法原理

演员-评论家算法的核心思想是将参与者分为两类角色:

  • 演员(Actors):执行实际工作的线程,它们对共享资源进行操作。
  • 评论家(Critics):监控并评估演员行为的线程,它们不直接操作资源,但可以提供反馈以指导演员的行为。

算法的基本流程如下:

  • 演员尝试对共享资源进行操作。
  • 评论家评估操作的影响,并给出建议或直接干预。
  • 根据评论家的建议,演员决定是否继续操作或修改行为。

三、数据结构

演员-评论家算法中涉及的数据结构包括:

  • 共享资源:需要被多个线程访问和修改的数据。
  • 评论家反馈:评论家对演员操作的评估结果。
  • 状态表示:用于描述环境当前的状态。
  • 动作空间:定义了演员可以选择的所有可能动作。
  • 策略网络(演员):参数化为θ,输出给定状态下的动作概率分布。
  • 价值网络Q网络(评论家):参数化为w,评估当前状态或状态-动作对的价值。

四、算法使用场景

演员-评论家算法适用于:

  • 分布式系统:在分布式系统中协调不同节点的行为。
  • 实时系统:需要快速响应和动态调整策略的场景。
  • 多线程优化:在多线程环境中减少锁的使用,提高性能。

  • 机器人控制:优化机器人的动作策略。

  • 自动驾驶:学习驾驶策略和决策过程。

  • 游戏AI:训练游戏中的智能代理。
  • 资源管理:优化资源分配策略。
  • 连续动作空间:当动作空间是连续的,演员-评论家方法表现优越。
  • 高维状态空间:在复杂环境中,如机器人控制和游戏AI。
  • 需要高效学习的场景:在需要快速适应环境变化的任务中。

五、算法实现

使用Python实现的简单演员-评论家算法示例:

import numpy as np
import gym
import tensorflow as tfclass ActorCritic:def __init__(self, state_size, action_size):self.state_size = state_sizeself.action_size = action_sizeself.actor = self.build_actor()self.critic = self.build_critic()def build_actor(self):model = tf.keras.Sequential([tf.keras.layers.Dense(24, activation='relu', input_shape=(self.state_size,)),tf.keras.layers.Dense(self.action_size, activation='softmax')])model.compile(optimizer='adam', loss='categorical_crossentropy')return modeldef build_critic(self):model = tf.keras.Sequential([tf.keras.layers.Dense(24, activation='relu', input_shape=(self.state_size,)),tf.keras.layers.Dense(1, activation='linear')])model.compile(optimizer='adam', loss='mean_squared_error')return modeldef choose_action(self, state):state = state.reshape([1, self.state_size])probabilities = self.actor.predict(state).flatten()return np.random.choice(self.action_size, p=probabilities)def train(self, state, action, reward, next_state):state = state.reshape([1, self.state_size])next_state = next_state.reshape([1, self.state_size])target = reward + 0.99 * self.critic.predict(next_state)td_error = target - self.critic.predict(state)# Update actoraction_onehot = np.zeros(self.action_size)action_onehot[action] = 1self.actor.fit(state, action_onehot.reshape([1, self.action_size]), verbose=0)# Update criticself.critic.fit(state, target, verbose=0)# 使用示例
if __name__ == "__main__":env = gym.make('CartPole-v1')state_size = env.observation_space.shape[0]action_size = env.action_space.nagent = ActorCritic(state_size, action_size)for episode in range(1000):state = env.reset()done = Falsewhile not done:action = agent.choose_action(state)next_state, reward, done, _ = env.step(action)agent.train(state, action, reward, next_state)state = next_state

六、其他同类算法对比

与演员-评论家算法相比,其他并发控制算法包括:

  • 锁(Locks):通过互斥锁来保证同一时间只有一个线程访问资源。
  • 信号量(Semaphores):使用计数信号量来控制对资源的访问。
  • 监视器(Monitors):一种同步机制,允许线程在进入临界区前等待。
算法特点优势劣势
Q-Learning基于值的学习,使用 Q 表简单易懂,适用于离散动作空间不适用于高维状态空间,收敛速度慢
SARSA在线学习,使用当前策略更新 Q 值适应性强,能够处理非最优策略收敛速度慢,容易陷入局部最优
DQN使用深度学习进行 Q 值估计处理高维状态空间,具有较好的泛化能力训练不稳定,需要经验回放和目标网络
A3C异步并行学习,使用多个代理训练效率高,能够处理复杂环境实现复杂,需调试多个代理的同步
PPO采用剪切损失函数,保证策略更新稳定简单易实现,具有良好的性能训练速度可能较慢,超参数调节较为复杂

七、多语言代码实现

Java

import java.util.Random;public class ActorCritic {private double[] policy;  // Actor's policyprivate double[] valueFunction;  // Critic's value functionprivate double alpha = 0.01;  // Learning rate for policyprivate double beta = 0.01;  // Learning rate for value functionprivate Random random = new Random();public ActorCritic(int numActions) {policy = new double[numActions];valueFunction = new double[numActions];// Initialize policy and value functionfor (int i = 0; i < numActions; i++) {policy[i] = 1.0 / numActions;valueFunction[i] = 0.0;}}public int selectAction() {double p = random.nextDouble();double cumulativeProbability = 0.0;for (int i = 0; i < policy.length; i++) {cumulativeProbability += policy[i];if (p < cumulativeProbability) {return i;}}return policy.length - 1;}public void update(int action, double reward, double nextValue) {double tdError = reward + nextValue - valueFunction[action];valueFunction[action] += beta * tdError;policy[action] += alpha * tdError * (1 - policy[action]);// Normalize policydouble sum = 0.0;for (double p : policy) sum += p;for (int i = 0; i < policy.length; i++) policy[i] /= sum;}public static void main(String[] args) {// Example usageActorCritic ac = new ActorCritic(4);int action = ac.selectAction();ac.update(action, 1.0, 0.5);System.out.println("Selected action: " + action);}
}

Python

import numpy as npclass ActorCritic:def __init__(self, num_actions, alpha=0.01, beta=0.01):self.policy = np.ones(num_actions) / num_actionsself.value_function = np.zeros(num_actions)self.alpha = alphaself.beta = betadef select_action(self):return np.random.choice(len(self.policy), p=self.policy)def update(self, action, reward, next_value):td_error = reward + next_value - self.value_function[action]self.value_function[action] += self.beta * td_errorself.policy[action] += self.alpha * td_error * (1 - self.policy[action])self.policy /= np.sum(self.policy)# Example usage
ac = ActorCritic(4)
action = ac.select_action()
ac.update(action, 1.0, 0.5)
print(f"Selected action: {action}")

C++

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>class ActorCritic {
public:ActorCritic(int numActions, double alpha = 0.01, double beta = 0.01): alpha(alpha), beta(beta), policy(numActions, 1.0 / numActions), valueFunction(numActions, 0.0) {std::srand(std::time(0));}int selectAction() {double p = static_cast<double>(std::rand()) / RAND_MAX;double cumulativeProbability = 0.0;for (size_t i = 0; i < policy.size(); ++i) {cumulativeProbability += policy[i];if (p < cumulativeProbability) {return i;}}return policy.size() - 1;}void update(int action, double reward, double nextValue) {double tdError = reward + nextValue - valueFunction[action];valueFunction[action] += beta * tdError;policy[action] += alpha * tdError * (1 - policy[action]);double sum = 0.0;for (double p : policy) sum += p;for (double &p : policy) p /= sum;}private:double alpha;double beta;std::vector<double> policy;std::vector<double> valueFunction;
};int main() {ActorCritic ac(4);int action = ac.selectAction();ac.update(action, 1.0, 0.5);std::cout << "Selected action: " << action << std::endl;return 0;
}

Go

package mainimport ("fmt""math/rand""time"
)type ActorCritic struct {policy         []float64valueFunction  []float64alpha, beta    float64
}func NewActorCritic(numActions int, alpha, beta float64) *ActorCritic {policy := make([]float64, numActions)valueFunction := make([]float64, numActions)for i := range policy {policy[i] = 1.0 / float64(numActions)}return &ActorCritic{policy, valueFunction, alpha, beta}
}func (ac *ActorCritic) SelectAction() int {p := rand.Float64()cumulativeProbability := 0.0for i, prob := range ac.policy {cumulativeProbability += probif p < cumulativeProbability {return i}}return len(ac.policy) - 1
}func (ac *ActorCritic) Update(action int, reward, nextValue float64) {tdError := reward + nextValue - ac.valueFunction[action]ac.valueFunction[action] += ac.beta * tdErrorac.policy[action] += ac.alpha * tdError * (1 - ac.policy[action])sum := 0.0for _, p := range ac.policy {sum += p}for i := range ac.policy {ac.policy[i] /= sum}
}func main() {rand.Seed(time.Now().UnixNano())ac := NewActorCritic(4, 0.01, 0.01)action := ac.SelectAction()ac.Update(action, 1.0, 0.5)fmt.Printf("Selected action: %d\n", action)
}

八、实际服务应用场景代码框架

应用场景

        开发一个智能机器人控制系统,使用演员-评论家方法来训练机器人在特定环境中移动。我们将使用 OpenAI Gym 作为环境,使用 Python 实现整个系统。

项目结构

robot_controller/
├── main.py
├── actor_critic.py
├── environment.py
└── requirements.txt

requirements.txt

gym
tensorflow
numpy

actor_critic.py

import numpy as np
import tensorflow as tfclass ActorCritic:def __init__(self, state_size, action_size):self.state_size = state_sizeself.action_size = action_sizeself.actor = self.build_actor()self.critic = self.build_critic()def build_actor(self):model = tf.keras.Sequential([tf.keras.layers.Dense(24, activation='relu', input_shape=(self.state_size,)),tf.keras.layers.Dense(self.action_size, activation='softmax')])model.compile(optimizer='adam', loss='categorical_crossentropy')return modeldef build_critic(self):model = tf.keras.Sequential([tf.keras.layers.Dense(24, activation='relu', input_shape=(self.state_size,)),tf.keras.layers.Dense(1, activation='linear')])model.compile(optimizer='adam', loss='mean_squared_error')return modeldef choose_action(self, state):state = state.reshape([1, self.state_size])probabilities = self.actor.predict(state).flatten()return np.random.choice(self.action_size, p=probabilities)def train(self, state, action, reward, next_state):state = state.reshape([1, self.state_size])next_state = next_state.reshape([1, self.state_size])target = reward + 0.99 * self.critic.predict(next_state)td_error = target - self.critic.predict(state)# Update actoraction_onehot = np.zeros(self.action_size)action_onehot[action] = 1self.actor.fit(state, action_onehot.reshape([1, self.action_size]), verbose=0)# Update criticself.critic.fit(state, target, verbose=0)

environment.py

import gymclass RobotEnvironment:def __init__(self):self.env = gym.make('CartPole-v1')def reset(self):return self.env.reset()def step(self, action):return self.env.step(action)def render(self):self.env.render()def close(self):self.env.close()

main.py

import numpy as np
from actor_critic import ActorCritic
from environment import RobotEnvironmentif __name__ == "__main__":env = RobotEnvironment()state_size = env.env.observation_space.shape[0]action_size = env.env.action_space.nagent = ActorCritic(state_size, action_size)for episode in range(1000):state = env.reset()done = Falsewhile not done:action = agent.choose_action(state)next_state, reward, done, _ = env.step(action)agent.train(state, action, reward, next_state)state = next_stateenv.render()env.close()

        演员-评论家方法是一种强大的强化学习算法,结合了策略和价值函数的优点,适用于多种复杂的环境。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/413532.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyQt5:pycharm设置及使用

前言 PyQt5 是一个用于创建图形用户界面的 Python 库&#xff0c;它是 Qt 应用程序框架的 Python 绑定。Qt 是一个广泛使用的跨平台 C 框架&#xff0c;PyQt5 允许开发者使用 Python 编写图形界面应用程序&#xff0c;而不必直接使用 C。 为了方便地使用它&#xff0c;我尝试在…

【MySQL进阶之路】数据库的操作

目录 创建数据库 字符集和校验规则 查看数据库支持的字符集 查看数据库支持的字符集校验规则 指定字符集和校验规则 在配置文件中配置 查看数据库 显示创建语句 修改数据库 删除数据库 数据库的备份和恢复 备份整个数据库 备份特定表 备份多个数据库 备份所有数据…

【大模型】LangChain基础学习

前言:LangChain是一个用于构建端到端语言模型应用的框架 目录 1. 基础知识2. 基本使用2.1 安装2.2 启动示例2.3 使用prompt2.4 输出解析器 3. 相关应用3.1 RAG 参考文献 1. 基础知识 六大组件 模型&#xff08;Models&#xff09;&#xff1a;包含各大语言模型的LangChain接口…

Redis从入门到入门(上)

1.Redis概述 文章目录 1.Redis概述1.1 什么是Redis1.2 Redis的应用场景 2.Linux下Redis的安装与使用2.1 Redis下载2.2 Redis的启动2.3 Redis配置2.4 连接Redis 1.1 什么是Redis Redis是用C语言开发的一个开源的高性能键值对&#xff08;key-value&#xff09;数据库&#xff0…

MATLAB生成COE文件

MATLAB代码 % 参数设置 N 4096; % 数据点数量 t linspace(0, 2*pi, N); % 时间向量 width 12; % 位宽% 正弦波&#xff0c;幅度在0到5之间 sine_wave 2.5 * sin(t) 2.5;% 三角波&#xff0c;幅度在0到5之间 tri_wave 5 * (1 - abs(mod(t/(2*pi)*4, 2) - 1));% 方波&…

springboot集成七牛云上传文件

大体思路 上传 前端上传MultipartFile file 文件 进行名字空值校验和格式校验&#xff0c;大概就是判断后缀是不是属于jpg.png 生成唯一uuid名称&#xff0c;然后拿着这个文件名和图片文件File调接口 接口参数为 输入流inputstream&#xff0c;将file化流传输文件名上传t…

多线程+连接池+代理 运行一段时间线程阻塞,如何解决??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

<Rust>egui学习之小部件(四):如何在窗口中添加滚动条Scroll部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第四篇博…

今日算法:蓝桥杯基础题之“切面条”

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注&#xff01;个人知乎 从今天开始&#xff0c;一起了解算法&#xff0c;每日一题&#xff0c;从 JavScript 的技术角度进行解答&#xff0c;如果你对算法也感兴趣&#xff0c;请多多关注哦。 问题描述 一…

【深度学习与NLP】——深度卷积神经网络AlexNet

目录 一、卷积神经网络的发展历程 二、简要介绍 三、代码实现 四、缺点和过时的地方 一、卷积神经网络的发展历程 早期理论基础阶段&#xff08;20 世纪 60 年代 - 80 年代&#xff09;&#xff1a; 1968 年&#xff0c;Hubel 和 Wiesel 通过对猫视觉神经的研究&#xff0…

Hibernate 批量插入速度慢的原因和解决方法

由于业务需要一次性连续写入超过10k条以上的新数据&#xff0c;当对象超过10个成员变量以后&#xff0c;整个写入过程居然需要长达35秒&#xff0c;这个速度是不能接受的&#xff0c;故此研究了一下怎么开启Hibernate批量写入的功能。 我这边使用的是Hibernate 5.6.15 在网上…

Python 从入门到实战3(列表的简单操作)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过python小栗子来学习python基础知识语法&#xff…

C语言中的“#”和“##”

目录 开头1.什么是#?2.什么是##?3.#和##的实际应用输出变量的名字把两个符号连接成一个符号输出根据变量的表达式…… 下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。在今天&#xff0c;我们要学一下关于C语言中的#和##的一些知识。 1.什么是#? #&#xff0…

《黑神话:悟空》:30%抽成真相

《黑神话&#xff1a;悟空》自建服务器出售&#xff1f;揭秘游戏界的30%抽成真相&#xff01; 近年来&#xff0c;随着游戏行业的迅猛发展&#xff0c;游戏开发商与发行平台之间的利益分配问题逐渐成为业界关注的焦点。其中&#xff0c;《黑神话&#xff1a;悟空》作为一款备受…

JS基础之【基本数据类型与类型间的隐式显示转换】

&#x1f680; 个人简介&#xff1a;某大型国企高级前端开发工程师&#xff0c;7年研发经验&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码…

streamlit+wordcloud使用pyinstaller打包遇到的一些坑

说明 相比常规的python程序打包&#xff0c;streamlit应用打包需要额外加一层壳&#xff0c;常规app.py应用运行直接使用 python app.py就可以运行程序了&#xff0c;但streamlit应用是需要通过streamlit命令来运行 streamlit app.py所以使用常规的pyinstaller app.py打包是…

云同步的使用

云同步技术是一种在多个设备或系统之间保持数据一致性的技术&#xff0c;它通常依赖于云存储服务来实现。在Java中&#xff0c;实现云同步功能通常需要与云服务提供商的API进行交互&#xff0c;如Amazon S3、Google Cloud Storage、Microsoft Azure Blob Storage等。 以下是一个…

秋风送爽,夏意未央|VELO Prevail Revo坐垫,一骑绿动起来吧~

夏末秋初&#xff0c;当第一片落叶缓缓飘落&#xff0c;是时候骑上你的自行车&#xff0c;迎接新的季节啦。带上维乐Prevail Revo坐垫&#xff0c;因为它独树一帜地采用EVA与回收咖啡渣精制而成的轻量发泡提升了减震性能&#xff0c;可以让你的每一次骑行都充满意义。    “…

虚幻引擎(Unreal Engine)技术使得《黑神话悟空传》大火,现在重视C++的开始吃香了,JAVA,Go,Unity都不能和C++相媲美!

虚幻引擎&#xff08;Unreal Engine&#xff09;火了黑神话游戏。 往后&#xff0c;会有大批量的公司开始模仿这个赛道&#xff01; C 的虚拟引擎技术通常指的是使用 C 语言开发的游戏引擎&#xff0c;如虚幻引擎&#xff08;Unreal Engine&#xff09;等。以下是对 C 虚拟引…

【virtuoso】INV 原理图+前仿真 + 版图 + 后仿真

采用SMIC工艺&#xff0c;不同工艺版图窗口可能有差异 1. 原理图&前仿真 1.1 绘制原理图 PMOS: NMOS宽长比2&#xff1a;1 PMOS开启导通电阻大一点&#xff0c;这样设置&#xff0c;可以使得阈值电压是VDD/2 按 i&#xff0c;可以插入器件按p&#xff0c;可以放置端口 1.2…