多智能体强化学习环境PettingZoo:从AEC/并行API到实战应用

news2026/5/3 12:54:51
1. 项目概述从单智能体到多智能体的跃迁如果你是从OpenAI Gym或者Gymnasium一路玩过来的强化学习爱好者那么当你第一次尝试把研究兴趣扩展到多个智能体时大概率会感到一阵头疼。单智能体环境里env.reset()、env.step(action)、env.render()这套流程已经刻进了DNA。但到了多智能体场景事情就复杂了谁先行动谁后行动观察空间和动作空间怎么统一管理奖励怎么分配更别提那些需要智能体之间通信、合作甚至竞争的环境了。过去你可能需要为每一个多智能体环境写一套特定的交互逻辑或者依赖一些设计各异、维护状态堪忧的独立代码库这极大地阻碍了研究的可复现性和算法的通用性。PettingZoo的出现就是为了解决这个痛点。你可以把它理解为多智能体强化学习领域的“Gymnasium”。它提供了一个标准化的Python API将五花八门的多智能体环境——从经典的棋盘游戏、雅达利游戏到复杂的协作物理模拟——统一到一个简洁、一致的接口之下。它的核心目标是让研究者能像使用Gymnasium操作单个智能体一样轻松地操作一群智能体从而把精力真正集中在算法设计上而不是环境交互的“脏活累活”上。这个库由Farama基金会前身为OpenAI Gym团队的核心成员创立维护这本身就意味着它在设计理念和工程质量上有着深厚的底蕴。无论是想快速验证一个多智能体算法想法的新手还是需要构建复杂、可定制环境进行前沿研究的资深开发者PettingZoo都提供了一个坚实、可靠的起点。接下来我们就深入拆解这个工具看看它如何让多智能体研究变得“优雅”起来。2. 核心设计哲学AEC与并行API的双重奏PettingZoo的API设计是其灵魂所在。它没有采用一种“万能”但可能臃肿的接口而是巧妙地提供了两种模型来应对不同性质的环境AECAgent Environment Cycle环境和并行Parallel环境。理解这两种模型的区别和适用场景是高效使用PettingZoo的关键。2.1 AEC环境回合制与顺序决策的基石AEC模型是PettingZoo的默认和基础模型。它模拟了一种严格的顺序交互流程在每一个时间步环境会与一个且仅一个智能体进行交互。这个模型完美契合了回合制游戏或行动有明显先后顺序的场景比如棋类游戏围棋、象棋、卡牌游戏扑克以及许多基于回合的策略游戏。它的工作流程就像一个严格的调度器初始化env.reset()后环境进入初始状态并确定第一个行动的智能体。迭代循环使用env.agent_iter()获取一个智能体迭代器。在循环中env.last()方法会返回当前智能体的观察、奖励、终止标志等信息。决策与执行用户或算法根据这些信息为当前智能体选择动作然后调用env.step(action)提交动作。状态推进环境处理该动作更新内部状态并决定下一个行动的智能体可能因为动作触发而改变顺序循环继续直到所有智能体都到达终止或截断状态。这种设计的最大优势是普适性极强。任何多智能体交互理论上都可以被建模成AEC游戏因为它对智能体间的同步性没有任何假设。同时它强制研究者显式地处理智能体间的顺序依赖避免了在同步假设下可能出现的隐蔽Bug。注意在AEC环境中env.step(action)的调用必须与env.agent_iter()的当前智能体严格对应。错误地为非当前智能体提交动作或者在不该提交动作时如智能体已终止提交动作都会导致异常。这是新手最容易踩的坑之一。2.2 并行环境同步决策的优化抽象然而在诸如机器人集群控制、多智能体物理模拟等场景中智能体通常是同时感知、同时决策、同时执行的。为每个智能体顺序调用step不仅低效也不符合问题本质。为此PettingZoo提供了并行API。在并行环境中核心方法变成了env.step(actions)其中actions是一个字典键为智能体名值为对应动作。环境一次性接收所有存活智能体的动作同时推进到下一个状态并返回所有智能体的新观察、奖励、终止标志等信息。# 并行API示例 observations, rewards, terminations, truncations, infos env.step(actions)并行API的代码更简洁更符合直觉并且在底层环境原生支持同步步进时效率更高。但它的使用有一个重要前提你必须确保在每一步所有需要行动的智能体都提供了有效的动作。如果某个智能体本回合不应行动例如在某些阶段被“冻结”你需要在动作字典中显式处理。2.3 如何选择与转换那么该如何选择呢一个简单的原则是如果你的环境本质上是同步的优先使用并行API以获得简洁和性能如果不确定或者环境天然是顺序的则使用AEC API它是万能的保底方案。PettingZoo非常贴心地提供了两者之间的转换工具。你可以通过from pettingzoo.utils.conversions import aec_to_parallel将一个AEC环境包装成并行环境反之亦然。这让你可以用一种API编写算法却能在两种模式的环境上测试。不过要注意这种转换会带来微小的开销并且某些极端情况下的语义可能略有差异在严谨的实验中需留意。3. 环境全家桶从经典博弈到复杂协作PettingZoo不是一个空架子API它自带了一个丰富且高质量的环境集合这些环境被分门别类几乎涵盖了多智能体研究的所有典型场景。直接使用这些经过良好测试和版本控制的环境能让你避开从零搭建模拟器的巨大工程开销。3.1 Atari多智能体游戏研究的试金石PettingZoo的Atari环境基于经典的Arcade Learning Environment (ALE)但将其扩展为多玩家版本。这里不仅有《乓》Pong这种一对一的竞争游戏也有《太空侵略者》Space Invaders的合作模式以及更复杂的混合动机游戏。实操心得Atari环境对算力要求较高因为涉及图像帧处理。在使用时强烈建议配合SuperSuit库后文会介绍中的帧堆叠frame_stack、图像缩放和灰度化resize、color_reduction等Wrapper可以大幅减少输入维度加快训练速度。安装时务必使用pip install pettingzoo[atari]来获取正确的ROM依赖。3.2 Butterfly专注于深度协作的视觉环境这是Farama团队自己开发的一组环境特点是视觉观察和高难度协作。例如“活塞球”Pistonball环境多个智能体控制上下移动的活塞目标是将球撞过对方底线。智能体只能看到自己周围局部区域的像素必须通过策略演化出默契的传球配合。这类环境非常适合研究去中心化协作、局部通信和基于视觉的策略学习。3.3 Classic经典游戏与基准测试这个系列包含了许多确定性高、运行速度快的抽象环境是算法调试和快速原型验证的利器。例如棋类连珠棋Connect Four、国际象棋Chess。牌类德州扑克Texas Hold‘em、斗地主Dou Dizhu。简单网格世界囚徒困境迭代游戏、交通路口模拟。Classic环境通常提供两种观察模式一种是完整的游戏状态如棋盘矩阵适合传统RL算法另一种是部分可观察的、符合游戏规则的信息如手牌适合更复杂的研究。它们的快速迭代特性让你能在几分钟内完成大量实验验证算法核心逻辑是否正确。3.4 MPE粒子世界环境源自OpenAI的Multi-Agent Particle Environments这是一组简单的2D粒子模拟环境。智能体被抽象为移动的圆点任务包括协作导航、通信、捕猎等。尽管画面简单但MPE环境在研究多智能体通信、信用分配和混合合作竞争方面被广泛引用。它的优势在于完全可控你可以轻松修改环境动力学、奖励函数来构造特定的研究问题。3.5 SISL多智能体移动与导航包含三个协作环境最初来自斯坦福的SISL实验室。例如“多智能体追击”Multi-Agent Pursuit多个追击者需要合作围捕逃跑者。这些环境比MPE更复杂一些涉及连续动作空间和更复杂的物理交互是迈向更真实机器人仿真的一个好台阶。4. 实战入门以“活塞球”环境为例走通全流程理论说得再多不如亲手跑一遍。让我们以Butterfly系列中的pistonball_v6环境为例展示从安装、运行、封装到与经典算法库对接的完整流程。你会发现有了PettingZoo构建一个多智能体训练管线可以如此顺畅。4.1 环境安装与基础交互首先安装环境依赖和必要的工具库# 安装PettingZoo基础库和Butterfly环境依赖 pip install pettingzoo[butterfly] # 安装常用的图像处理库SuperSuit依赖 pip install supersuit接下来我们写一段最基础的代码让环境运行起来并理解其数据流import pygame # pistonball 需要pygame进行渲染 from pettingzoo.butterfly import pistonball_v6 # 创建环境实例 # render_modehuman 用于弹出窗口可视化 env pistonball_v6.env(render_modehuman, n_pistons20, continuousTrue) # 环境重置获取初始观察 observations env.reset() # 主循环 for agent in env.agent_iter(): # 1. 获取当前agent的信息元组 # 注意env.last() 返回的是 (obs, reward, terminated, truncated, info) # 在PettingZoo旧版本中terminated和truncated是分开的布尔值。 # 最新版遵循Gymnasium规范返回一个包含两个布尔值的元组。 observation, reward, termination, truncation, info env.last() # 2. 如果智能体已经结束终止或被截断则其动作为None if termination or truncation: action None else: # 3. 这里应该接入你的策略网络我们先用随机策略代替。 # 动作空间是连续的continuousTrue时所以从[-1, 1]均匀采样。 action env.action_space(agent).sample() # 4. 提交动作环境步进 env.step(action) # 5. 渲染非必须但可视化有助于调试 env.render() # 关闭环境 env.close()运行这段代码你会看到一个20个活塞智能体的窗口小球在随机动作下乱跳。这已经展示了AEC API的核心循环。你需要重点关注env.last()的返回值和action None的处理逻辑这是正确驱动循环的关键。4.2 使用SuperSuit进行环境预处理原始的环境观察通常是RGB像素并不适合直接喂给神经网络。我们需要进行标准化预处理。这就是SuperSuit的用武之地。它提供了一套与Gymnasium/PettingZoo完美兼容的Wrapper。假设我们想训练一个CNN策略常见的预处理流水线包括颜色通道调整与缩放将RGB转为灰度并缩小图像尺寸。帧堆叠将连续几帧堆叠起来以提供时间动态信息。归一化将像素值从[0, 255]缩放到[0, 1]或[-1, 1]。from pettingzoo.butterfly import pistonball_v6 import supersuit as ss def make_env(): env pistonball_v6.env(render_modergb_array, n_pistons20, continuousTrue) # 对每个智能体的观察空间应用相同的Wrapper # 1. 将图像缩放到84x84并转换为灰度通道数从3变为1 env ss.resize_v1(env, x_size84, y_size84) env ss.color_reduction_v0(env, modefull) # 2. 归一化像素值到 [0, 1] env ss.normalize_obs_v0(env, env_min0, env_max255) # 3. 帧堆叠使用最近4帧 env ss.frame_stack_v1(env, stack_size4) # 4. 将环境转换为并行API方便某些算法库使用 env ss.pettingzoo_env_to_vec_env_v1(env) # 5. 将所有智能体的环境堆叠成一个向量化环境实现并行模拟 env ss.concat_vec_envs_v1(env, 8, num_cpus4, base_classgymnasium) return env vec_env make_env()这段代码构建了一个强大的训练环境它同时并行运行8个环境实例每个实例的观察都被预处理成84x84x4的张量。num_cpus参数允许利用多核CPU加速模拟。SuperSuit的链式调用让复杂的预处理变得清晰易懂。4.3 与主流训练框架对接以CleanRL为例环境准备好了接下来就是选择算法进行训练。PettingZoo的API设计使其能轻松对接各种主流RL库。这里以CleanRL为例展示如何用PPO算法训练活塞球环境。CleanRL以其简洁、透明的单文件实现著称。PettingZoo官方提供了详细的 CleanRL教程 。其核心思想是将多智能体环境视为一个“大”的单智能体环境其中每个时间步这个“大智能体”需要为所有活跃的智能体输出动作。关键步骤包括观察拼接在每一步将所有智能体的观察经过预处理后拼接成一个大的观察向量或张量。策略网络输出策略网络输出一个大的动作分布再按智能体索引拆分成各自的动作。奖励与终止处理同样需要收集所有智能体的奖励和终止信号用于计算总回报和判断回合结束。由于代码较长这里概述其接口适配的关键点# 在训练循环中 obs, _ vec_env.reset() while not done: # 将当前观察可能已为向量输入策略网络得到动作、价值、对数概率 actions, values, logprobs agent.get_action_and_value(torch.Tensor(obs).to(device)) # 将动作Tensor转换为numpy数组并适配环境输入格式 next_obs, rewards, terminations, truncations, infos vec_env.step(actions.cpu().numpy()) # 计算折扣回报等... obs next_obsPettingZoo环境返回的terminations和truncations是字典需要根据算法库的要求进行处理例如对于向量化环境可能需要对所有智能体的终止状态进行逻辑“或”操作来判断整个环境是否结束。5. 构建自定义环境设计你的多智能体沙盒虽然内置环境丰富但自己的研究问题往往需要定制环境。PettingZoo提供了清晰的模板和规范引导你创建符合API标准的环境。5.1 环境类的基本结构一个自定义的AEC环境需要继承pettingzoo.AECEnv并实现一系列核心方法from pettingzoo import AECEnv from gymnasium import spaces import numpy as np class MyCustomEnv(AECEnv): metadata {render_modes: [human, rgb_array], name: my_env_v0} def __init__(self, render_modeNone, **kwargs): super().__init__() # 定义可能的智能体列表 self.possible_agents [agent_0, agent_1] # 定义动作空间和观察空间字典映射 self.action_spaces {agent: spaces.Discrete(3) for agent in self.possible_agents} self.observation_spaces {agent: spaces.Box(low0, high1, shape(4,)) for agent in self.possible_agents} self.render_mode render_mode def reset(self, seedNone, optionsNone): # 重置环境状态初始化agents列表设置第一个行动的agent等 self.agents self.possible_agents[:] self._agent_selector AgentSelector(self.agents) # 用于决定行动顺序 self.agent_selection self._agent_selector.next() # 初始化观察、奖励、终止等信息字典 self.observations {agent: np.zeros(4) for agent in self.agents} self.rewards {agent: 0 for agent in self.agents} self.terminations {agent: False for agent in self.agents} self.truncations {agent: False for agent in self.agents} self.infos {agent: {} for agent in self.agents} # 返回初始观察和info return self.observations, self.infos def step(self, action): # 如果当前选中的agent已终止/截断但step被调用应处理此情况 if self.terminations[self.agent_selection] or self.truncations[self.agent_selection]: self._was_dead_step(action) return # 1. 执行动作更新环境状态 agent self.agent_selection self._apply_action(agent, action) # 2. 计算奖励更新observations, rewards, terminations, truncations, infos self._calculate_rewards() self._update_observations() # 3. 选择下一个行动的agent self.agent_selection self._agent_selector.next() # 4. 累积奖励AEC特性奖励在agent被再次选中时才通过last()暴露 self._accumulate_rewards() def observe(self, agent): # 返回指定agent的当前观察 return self.observations[agent] def render(self): # 实现渲染逻辑 if self.render_mode human: # pygame 或 matplotlib 可视化 pass elif self.render_mode rgb_array: return np.zeros((400, 600, 3), dtypenp.uint8) def close(self): # 清理资源 pass5.2 关键实现细节与避坑指南_was_dead_step方法这是AECEnv的一个内置方法用于处理为已终止的智能体调用step的情况。在你的step方法开头检查并调用它是符合API规范的重要一步能避免许多难以调试的错误。奖励累积机制这是AEC API最需要理解的一点。在step中计算的奖励不会立即通过env.last()返回。相反它们被存储在self.rewards字典中。只有当_accumulate_rewards()被调用并且某个智能体再次被选为self.agent_selection时其累积的奖励才会被“结算”并通过last()返回。这样设计是为了处理智能体跳过回合或奖励延迟的情况。新手常常忘记在step末尾调用_accumulate_rewards()导致奖励永远无法被获取。空间定义action_spaces和observation_spaces必须在__init__中为所有possible_agents定义好。即使某个智能体中途加入或离开空间定义也不应改变。版本后缀类名和环境注册名必须包含_v0这样的版本后缀。当环境发生不兼容的变更时递增版本号如_v1这是PettingZoo保证实验可复现性的重要约定。5.3 注册环境以供使用为了让你的环境能像内置环境一样通过pettingzoo.mycustom导入你需要创建一个__init__.py文件并注册它# my_custom_env/__init__.py from .my_custom_env import MyCustomEnv def env(**kwargs): return MyCustomEnv(**kwargs)然后你就可以通过from pettingzoo.my_custom_env import env来使用它了。更详细的项目结构、测试和文档规范请参考PettingZoo官方的 环境创建教程 它提供了一个完整的模板项目。6. 常见问题排查与性能优化实录在实际使用和开发中你肯定会遇到各种问题。下面是我在项目中积累的一些典型问题及其解决方案。6.1 环境交互与API使用问题问题1env.step(action)后env.last()返回的奖励始终是0。排查这几乎总是因为忘记了AEC环境的奖励累积机制。检查你的step方法是否在最后调用了self._accumulate_rewards()。同时确保你在step中正确更新了self.rewards[agent]字典。解决在自定义环境的step方法末尾添加self._accumulate_rewards()。在使用环境时理解奖励是在智能体下一次被agent_iter选中的时候才通过last()给出的。问题2遇到AssertionError: agent died或类似错误。排查这通常是因为你在一个智能体已经terminated或truncated后仍然试图为它提供非None的动作。在AEC循环中必须严格检查if termination or truncation: action None env.step(action)解决确保你的策略逻辑在智能体结束后不再为其生成动作。在自定义环境中确保step方法开头有对死亡状态的处理调用_was_dead_step。问题3并行环境step时报错提示动作字典缺少某个智能体的键。排查并行API要求你为所有当前存活的智能体提供动作。env.agents属性列出了当前存活的智能体列表。你的动作字典必须包含这个列表中的所有键。解决# 获取当前存活的所有智能体 current_agents env.agents # 为每个存活智能体生成动作 actions {agent: policy(observation[agent]) for agent in current_agents} # 再调用 step env.step(actions)6.2 安装与依赖问题问题4安装pettingzoo[atari]或pettingzoo[butterfly]时失败提示ROM或依赖缺失。排查Atari环境需要ROM文件Butterfly环境依赖一些图形库如pygame、pymunk。Linux系统可能缺少底层开发库。解决Atari ROMsPettingZoo的Atari依赖ale-py它会自动处理大部分ROM。如果遇到许可问题可能需要手动接受ROM许可参考ale-py文档。系统依赖在Ubuntu/Debian上尝试sudo apt-get install python3-dev zlib1g-dev libjpeg-dev cmake swig。对于macOS确保Xcode命令行工具已安装。特定环境如果某个环境安装失败可以尝试单独安装其依赖或者查阅该环境子模块的README或Issues。问题5在Windows上运行Butterfly环境如pistonball出现显示问题或崩溃。排查PettingZoo对Windows的支持是社区贡献的可能不如Linux/macOS稳定。Butterfly环境重度依赖pygame进行渲染在Windows上可能遇到线程或后端问题。解决尝试设置环境变量SDL_VIDEODRIVERwindib或SDL_VIDEODRIVERdirectx。在创建环境时使用render_modergb_array而不是human然后使用matplotlib等库来显示图像避开pygame的直接窗口渲染。考虑在WSL2Windows Subsystem for Linux中运行这通常能获得与原生Linux一致的体验。6.3 训练与性能优化问题6多智能体环境模拟速度慢成为训练瓶颈。排查多智能体环境本身计算量就大如果还用Python循环逐个智能体处理速度会更慢。解决向量化使用supersuit.concat_vec_envs_v1创建多个环境实例并行运行。这是提升吞吐量最有效的方法能充分利用多核CPU。使用并行API如果环境逻辑允许使用并行APIparallel_env通常比AEC API效率更高因为减少了Python层面的循环开销。优化自定义环境检查你的step和observe方法。尽量使用NumPy的向量化操作避免低效的Python循环。对于复杂物理计算考虑用numba加速或寻找更高效的底层库。观察预处理使用SuperSuit的Wrapper在环境层面完成图像缩放、灰度化等操作比在神经网络的第一层做这些操作更高效。问题7智能体数量动态变化的环境如何管理经验回放排查这是多智能体RL的一个核心挑战。传统的经验回放缓冲区假设数据维度固定。解决填充与掩码最常见的策略是使用“填充”padding和“掩码”masking。设定一个最大智能体数量不足的用零填充并提供一个二进制掩码来指示哪些位置是有效的真实数据。在训练时损失函数要乘以掩码忽略填充部分的影响。基于图的回放对于智能体关系可以用图表示的环境可以考虑使用图神经网络GNN和对应的图结构经验回放。使用支持多智能体的框架一些高级RL库如EPyMARL、MALib或Ray的RLLib多智能体模块已经内置了对可变数量智能体的支持封装了这些复杂性。7. 生态整合与进阶资源PettingZoo不是一个孤立的库它深深嵌入在Farama基金会构建的强化学习生态中。了解这个生态能让你如虎添翼。GymnasiumPettingZoo的单智能体基石。两者的API设计一脉相承许多概念如空间定义、Wrapper是相通的。熟悉Gymnasium能让你更快上手PettingZoo。SuperSuit如前所述这是环境预处理的瑞士军刀。除了常见的图像包装器它还提供如帧差分、动作重复、奖励裁剪等实用功能。强烈建议在任何严肃的训练项目中使用它而不是自己重复造轮子。Shimmy这是Farama提供的兼容层让你可以轻松地将其他流行的环境API如DeepMind Control Suite、OpenAI Gym旧版、Atari等转换成Gymnasium/PettingZoo格式。如果你有旧代码或想使用特定环境Shimmy能提供无缝对接。主流算法库CleanRL追求极致简洁和透明适合学习、研究和快速原型。官方提供了与PettingZoo对接的详细教程。Tianshou一个模块化、高性能的PyTorch RL库对多智能体有很好的支持其MultiAgentPolicyManager可以方便地管理多策略。Ray RLLib工业级分布式RL库对大规模多智能体训练支持最好。它可以将不同的智能体分配到不同的计算节点上支持复杂的异构策略训练。MALib专注于多智能体学习的库内置了许多先进的多智能体算法如MAPPO、QMIX等并与PettingZoo深度集成。选择哪个算法库取决于你的需求研究算法细节用CleanRL平衡灵活与性能用Tianshou进行超大规模训练用RLLib专注于多智能体前沿算法用MALib。最后多智能体强化学习是一个快速发展的领域挑战与乐趣并存。PettingZoo通过提供一个稳定、统一的环境接口极大地降低了入门和研究的工程门槛。我个人的体会是初期多花时间彻底理解AEC和并行API的差异、奖励机制以及环境封装后期会节省大量的调试时间。当你能够随心所欲地创建自己的多智能体世界并看着智能体在其中从混乱走向协作或竞争时那种成就感是单智能体环境无法比拟的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…