神经进化算法实战:从零构建AI Flappy Bird游戏智能体

news2026/5/12 18:13:57
1. 项目概述当AI学会玩像素小鸟如果你玩过那个让人又爱又恨的《Flappy Bird》一定对那只在绿色水管间反复横跳的小鸟记忆犹新。但你想过吗如果让一群“数字小鸟”自己学会玩这个游戏会是什么景象这正是“AI Flappy Bird”这个项目在做的事。它不是一个普通的游戏复刻而是一个活生生的、基于神经进化算法的AI实验场。在这里上百只由神经网络驱动的虚拟小鸟通过模拟“自然选择”的过程从最初的“出生即坠机”到最终成为“水管穿梭大师”整个过程完全自主无需任何人类编写的游戏策略。对于想入门AI、机器学习尤其是对“进化算法”和“神经网络”如何协同工作感到好奇的开发者、学生或爱好者来说这个项目提供了一个绝佳的、可视化的学习案例。它用最直观的方式告诉你智能如何从零开始通过简单的规则迭代“生长”出来。2. 核心架构神经进化如何驱动游戏这个项目的核心是将两个经典的AI概念——神经网络和遗传算法——巧妙地结合形成了一个完整的“神经进化”系统。它不是教AI具体的规则而是为AI搭建一个能够自我学习和进化的环境框架。2.1 系统总览从感知到进化的闭环整个系统运行在一个高效的闭环中我们可以将其理解为一场持续进行的“数字达尔文主义”实验。其核心流程如下初始化种群程序启动时会随机生成一个由150只小鸟组成的初始种群。每只小鸟的“大脑”都是一个全新的、权重完全随机的神经网络。此时的小鸟没有任何游戏知识行为完全随机。环境交互与评估所有小鸟同时开始游戏。它们各自的神经网络实时接收游戏状态信息如小鸟位置、下一个水管的距离等并输出“是否振翅”的决策。游戏引擎负责处理物理碰撞、计分和渲染。当最后一只小鸟撞上水管或飞出屏幕一代结束。适者生存选择系统根据每只小鸟的表现存活时间、通过水管数量计算一个“适应度”分数。分数越高代表其基因神经网络权重越优秀。接下来系统会依据适应度以更高的概率选择优秀的个体作为“父母”。繁衍与变异遗传操作被选中的“父母”的神经网络权重会通过“交叉”操作进行混合产生“后代”的权重。同时这个过程会引入小概率的“变异”即随机微调某些权重值以增加种群的多样性和探索新策略的可能性。迭代进化用新生成的后代神经网络权重替换掉旧的种群通常会保留少量最优秀的个体直接进入下一代称为“精英保留”从而形成新一代的小鸟。然后流程回到第2步开启新一轮的生存挑战。这个循环不断重复每一代都在前一代的基础上进行优化。优秀的决策模式如“在距离水管特定高度时振翅”会通过权重被保留和强化而糟糕的策略则被淘汰。经过几十代的进化整个种群的游戏水平会实现从零到精通的飞跃。2.2 神经网络小鸟的“微型决策大脑”每只小鸟的智能核心是一个前馈神经网络。它负责将游戏世界的实时状态映射为一个简单的二选一动作振翅Flap或不振翅Do Nothing。网络结构详解6-12-1架构 这是一个典型的三层结构输入层、隐藏层、输出层比原始《Flappy Bird》AI项目中常见的4输入网络更为精细。输入层6个节点这是小鸟的“感官系统”负责接收并标准化处理6个关键的游戏状态特征。输入值的范围通常被归一化到[0, 1]或[-1, 1]之间以利于网络稳定学习。小鸟的垂直位置Y坐标标准化后的小鸟在画布上的高度。网络需要知道自己是处于屏幕上方还是下方。小鸟的垂直速度当前是向上飞还是向下坠以及速度的快慢。这是判断重力影响和运动趋势的关键。到下一个水管缺口的水平距离小鸟距离下一个需要穿越的水管还有多远。这是判断“何时”需要做出反应的核心依据。下一个水管缺口的中心点垂直位置缺口在屏幕上的Y坐标。这是判断“何处”是安全通道的目标。小鸟与缺口中心的高度差直接计算小鸟Y坐标 - 缺口中心Y坐标。这个值直观地告诉网络当前的位置偏差正值表示小鸟在缺口上方需要下降负值则表示在下方需要上升。距离上一次振翅的帧数记录自上次振翅动作过去了多少游戏帧。这个特征能防止网络陷入“疯狂振翅”的无效策略鼓励其学习有节奏的、节省能量的飞行模式。隐藏层12个节点这是网络的“思考中枢”。12个神经元意味着有12个不同的“特征探测器”它们以复杂的非线性方式组合输入信息。例如某个隐藏神经元可能专门学习“当距离水管很近且高度差为负时”这种复合情况。我们使用ReLU激活函数其公式为f(x) max(0, x)。它的好处是计算简单能有效缓解梯度消失问题并引入非线性使网络能够拟合更复杂的决策边界。输出层1个节点决策的终点。这里使用Sigmoid激活函数其公式为f(x) 1 / (1 e^(-x))。它将隐藏层的输出压缩到(0, 1)区间。在代码中我们通常会设定一个阈值如0.5。如果输出值大于0.5则小鸟执行振翅动作反之则保持当前状态。前向传播计算示例 假设某一帧小鸟的归一化输入向量为[0.5, 0.2, 0.8, 0.6, 0.1, 0.3]。该向量与输入层-隐藏层之间的权重矩阵6x12相乘得到隐藏层的加权和。对加权和结果应用ReLU函数将所有负值置零得到隐藏层的激活值向量如[0.23, 0.67, 0.89, ...]。将隐藏层激活值向量与隐藏层-输出层之间的权重矩阵12x1相乘得到一个标量值。对该标量值应用Sigmoid函数。假设结果为0.68。由于0.68 0.5神经网络决策为“振翅”。小鸟便会在这一帧向上跳跃。实操心得输入特征工程设计输入特征是神经网络项目成功的关键。最初版本可能只用了小鸟位置和最近水管的距离。而本项目增加的“高度差”和“上次振翅帧数”是极大的优化。高度差让网络无需自己计算偏差降低了学习难度“振翅帧数”则有效防止了网络输出高频振荡信号即每帧都试图振翅让学习过程更稳定。在实际构建类似AI游戏代理时多从“智能体需要知道什么才能做出好决策”的角度思考精心设计输入特征往往比单纯增加网络层数或神经元数量更有效。2.3 遗传算法驱动进化的“自然选择之手”如果说神经网络是小鸟的大脑那么遗传算法就是塑造这些大脑的进化法则。它模拟了生物进化中的选择、交叉和变异。适应度函数这是进化的“指挥棒”定义了什么是“好”。在本项目中适应度通常设计为适应度 (通过的管道数量)^2 (存活时间)^1。平方项确保能通过更多管道的小鸟获得指数级增长的奖励从而被强烈选择。这引导种群快速追求通过管道而非仅仅存活。选择策略项目采用了混合选择策略以平衡收敛速度和种群多样性。锦标赛选择随机选取k只小鸟如k4让它们中适应度最高的胜出成为父代。重复此过程直至选够所需数量。这种方法给适应度不高但拥有独特基因的小鸟一定机会有助于维持多样性。轮盘赌选择每个个体被选中的概率与其适应度占总适应度的比例成正比。这是一种经典方法能确保最优秀的个体有高概率被选中。交叉重组这是组合优秀基因的方式。从两个父代神经网络中随机选择一种交叉策略单点交叉随机选择一个权重位置将父代A该位置前的所有权重和父代B该位置后的所有权重组给子代。均匀交叉对每一个权重都抛一次“硬币”随机决定它来自父代A还是父代B。混合交叉子代的某个权重是父代A和父代B对应权重的加权平均值如子代权重 0.7*A权重 0.3*B权重。变异这是创新的源泉防止算法陷入局部最优解。对于子代的每一个权重都有一个小概率如15%发生变异。变异通常是在原权重上加一个服从高斯分布正态分布的随机小扰动。本项目还实现了自适应变异率当种群适应度停滞不前时略微提高变异率以鼓励探索当适应度快速提升时则降低变异率以利于利用当前好基因。精英主义为了避免优秀基因在交叉和变异中丢失每一代都会无条件保留适应度最高的前10%的个体直接复制到下一代。这保证了进化不会倒退。3. 工程实现与代码深度解析理解了原理我们来看看如何用代码实现这个系统。项目使用原生JavaScript和HTML5 Canvas结构清晰非常适合学习。3.1 核心类与数据结构设计整个项目围绕几个核心类构建职责分明Bird类代表一只小鸟。属性位置、速度、加速度重力、是否存活、神经网络NeuralNetwork对象、适应度分数。方法flap()振翅、update()根据重力更新位置、think(pipes)利用神经网络决策、calculateFitness()计算适应度。NeuralNetwork类神经网络的具体实现。属性input_nodes,hidden_nodes,output_nodes以及对应的权重矩阵weights_ih输入到隐藏和weights_ho隐藏到输出偏置向量。方法feedforward(input_array)前向传播计算输出、copy()复制网络用于精英保留、crossover(parent2)与另一个网络交叉、mutate(rate)按概率变异权重。Pipe类代表上下水管对。属性位置、缺口中心位置、缺口高度、宽度、是否已被某只小鸟通过用于计分。方法update()向左移动、draw(ctx)绘制到画布、offscreen()判断是否移出屏幕左侧。Population类管理整个鸟群和进化过程。属性birds数组generation当前代数bestBird历史最佳小鸟。方法update()更新所有存活小鸟、naturalSelection()执行选择、交叉、变异生成新一代、calculateFitness()计算种群中所有小鸟的适应度。3.2 关键代码段剖析让我们深入几个最关键的函数看看逻辑是如何落地的。1. 神经网络的前向传播 (NeuralNetwork.feedforward)feedforward(input_array) { // 将输入数组转换为矩阵对象假设使用简单的数组或矩阵库 let inputs Matrix.fromArray(input_array); // 计算隐藏层信号 inputs * weights_ih bias_h let hidden Matrix.multiply(this.weights_ih, inputs); hidden.add(this.bias_h); // 应用ReLU激活函数 hidden.map(this.relu); // 计算输出层信号 hidden * weights_ho bias_o let output Matrix.multiply(this.weights_ho, hidden); output.add(this.bias_o); // 应用Sigmoid激活函数得到最终输出 output.map(this.sigmoid); // 返回输出值一个0到1之间的数 return output.toArray()[0]; } // ReLU 激活函数 relu(x) { return Math.max(0, x); } // Sigmoid 激活函数 sigmoid(x) { return 1 / (1 Math.exp(-x)); }2. 遗传算法的核心——生成新一代 (Population.naturalSelection)naturalSelection() { let newBirds []; let maxFitness this.getMaxFitness(); // 1. 精英保留直接复制适应度最高的前10% for (let i 0; i this.elitismCount; i) { let eliteBird this.birds[i]; // 假设birds已按适应度降序排序 newBirds.push(eliteBird.copy()); // 复制神经网络 } // 2. 通过选择、交叉、变异生成剩余90%的个体 for (let i 0; i this.popSize - this.elitismCount; i) { // 选择父代这里以轮盘赌为例 let parentA this.selectParent(); let parentB this.selectParent(); // 交叉生成子代神经网络 let childBrain parentA.brain.crossover(parentB.brain); // 变异 childBrain.mutate(this.mutationRate); // 创建新的小鸟赋予其子代大脑 let childBird new Bird(); childBird.brain childBrain; newBirds.push(childBird); } // 用新一代替换旧一代 this.birds newBirds; this.generation; } // 轮盘赌选择 selectParent() { // 计算总适应度 let fitnessSum this.birds.reduce((sum, bird) sum bird.fitness, 0); let rand Math.random() * fitnessSum; let runningSum 0; for (let bird of this.birds) { runningSum bird.fitness; if (runningSum rand) { return bird; } } // 保底返回最后一只理论上不会执行到这里 return this.birds[this.birds.length - 1]; }3. 小鸟的决策过程 (Bird.think)think(pipes) { // 1. 找到最近且在前方的水管 let closestPipe null; let closestDistance Infinity; for (let pipe of pipes) { let distance pipe.x pipe.width - this.x; if (distance 0 distance closestDistance) { // 只关心前方水管 closestPipe pipe; closestDistance distance; } } if (!closestPipe) return; // 没有水管无需决策 // 2. 构建输入向量6个特征 let inputs []; inputs[0] this.y / canvas.height; // 归一化Y位置 inputs[1] this.velocity / 10; // 归一化速度假设最大速度10 inputs[2] closestDistance / canvas.width; // 归一化水平距离 inputs[3] closestPipe.gapCenterY / canvas.height; // 归一化缺口中心 inputs[4] (this.y - closestPipe.gapCenterY) / canvas.height; // 归一化高度差 inputs[5] this.framesSinceFlap / 60; // 归一化帧数假设1秒60帧 // 3. 前向传播获取决策 let decision this.brain.feedforward(inputs); // 4. 执行动作阈值判断 if (decision 0.5) { this.flap(); this.framesSinceFlap 0; // 重置振翅计时器 } else { this.framesSinceFlap; } }注意事项归一化的重要性在think()函数中所有输入特征都被归一化到0到1之间或-1到1。这是神经网络训练的黄金法则。未经归一化的原始数据如像素坐标可能是0-400速度可能是-10到10尺度差异巨大会导致权重更新不稳定训练效率极低甚至失败。务必确保输入数据处于相近的数值范围内。3.3 可视化与监控系统项目的另一大亮点是强大的实时可视化这对于理解和调试进化过程至关重要。游戏主画面使用Canvas绘制小鸟、水管、背景。最佳小鸟会被高亮显示如描边或不同颜色。实时神经网络可视化在画布角落动态绘制最佳小鸟的神经网络图。节点的大小或颜色根据其激活值实时变化如使用从蓝到红的渐变色连接线的粗细代表权重绝对值的大小。这让你能直观地“看到”小鸟在思考什么。数据分析仪表盘通过HTML5的canvas或结合SVG/Chart.js库绘制多种实时图表适应度趋势图展示每一代种群最高适应度、平均适应度的变化观察学习曲线。存活率图表显示每一代中小鸟的平均存活时间或通过水管数量。基因多样性图通过计算种群中神经网络权重的方差或平均距离来监控多样性是否在丧失早熟收敛。决策置信度统计输出层Sigmoid值的分布如果值都集中在0或1附近说明网络决策很“自信”如果集中在0.5附近则说明网络还在“犹豫”。4. 参数调优与高级策略要让AI高效学习仅仅实现算法还不够参数调优和策略选择是关键。这里分享一些从项目中提炼出的经验。4.1 核心参数调优指南在main.js或配置文件中以下参数对进化速度和最终性能有决定性影响参数默认值作用与影响调优建议POP_SIZE150每代种群大小。越大越好但受性能限制。更大的种群意味着更多的并行探索更不容易陷入局部最优但计算和渲染开销也更大。建议在100-500之间根据机器性能调整。MUTATION_RATE0.15每个权重发生变异的概率。动态调整策略更佳。初期前20代可稍高如0.2鼓励探索后期可降低如0.05专注于优化已有好策略。本项目中的自适应变异率是更优方案。ELITISM_RATE0.1直接保留到下一代的精英比例。通常设置在5%-20%。太高的精英率会减少多样性导致早熟太低则可能丢失优秀基因。0.1是一个稳健的起点。PIPE_GAP200水管上下缺口的高度像素。影响游戏难度。越小越难。可以设置为固定值也可以实现动态难度根据最近几代的平均表现动态调整缺口大小保持挑战性。HIDDEN_NODES12隐藏层神经元数量。代表模型容量。对于Flappy Bird这种简单游戏8-16个已经足够。太少学不会复杂策略太多可能导致过拟合在训练集上表现好但泛化能力差和训练变慢。GRAVITY/JUMP0.6 / -12物理参数重力加速度和振翅向上的初速度。决定了游戏的“手感”。JUMP的绝对值需要大于GRAVITY的累积效应小鸟才能飞起来。调整这两个值可以改变游戏的整体节奏。4.2 超越基础可尝试的高级改进如果你已经让基础版本运行良好可以尝试以下进阶修改这能让你更深入地理解神经进化算法的潜力增加输入特征下一个水管的宽度虽然固定但让网络知道也无妨。连续多个水管的距离和位置让小鸟具备一定的“前瞻性”而不是只盯着最近的一个。小鸟的当前加速度结合速度更精确地描述运动状态。改进网络结构增加一个隐藏层例如6-8-4-1结构。更深的网络理论上能学习更抽象的特征但对于此简单任务可能不必要且会增加训练难度。尝试不同的激活函数隐藏层可以尝试Leaky ReLUf(x)max(0.01x, x)防止“神经元死亡”输出层可以尝试Tanh函数输出范围-1到1配合不同的动作编码。增强遗传算法物种形成借鉴NEAT算法根据网络结构的相似性将种群划分为不同物种物种内部竞争避免一个优势物种过早统治整个种群而扼杀创新。交叉策略自适应根据父母双方的适应度差异动态选择交叉策略均匀交叉或单点交叉。更复杂的适应度函数除了通过水管数可以加入“飞行平稳度”奖励速度变化小或“节能”奖励振翅次数少引导进化出更优雅的飞行策略。环境与游戏机制改进动态环境让水管的间距、高度随机范围随时间或代数变化考验AI的适应能力。添加噪音在神经网络的输入或输出中加入微小随机噪声可以提高学习到的策略的鲁棒性。5. 常见问题、调试技巧与性能优化在实际运行和修改代码的过程中你肯定会遇到各种问题。以下是一些常见坑点及解决方案。5.1 学习失败问题排查现象可能原因解决方案种群适应度始终为零或极低小鸟完全不会飞1. 神经网络权重初始化不当如全为零或过大。2. 变异率过高导致任何好策略都无法稳定遗传。3. 输入特征未归一化导致梯度爆炸或消失。4. 适应度函数设计有误无法有效区分好坏。1. 使用Xavier或He权重初始化方法。2. 大幅降低初始变异率如0.01并启用自适应变异。3. 检查think()函数确保所有输入值被映射到合理范围如[0,1]。4. 简化适应度函数先确保能奖励“存活时间”再增加“通过水管”的奖励。前几代有进步但很快陷入平台期分数不再增长1. 种群多样性丧失早熟收敛。2. 精英保留率太高挤占了新个体的空间。3. 变异率太低缺乏创新。4. 游戏难度对于当前种群来说已达上限。1. 引入锦标赛选择或物种形成来维持多样性。2. 降低精英率如从0.1降到0.05。3. 提高变异率或当适应度停滞时临时增加“冲击性”大变异。4. 尝试动态增加游戏难度如缩小水管缺口。小鸟行为怪异如疯狂振翅或完全不振翅1. 输出层Sigmoid函数的阈值设置不当。2. 缺少“防抖动”或“冷却”机制。3. 输入特征中缺少“上次振翅时间”导致网络陷入高频振荡。1. 调整决策阈值如从0.5调到0.7或改用基于概率的采样以Sigmoid输出值为振翅概率。2. 在代码中强制设置振翅的最小间隔如至少间隔5帧。3. 确认已将“距离上次振翅的帧数”作为输入特征之一。可视化图表显示神经网络所有节点激活值几乎不变1. 权重初始化值太小导致信号在传播中衰减殆尽。2. 使用了错误的激活函数如在前层用了Sigmoid导致梯度消失。3. 输入值范围异常如全为0。1. 检查权重初始化代码确保初始权重是符合高斯分布的小随机数如均值为0标准差为0.1。2. 隐藏层坚持使用ReLU及其变体。3. 在think()函数中打印输入向量确认其值在预期范围内变化。5.2 性能优化技巧当种群规模POP_SIZE较大或网络较复杂时性能可能成为瓶颈。以下是一些优化思路矩阵运算优化神经网络的核心是矩阵乘法。使用朴素的嵌套循环性能很差。可以考虑使用JavaScript的TypedArray如Float64Array代替普通数组存储矩阵数据。将小的、频繁调用的矩阵运算如点积手动展开循环或利用一些线性代数库的优化。对于非常大的种群可以分批进行前向传播计算。渲染优化Canvas渲染是主要性能消耗点。离屏渲染对于静态或变化不频繁的元素如背景、云朵可以预先绘制到另一个离屏Canvas上每帧直接复制过来避免重复绘制。减少绘制调用例如将所有水管在一次beginPath()和fill()调用中绘制完毕而不是每根水管单独调用。按需渲染神经网络可视化可以每5帧或10帧更新一次神经网络可视化图而不是每帧都更新。逻辑更新与渲染解耦游戏逻辑更新如小鸟位置、碰撞检测的帧率如60Hz和画面渲染的帧率可以分离。即使画面卡顿进化模拟也可以在后台继续高速运行。这可以通过requestAnimationFrame控制渲染用setInterval或Web Worker进行逻辑计算来实现。5.3 实验与记录强烈建议在修改任何参数或算法后做好实验记录。可以简单记录以下信息实验标识日期、版本或描述。修改的参数例如MUTATION_RATE0.1, ELITISM0.2。关键结果达到平均分1000所需的代数、历史最高分、最终种群的适应度分布。观察到的现象例如“前50代进步快后陷入平台期”“出现了奇特的上下盘旋飞行策略”。通过系统性的实验和对比你才能真正理解每个参数和算法组件对进化过程的影响从而获得调优的直觉。这个从“代码能跑”到“理解为何这样跑得好”的过程正是AI项目实践中最宝贵的收获。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2606835.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…