feat: docs

This commit is contained in:
zsq259
2024-06-24 15:46:49 +08:00
parent abfb098075
commit 6327553edf
214 changed files with 12760 additions and 0 deletions

103
docs/A*.md Normal file
View File

@ -0,0 +1,103 @@
# 启发式函数与A*搜索算法
## 介绍
在人工智能和路径规划中启发式函数和A*搜索算法是两个重要的概念。启发式函数用于估计从当前状态到目标状态的代价而A\*搜索算法则利用这些估计来找到最优路径。
## 启发式函数
### 什么是启发式函数?
启发式函数Heuristic Function是用于估计当前状态到目标状态之间的最小成本的函数。它的设计是为了加速搜索算法使其更高效地找到解决方案。
### 启发式函数的性质
1. **可接受性Admissibility**
- 一个启发式函数是可接受的,如果它从不高估从节点到目标节点的实际最小成本。
- 数学定义:对于所有节点 \(n\),启发式函数 \(h(n)\) 必须满足 \(h(n) \leq h^*(n)\),其中 \(h^*(n)\) 是从节点 \(n\) 到目标节点的实际成本。
2. **一致性Consistency**
- 一致性的启发式函数也称为单调性启发式函数。如果对于所有节点 \(n\) 和其每个子节点 \(m\),启发式函数 \(h\) 满足 \(h(n) \leq c(n, m) + h(m)\),其中 \(c(n, m)\) 是从节点 \(n\) 到节点 \(m\) 的实际成本。
- 数学定义:\(h(n) \leq c(n, m) + h(m)\)。
### 启发式函数的示例
1. **曼哈顿距离Manhattan Distance**
- 在网格路径规划中,曼哈顿距离是两个点之间沿轴线方向的总距离。
- 公式:\(h(n) = |x_1 - x_2| + |y_1 - y_2|\)。
2. **欧几里得距离Euclidean Distance**
- 欧几里得距离是两点之间的直线距离。
- 公式:\(h(n) = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}\)。
## A*搜索算法
### 什么是A*搜索?
A*搜索是一种图搜索算法它结合了Dijkstra算法和贪婪最佳优先搜索的优点。A*搜索使用启发式函数来引导搜索方向,从而找到从起始点到目标点的最优路径。
### A*搜索的工作原理
1. **初始化**
- 将起始节点添加到优先队列中初始代价为0。
2. **搜索过程**
- 从优先队列中取出总代价最小的节点作为当前节点。
- 如果当前节点是目标节点,则搜索结束。
- 否则,扩展当前节点的所有邻居节点,并更新它们的代价和优先级。
- 重复上述步骤,直到找到目标节点或优先队列为空。
3. **代价函数**
- A*搜索使用一个代价函数 \(f(n) = g(n) + h(n)\) 来评估每个节点的优先级。
- 其中,\(g(n)\) 是从起始节点到节点 \(n\) 的实际代价,\(h(n)\) 是从节点 \(n\) 到目标节点的启发式估计代价。
### A*搜索的伪代码
```pseudo
function A*(start, goal)
openSet := {start}
cameFrom := empty map
gScore := map with default value of Infinity
gScore[start] := 0
fScore := map with default value of Infinity
fScore[start] := heuristic(start, goal)
while openSet is not empty
current := node in openSet with lowest fScore[current]
if current == goal
return reconstruct_path(cameFrom, current)
openSet.remove(current)
for each neighbor of current
tentative_gScore := gScore[current] + d(current, neighbor)
if tentative_gScore < gScore[neighbor]
cameFrom[neighbor] := current
gScore[neighbor] := tentative_gScore
fScore[neighbor] := gScore[neighbor] + heuristic(neighbor, goal)
if neighbor not in openSet
openSet.add(neighbor)
return failure
function reconstruct_path(cameFrom, current)
total_path := {current}
while current in cameFrom
current := cameFrom[current]
total_path.prepend(current)
return total_path
```
### A*搜索的应用
- **视频游戏**:用于角色路径规划。
- **路径规划问题**:如地图导航、机器人路径规划等。
- **资源规划问题**:如物流和供应链管理。
- **语言分析**:如句法分析。
- **机器翻译和语音识别**:用于寻找最优匹配和路径。
## 结论
启发式函数和A\*搜索算法是解决复杂路径规划和搜索问题的重要工具。通过设计有效的启发式函数可以显著提高搜索算法的效率。A*搜索算法结合了路径代价和启发式估计,是找到最优路径的强大方法。

140
docs/minmax.md Normal file
View File

@ -0,0 +1,140 @@
# Minimax 搜索算法
## 介绍
Minimax 是一种用于两人对弈游戏的决策算法如国际象棋、井字棋和跳棋。它帮助确定玩家的最佳行动假设对手也在最优地进行游戏。Minimax 算法的目标是在最小化可能损失的情况下最大化玩家的得分(因此得名 "minimax")。
## 基本概念
### 游戏树
游戏树表示游戏中所有可能的移动。从当前状态开始,每个节点代表一个游戏状态,每条边代表一个移动。
### 最大化和最小化玩家
- **最大化玩家Max**:这个玩家试图获得尽可能高的分数。
- **最小化玩家Min**:这个玩家试图最小化最大化玩家的得分。
## Minimax 如何工作
1. **生成游戏树**:从当前游戏状态开始,生成所有可能的未来状态,直到某个预定深度。
2. **评估叶节点**:使用评估函数为每个叶节点(终止状态或最大深度的状态)分配一个分数。
3. **回溯分数**
- 对于 Max 节点,选择子节点中得分最高的。
- 对于 Min 节点,选择子节点中得分最低的。
4. **选择最佳移动**:在根节点(当前游戏状态),选择导致 Max 玩家得分最高的移动。
## 示例
让我们以井字棋为例。假设现在是 Max 的回合,当前棋盘如下:
```
X | O | X
-----------
O | X |
-----------
| | O
```
### 步骤 1生成游戏树
生成 Max 的所有可能移动。由于是 Max 的回合,在每个空位上放置一个 "X"
```
X | O | X X | O | X X | O | X
----------- ----------- -----------
O | X | X O | X | O | X |
----------- ----------- -----------
| | O X | | O X | | O
```
### 步骤 2评估叶节点
为叶节点分配分数。假设:
- Max 获胜得 +10 分
- Min 获胜得 -10 分
- 平局得 0 分
```
X | O | X X | O | X X | O | X
----------- ----------- -----------
O | X | X O | X | O | X |
----------- ----------- -----------
| | O X | | O X | | O
得分: 0 得分: 10 得分: 10
```
### 步骤 3回溯分数
由于根节点是 Max 的回合,选择子节点中得分最高的:
```
Max
|
V
10
```
### 步骤 4选择最佳移动
Max 将选择导致得分为 10 的移动。
## 伪代码
以下是 Minimax 算法的简单伪代码:
```pseudo
function minimax(node, depth, maximizingPlayer)
if depth == 0 or node is a terminal node
return evaluate(node)
if maximizingPlayer
maxEval = -∞
for each child of node
eval = minimax(child, depth - 1, false)
maxEval = max(maxEval, eval)
return maxEval
else
minEval = +∞
for each child of node
eval = minimax(child, depth - 1, true)
minEval = min(minEval, eval)
return minEval
```
## Alpha-Beta 剪枝
Alpha-Beta 剪枝是 Minimax 算法的一种优化。它通过剪枝那些不会影响最终决策的分支,减少需要评估的节点数量。
### 带 Alpha-Beta 剪枝的伪代码
```pseudo
function alphabeta(node, depth, α, β, maximizingPlayer)
if depth == 0 or node is a terminal node
return evaluate(node)
if maximizingPlayer
maxEval = -∞
for each child of node
eval = alphabeta(child, depth - 1, α, β, false)
maxEval = max(maxEval, eval)
α = max(α, eval)
if β <= α
break
return maxEval
else
minEval = +∞
for each child of node
eval = alphabeta(child, depth - 1, α, β, true)
minEval = min(minEval, eval)
β = min(β, eval)
if β <= α
break
return minEval
```
## 结论
Minimax 是一种在两人对弈游戏中做出最佳决策的强大算法。通过考虑所有可能的移动及其结果它确保玩家在假设对手也在最优地进行游戏的情况下做出最佳移动。Alpha-Beta 剪枝进一步提高了 Minimax 的效率,减少了需要评估的节点数量。