当前位置: 首页 > article >正文

游戏树搜索与优化策略:Alpha-Beta剪枝及其实例分析

1.Alpha-Beta搜索

Alpha-Beta 搜索是一种用于对抗性游戏(比如象棋、围棋)的智能算法,目的是帮助计算机快速找到“最优走法”,同时避免不必要的计算。它的核心思想是:通过剪掉明显糟糕的分支,大幅减少需要计算的步数

通俗理解:

假设你和朋友下棋,你在思考下一步时,会脑补各种可能的走法:

  1. 如果你走A,朋友可能会走A1、A2、A3...,然后你又要回应,最终可能赢或输。

  2. 如果你走B,朋友可能会走B1、B2...,依此类推。

Alpha-Beta 的作用就是帮你快速排除明显不靠谱的选项。比如:

  • 当你分析走A时,发现朋友只要走A1就能轻松击败你,那么A这条路直接放弃,不用再分析A2、A3了。

  • 接着分析走B,如果发现无论朋友怎么应对,你都能赢,那么直接选B,不用再分析剩下的选项了。

这就是“剪枝”——砍掉无用的分支,节省时间。


核心规则:

  1. 两个角色

    • 你(最大化玩家):想选对自己最有利的走法(比如最高分数)。

    • 对手(最小化玩家):会选对你最不利的走法(比如最低分数)。

  2. 两个关键值

    • Alpha:当前你能保证的“最差下限”。比如你已经找到一条路至少能得5分,那么Alpha=5。

    • Beta:当前对手能允许的“最差上限”。比如对手已经找到一条路最多让你得3分,那么Beta=3。

  3. 剪枝条件

    • 如果在分析某一步时,发现它的结果比对手能接受的最差值还差(比如你算出这一步最多得2分,但对手已经有办法限制你到3分),那么直接放弃这条路,不用再往下算了!


举个栗子🌰:

假设你在下棋,有3种走法(A、B、C):

  1. 分析A:对手回应后,你最多得3分。

  2. 分析B:对手回应后,你至少能得5分。这时更新Alpha=5。

  3. 分析C:如果发现对手某一步能让你得分≤4分(而你的Alpha已经是5),那么直接放弃C的分支,因为对手绝不会让你得5分以上。

最终,你会选择B,因为它保证了至少5分,而其他分支要么分更低,要么被剪掉了。


总结:

  • Alpha-Beta 是“聪明穷举”:不盲目计算所有可能,而是边算边排除垃圾选项。

  • 核心是剪枝:通过Alpha和Beta的边界值,提前终止无用的计算。

  • 效果:让AI在复杂游戏中也能快速找到最优解!

就像考试时做选择题:先排除明显错误的选项,再仔细分析剩下的,省时又高效!

先给大家po一道例题

 我们为了辨识,将树结构变成下述标记:

         MAX(根节点)  
      /                           \  
   MIN₁(左)               MIN₂(右)  
  /           \               /          |        \          \  
MAX₁   MAX₂     MAX₃  MAX₄  MAX₅  MAX₆  
0  4        5 1         2 5      1 3       4 6      7 3  

遍历顺序与剪枝分析(假设从左到右遍历):

  1. 根节点(MAX)

    • α = -∞, β = +∞

    • 先处理左子节点 MIN₁

  2. MIN₁(左)

    • 继承父节点的α = -∞, β = +∞

    • 处理第一个子节点 MAX₁(叶子值0和4):

      • MAX₁返回最大值4

      • MIN₁当前β = min(+∞, 4) = 4

    • 处理第二个子节点 MAX₂(叶子值5和1):

      • MAX₂返回最大值5

      • MIN₁最终值 = min(4, 5) = 4

    • 根节点更新α = max(-∞, 4) = 4

  3. 根节点(MAX)继续处理右子节点 MIN₂(右)

    • 当前α = 4, β = +∞

    • MIN₂的α = 4, β = +∞

    • 处理第一个子节点 MAX₃(叶子值2和5):

      • MAX₃返回5

      • MIN₂当前β = min(+∞, 5) = 5

    • 处理第二个子节点 MAX₄(叶子值1和3):

      • MAX₄返回3

      • MIN₂更新β = min(5, 3) = 3

      • 此时父节点的α=4 ≥ β=3,触发剪枝!

      • 后续子节点(MAX₅、MAX₆)无需评估

  4. MIN₂最终值 = 3

    • 根节点比较左分支值4和右分支值3,选择最大值4

剪枝标注

  • MIN₂的MAX₅(叶子4,6)和MAX₆(叶子7,3)被剪枝,因为父节点MIN₂的β=3已小于根节点的α=4。

最终结果

  • 根节点值 = 4(来自左分支MIN₁)

  • 剪枝节点

      MAX (α=4, β=+∞)  /                 \  MIN₁(4)               MIN₂(3)  
/       \          /    |    \    \  
MAX₁(4) MAX₂(5)  MAX₃(5) MAX₄(3) [剪枝] [剪枝]
0⭕4⭕ 5⭕1⭕  2⭕5⭕ 1⭕3⭕ 4❌6❌ 7❌3❌
- **⭕**:被评估的叶子节点  
- **❌**:因剪枝未评估的节点  ---### 关键步骤说明  
1. **左分支(MIN₁)**:  - MAX₁和MAX₂均被完整遍历,MIN₁返回4。  
2. **右分支(MIN₂)**:  - 当MAX₄返回3后,MIN₂的β=3 < 根节点α=4,触发剪枝。  - 剪枝节省了对MAX₅(4,6)和MAX₆(7,3)的遍历。  
3. **剪枝条件**:  - 对于MIN节点,若子节点返回值 ≤ 父节点的α,则后续分支无需评估。  - 此处MIN₂的β=3 < α=4,直接剪枝。  **结论**:Alpha-Beta剪枝在此树中成功跳过了4个叶子节点的计算。

源码:

import numpy as np
import argparseMIN_EVAL = -1000000
MAX_EVAL =  1000000def main():parser = argparse.ArgumentParser()parser.add_argument('--g',type=str,default='ttt',help= 'ttt, con3 or con4')parser.add_argument('--h',type=str,default='1',help= 'human turn (1 or 2)')args = parser.parse_args()if args.g == 'ttt':from ttt import Gamegame = Game()elif args.g == 'con3':from con import Gamegame = Game(3)elif args.g == 'con4':from con import Gamegame = Game(4)else:print('Unknown Game:',args.g)exit(1)if args.h == '2':is_human = (False,False,True)else:is_human = (False,True,False)move = np.zeros(game.MAX_MOVE+1,dtype=np.int32)best_move = np.zeros(game.MAX_MOVE+1,dtype=np.int32)#is_human = (False,True,False)game_status = game.STILL_PLAYINGplayer = 2m = 0while m < game.MAX_MOVE and game_status == game.STILL_PLAYING:m += 1player = 3-playerif is_human[player]:game.print_board()move[m] = input('Enter move: ')while not game.is_legal_move( player, move[m] ):move[m] = input('Enter move: ')else:alphabeta(player,m,game,MIN_EVAL,MAX_EVAL,best_move,game.MAX_DEPTH)move[m] = best_move[m]game_status = game.make_move( player, move[m] )game.print_board()if game_status == game.WIN:print('Win for player',player)elif game_status == game.LOSS:print('Loss for player',player)elif game_status == game.DRAW:print('Draw')#**********************************************************
#   Negamax formulation of alpha-beta search
#
def alphabeta( player, m, game, alpha, beta, best_move, depth ):best_eval = MIN_EVALif game.game_won( 3-player ):     # lossreturn -1000 + m  # better to win faster (or lose slower)if game.game_drawn( 3-player):return 0if depth == 0:return game.board_eval( player )this_move = -1for c in game.move_range(): #range( 1, 10 ):if game.is_legal_move( player, c ):this_move = cgame.make_move( player, this_move )this_eval = -alphabeta(3-player,m+1,game,-beta,-alpha,best_move,depth-1)game.undo_move( player, this_move )if this_eval > best_eval:best_move[m] = this_movebest_eval = this_evalif best_eval > alpha:alpha = best_evalif alpha >= beta:   # cutoffreturn( alpha )if this_move < 0:   # no legal movesreturn( 0 )     # DRAWelse:return( alpha )if __name__ == '__main__':main()

2.井字棋(Tic-Tac-Toe)

 

1. 可能的游戏总数

井字棋的合法游戏总数约为 255,168 种。虽然理论上存在 9!=362,8809!=362,880 种落子顺序,但以下因素大幅减少了实际数量:

  • 提前终止:当一方连成三子时游戏结束。

  • 对称性:许多路径通过旋转或镜像视为等效。

  • 无效路径:某些落子顺序因违反规则(如重复落子)被排除。


2. 对称性简化后的深度2游戏树

从空棋盘开始,深度2的树结构如上(合并对称情况):

深度0(根节点):空棋盘
深度1(MAX层):X的三种对称等效开局:

  1. (Corner)

  2. (Edge)

  3. 中心(Center)

深度2(MIN层):O的回应(合并对称位置):

  • 若X在角

    • O可选择:中心对角角(对称合并后仅需计算一次)。

  • 若X在边

    • O可选择:中心相邻角对边

  • 若X在中心

    • O必须选择(对称合并后仅需计算一次)。


3. 评估函数与深度2节点的评估值

评估函数定义为:

其中:

  • X2(s):棋盘中有两条X且无O的行/列/对角线数量。

  • X1(s):棋盘中有一条X且无O的行/列/对角线数量。

  • O2(s) 和 O1(s)) 同理计算O的威胁。

示例计算(X在角,O在中心)

  • X2=1(对角线和右侧边各有一条潜在连线,但O在中心阻断一条,实际有效为1)。

  • X1=2(左侧边和上边各一条)。

  • O2=0,O1=1(中心O所在行/列/对角线)。

  • Eval = 3×1 + 2 − (3×0 + 1) = 4

其他深度2节点的评估值类似计算,最终结果为:

  • X在角 + O在中心 → Eval=4

  • X在角 + O在边 → Eval=3

  • X在中心 + O在角 → Eval=2


    4. Minimax算法与回传值

步骤

  1. 深度2(叶子节点):直接使用评估函数计算值。

  2. 深度1(MIN层):选择子节点中的最小值。

  3. 深度0(MAX层):选择子节点中的最大值。

示例(以X在角为例):

  • O在中心 → Eval=4

  • O在边 → Eval=3

  • O在对角角 → Eval=5

  • MIN层选择最小值3(O最优回应为边)。

  • 其他开局同理,最终根节点选择最大回传值(如X在角时值为3,X在中心时值为2)。

最佳开局:选择,因其回传值最高(3)。


5. Alpha-Beta剪枝

剪枝条件

  • 在MIN层,若某个子节点的值 ≤ 当前α,则剪枝后续分支。

  • 在MAX层,若某个子节点的值 ≥ 当前β,则剪枝后续分支。

示例(X在角,O按最优顺序回应):

  1. MIN层首先评估O在边(Eval=3),此时父节点(MAX层)的α=3。

  2. 后续评估O在对角角(Eval=5),由于5 > α=3,更新α=5。

  3. 最后评估O在中心(Eval=4),无需剪枝。

  4. 若子节点顺序为[中心→边→对角角],当O在中心返回4后,后续分支可能因α=4 ≥ β=3触发剪枝。

剪枝节点:在非最优顺序下,部分分支(如O在中心后的其他对称位置)可能被跳过。


6. 利用对手失误的最佳开局

即使Minimax认为所有开局平局,但若对手犯错,角开局更具优势:

  • 角开局的潜在威胁:X在角后,可形成两条潜在连线(如对角线和边)。

  • 对手失误示例:若O未占据中心,X可通过下一步占据中心形成双威胁,迫使O无法防守。

  • 其他开局(如边或中心)威胁较少,对手更易应对。


总结

  • 最佳开局:角(对称合并后唯一最优选择)。

  • 关键策略:通过评估函数量化威胁,利用Minimax和Alpha-Beta剪枝优化搜索。

  • 实战意义:理解对称性与剪枝条件可大幅减少计算量,同时针对对手失误设计陷阱。

 源码:

import numpy as npclass Game:def __init__(self):self.ILLEGAL_MOVE  =  0self.INITIAL_STATE =  1self.STILL_PLAYING =  2self.WIN           =  3self.LOSS          =  4self.DRAW          =  5self.EMPTY         =  0self.ILLEGAL_MOVE  =  0self.STILL_PLAYING =  1self.WIN           =  2self.LOSS          =  3self.DRAW          =  4self.MAX_MOVE      =  9self.MAX_DEPTH     =  9self.board = self.EMPTY*np.ones(10,dtype=np.int32)#   Print the boarddef print_board( self ):sb = '.XO'bd = self.boardprint(' +-------+')print(' |',sb[bd[1]],sb[bd[2]],sb[bd[3]],'|')print(' |',sb[bd[4]],sb[bd[5]],sb[bd[6]],'|')print(' |',sb[bd[7]],sb[bd[8]],sb[bd[9]],'|')print(' +-------+')#   Return True if the board is fulldef full_board( self ):b = 1while b <= 9 and self.board[b] != self.EMPTY:b += 1return( b == 10 )#   Return range of feasible movesdef move_range( self ):return range(1,10)#   Return True if the specified move is legaldef is_legal_move( self, player, r ):return( r >=1 and r <= 9 and self.board[r] == self.EMPTY )#   Make specified move on the board and return game statusdef make_move( self, player, this_move ):if self.board[this_move] != self.EMPTY:print('Illegal Move')return self.ILLEGAL_MOVEelse:self.board[this_move] = playerif self.game_won( player ):return self.WINelif self.full_board():return self.DRAWelse:return self.STILL_PLAYING#   Undo the specified movedef undo_move( self, player, this_move ):self.board[this_move] = self.EMPTY#   Return True if game won by player p on board bd[]def game_won( self, p ):bd = self.boardreturn(  ( bd[1] == p and bd[2] == p and bd[3] == p )or( bd[4] == p and bd[5] == p and bd[6] == p )or( bd[7] == p and bd[8] == p and bd[9] == p )or( bd[1] == p and bd[4] == p and bd[7] == p )or( bd[2] == p and bd[5] == p and bd[8] == p )or( bd[3] == p and bd[6] == p and bd[9] == p )or( bd[1] == p and bd[5] == p and bd[9] == p )or( bd[3] == p and bd[5] == p and bd[7] == p ))def game_drawn( self, p ):return self.full_board()

3.在具有机会节点的游戏中进行修剪 (Pruning in Games with Chance Nodes

先给大家po一道题

 

完整计算过程(无剪枝)

  1. MIN节点的值

    • MIN1: min(2, 2) = 2

    • MIN2: min(1, 2) = 1

    • MIN3: min(0, 2) = 0

    • MIN4: min(-1, 0) = -1

  2. CHANCE节点的期望值

    期望值=0.25×2+0.25×1+0.25×0+0.25×(−1)=0.5
  3. 根节点(MAX)的最终值:0.5。

 前六个叶子已知(2, 2, 1, 2, 0, 2)是否需要评估第七、八叶子?

  • 已知值:前三组(MIN1-MIN3)的值为2, 1, 0。

  • CHANCE节点当前期望值

    当前期望=0.25×2+0.25×1+0.25×0+0.25×x(x为MIN4的值)
  • MIN4的可能值:若第七叶子为-1,第八叶子为0 → MIN4 = -1。

  • 最终期望值:0.5(与是否评估第七、八叶子无关,因为MIN4的值已由-1确定)。
    结论不需要评估第七、八叶子,因为即使不评估,MIN4的最小值已由第七叶子-1确定。


 前七个叶子已知(2, 2, 1, 2, 0, 2, -1)是否需要评估第八叶子?

  • 已知MIN4的第七叶子为-1,无论第八叶子0是否评估,MIN4的值已确定为-1。
    结论不需要评估第八叶子

叶子值范围限定为[-2, 2]时的剪枝优化

  • 前两个叶子值为0.5:此描述与当前树结构不符,可能用户指其他上下文。假设问题为:已知所有叶子值范围在[-2, 2],且已评估部分叶子。

  • 左CHANCE节点范围:若指MIN1-MIN4的某个子分支,需具体说明。假设评估前两个分支(MIN1和MIN2):

    • MIN1 = 2,MIN2 = 1 → 期望值下限为 0.25×2+0.25×1+0.25×(−2)+0.25×(−2)=−0.25

相关文章:

游戏树搜索与优化策略:Alpha-Beta剪枝及其实例分析

1.Alpha-Beta搜索 Alpha-Beta 搜索是一种用于对抗性游戏&#xff08;比如象棋、围棋&#xff09;的智能算法&#xff0c;目的是帮助计算机快速找到“最优走法”&#xff0c;同时避免不必要的计算。它的核心思想是&#xff1a;通过剪掉明显糟糕的分支&#xff0c;大幅减少需要计…...

基于Qwen-VL的手机智能体开发

先上Demo&#xff1a; vl_agent_demo 代码如下&#xff1a; 0 设置工作目录&#xff1a; 你的工作目录需要如下&#xff1a; 其中utils文件夹和qwenvl_agent.py均参考自 GitHub - QwenLM/Qwen2.5-VL: Qwen2.5-VL is the multimodal large language model series developed by …...

记录一次Spring事务失效导致的生产问题

一、背景介绍 公司做的是“聚合支付”业务&#xff0c;对接了微信、和包、数字人民币等等多家支付机构&#xff0c;我们提供统一的支付、退款、自动扣款签约、解约等能力给全国的省公司、机构、商户等。 同时&#xff0c;需要做对账功能&#xff0c;即支付机构将对账文件给到…...

深度学习实战:用TensorFlow构建高效CNN的完整指南

一、为什么每个开发者都要掌握CNN&#xff1f; 在自动驾驶汽车识别路标的0.1秒里&#xff0c;在医疗AI诊断肺部CT片的精准分析中&#xff0c;甚至在手机相册自动分类宠物的日常场景里&#xff0c;卷积神经网络&#xff08;CNN&#xff09;正悄然改变着我们的世界。本文将以工业…...

算法 之 贪心思维训练!

文章目录 从最大/最小开始贪心2279.装满石头的背包的最大数量2971.找到最大周长的多边形 从最左、最右开始贪心2712.使所有字符相等的最小成本 划分型贪心1221.分割平衡字符串 贪心策略在处理一些题目的时候能够带来意想不到的效果 从最小/最大开始贪心&#xff0c;优先考虑最小…...

从0到1构建AI深度学习视频分析系统--基于YOLO 目标检测的动作序列检查系统:(1)视频信息的获取与转发

文章大纲 基于YOLO的动作序列检查系统架构设计系统架构图实时视频传输协议技术对比视频流 常见协议对比表三、WebSocket内网传输设计方案四、样例程序(Python + JavaScript)五、性能优化建议新兴技术预警参考文献提示词参考基于YOLO的动作序列检查系统架构设计 系统架构图 #…...

大语言模型学习--LangChain

LangChain基本概念 ReAct学习资料 https://zhuanlan.zhihu.com/p/660951271 LangChain官网地址 Introduction | &#x1f99c;️&#x1f517; LangChain LangChain是一个基于语言模型开发应用程序的框架。它可以实现以下应用程序&#xff1a; 数据感知&#xff1a;将语言模型…...

【PCIe 总线及设备入门学习专栏 4.5 -- PCIe 中断 MSI 与 MSI-X 机制介绍】

文章目录 PCI 设备中断机制PCIe 设备中断机制PCIe MSI 中断机制MSI CapabilityMSI-X 中断机制MSI-X capabilityMSI-X TablePBAMSI-X capability 解析MSI/MSI-X 操作流程扫描设备配置设备MSI 配置MSI-X 配置中断触发与处理PCI 设备中断机制 以前的PCI 设备是支持 物理上的 INTA…...

wxWidgets GUI 跨平台 入门学习笔记

准备 参考 https://wiki.wxwidgets.org/Microsoft_Visual_C_NuGethttps://wiki.wxwidgets.org/Tools#Rapid_Application_Development_.2F_GUI_Buildershttps://docs.wxwidgets.org/3.2/https://docs.wxwidgets.org/latest/overview_helloworld.htmlhttps://wizardforcel.gitb…...

valgrind 检测多线程 bug,检测 并发 bug concurrent bug parallel bug

valgrind --toolhelgrind ./your_program 如果检测的对象是大型程序&#xff0c;可以设定仅在某些函数中开启 valgrind 的检测&#xff1a; Valgrind 提供了一些客户请求&#xff08;client requests&#xff09;&#xff0c;可以在代码中插入特定的宏来控制 Valgrind 的行为。…...

OpenMCU(一):STM32F407 FreeRTOS移植

概述 本文主要描述了STM32F407移植FreeRTOS的简要步骤。移植描述过程中&#xff0c;忽略了Keil软件的部分使用技巧。默认读者熟练使用Keil软件。本文的描述是基于OpenMCU_FreeRTOS这个工程&#xff0c;该工程已经下载放好了移植stm32f407 FreeRTOS的所有文件 OpenMCU_FreeRTOS工…...

割平面法的理解

割平面法的理解 1. 简介 割平面法&#xff08;Cutting Plane Method&#xff09;用于求解整数规划问题&#xff0c;通过逐步添加线性约束&#xff08;割平面&#xff09;逼近整数解。本文以Gomory割平面法为例&#xff0c;结合简单示例拆解核心步骤。 2. 示例详解 问题描述 …...

[自动驾驶-传感器融合] 多激光雷达的外参标定

文章目录 引言外参标定原理ICP匹配示例参考文献 引言 多激光雷达系统通常用于自动驾驶或机器人&#xff0c;每个雷达的位置和姿态不同&#xff0c;需要将它们的数据统一到同一个坐标系下。多激光雷达外参标定的核心目标是通过计算不同雷达坐标系之间的刚性变换关系&#xff08…...

C++ 学习(八)(模板,可变参数模板,模板专业化(完整模板专业化,部分模板专业化),类型 Traits,SFINAE(替换失败不是错误),)

C 模板 C 中的模板是一项强大的功能&#xff0c;允许您编写通用代码&#xff0c;这意味着您可以编写可以处理不同数据类型的单个函数或类。这意味着您无需为要使用的每种数据类型编写单独的函数或类。 模板函数 要创建模板函数&#xff0c;请使用 关键字&#xff0c;后跟类型…...

AI---DevOps常备工具(‌AI-Integrated DevOps Essential Tools)

AI---DevOps常备工具 技术领域正在迅速发展&#xff0c;随着我们步入 2025 年&#xff0c;有一点是明确的&#xff1a;人工智能&#xff08;AI&#xff09;不再只是一个流行词&#xff0c;它是每个 DevOps 工程师都需要掌握的工具。随着云环境的复杂性增加、对更快部署的需求以…...

题目梳理2025[长期更新]

题目梳理 组合类题目(2025年3月5日) 组合总数1&#xff0c;组合总数2&#xff0c;组合总数3 -> 递归回溯的思想 组合总数4 -> 爬楼的思想&#xff0c;动态规划&#xff0c;确定递归边界&#xff0c;确定递归入口&#xff0c;最后一步怎么走的思想...

Maven 中 SNAPSHOT 版本与 RELEASE 版本的区别

Maven 仓库分为 Snapshot 快照仓库和 Release 发行仓库两种类型的仓库。Snapshot 快照仓库用于保存 SNAPSHOT 版本&#xff0c;Release 发行仓库用于保存 RELEASE 版本。 SNAPSHOT 是一种特殊的版本标识&#xff0c;主要用于表示项目的不稳定、正在开发中的版本&#xff0c;而…...

JavaScript 知识点整理

1. 什么是AST&#xff1f;它在前端有哪些应用场景&#xff1f; AST Abstract Syntax Tree抽象语法树&#xff0c;用于表达源码的树形结构 应用&#xff1a; Babel&#xff1a;一个广泛使用的 JS 编译器&#xff0c;将ES6 或 JSX 等现代语法转换为兼容性较好的 ES5 代码。Esl…...

迷你世界脚本出生点接口:Spawnport

出生点接口&#xff1a;Spawnport 彼得兔 更新时间: 2023-04-26 10:19:56 具体函数名及描述如下: 序号 函数名 函数描述 1 getSpawnPoint(...) 获取默认出生点 2 setSpawnPoint(...) 设置出生点位置 3 getChunkValidSpawnPos(...) 获取区块有效刷新点…...

鸿蒙与DeepSeek深度整合:构建下一代智能操作系统生态

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/north 目录 技术融合背景与价值鸿蒙分布式架构解析DeepSeek技术体系剖析核心整合架构设计智能调度系统实现…...

利用行波展开法测量横观各向同性生物组织的生物力学特性|文献速递-医学影像人工智能进展

Title 题目 Measurement of biomechanical properties of transversely isotropic biological tissue using traveling wave expansion 利用行波展开法测量横观各向同性生物组织的生物力学特性 01 文献速递介绍 纤维嵌入结构在自然界中普遍存在。从脑白质&#xff08;罗曼…...

AR配置静态IP双链路负载分担示例

AR配置静态IP双链路负载分担示例 适用于大部分企业网络出口 业务需求&#xff1a; 运营商1分配的接口IP为100.100.1.2&#xff0c;子网掩码为255.255.255.252&#xff0c;网关IP为100.100.1.1。 运营商2分配的接口IP为200.200.1.2&#xff0c;子网掩码为255.255.255.248&am…...

文件操作(详细讲解)(1/2)

你好这里是我说风俗&#xff0c;希望各位客官点点赞&#xff0c;收收藏&#xff0c;关关注&#xff0c;各位对我的支持是我持续更新的动力&#xff01;&#xff01;&#xff01;&#xff01;第二期会马上更的关注我获得最新消息哦&#xff01;&#xff01;&#xff01;&#xf…...

[AI]从零开始的so-vits-svc歌声推理及混音教程

一、前言 在之前的教程中已经为大家讲解了如何安装so-vits-svc以及使用现有的模型进行文本转语音。可能有的小伙伴就要问了&#xff0c;那么我们应该怎么使用so-vits-svc来进行角色歌曲的创作呢&#xff1f;其实歌曲的创作会相对麻烦一些&#xff0c;会使用到好几个软件&#x…...

华为OD机试-停车场最大距离(Java 2024 E卷 100分)

题目描述 停车场有一排车位,用 0 表示空位,1 表示已停车。至少有一辆车停在车位上,也至少有一个空位。为了防剐蹭,需要找到一个空位,使得该空位与最近的车辆之间的距离最大。返回这个最大距离。 输入描述 一个用半角逗号分隔的停车标识字符串,停车标识为 0 或 1,0 表示…...

SpringMVC控制器定义:@Controller注解详解

文章目录 引言一、Controller注解基础二、RequestMapping与请求映射三、参数绑定与数据校验四、RestController与RESTful API五、控制器建议与全局处理六、控制器测试策略总结 引言 在SpringMVC框架中&#xff0c;控制器(Controller)是整个Web应用的核心组件&#xff0c;负责处…...

免费分享一个软件SKUA-GOCAD-2022版本

若有需要&#xff0c;可以下载。 下载地址 通过网盘分享的文件&#xff1a;Paradigm SKUA-GOCAD 22 build 2022.06.20 (x64).rar 链接: https://pan.baidu.com/s/10plenNcMDftzq3V-ClWpBg 提取码: tm3b 安装教程 Paradigm SKUA-GOCAD 2022版本v2022.06.20安装和破解教程-CS…...

学习threejs,使用LineBasicMaterial基础线材质

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.LineBasicMaterial1.…...

python保留字及作用

在 Python 中&#xff0c;保留字&#xff08;Reserved Keywords&#xff09;是具有特殊意义和用途的单词&#xff0c;不能用作变量名、函数名或标识符。以下是 Python 的保留字及其作用&#xff1a; Python 保留字列表 保留字作用False布尔值&#xff0c;表示假。None表示空值…...

java面试题(一)基础部分

1.【String】StringBuffer和StringBuilder区别&#xff1f; String对象是final修饰的不可变的。对String对象的任何操作只会生成新对象&#xff0c;不会对原有对象进行操作。 StringBuilder和StringBuffer是可变的。 其中StringBuilder线程不安全&#xff0c;但开销小。 St…...