N皇后问题:从入门到精通,一篇文章让你彻底搞懂!

N皇后问题——通俗易懂地讲解(C++) 注:参考程序猿小灰,hackbuteer1 八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出: 在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上 (斜率为1),问有多少种摆法。高斯认为有76种方案。 让我们来举个栗子,下图的绿色格子是一个皇后在棋盘上的“封锁范围”,其他皇后不得放置在这些... 阅读详情

N皇后问题:从入门到精通,一篇文章让你彻底搞懂!

导读:本文从0到1讲解N皇后问题,包含图解演示、代码优化、位运算黑科技,最后还附赠面试模板!不管你是算法小白还是准备面试,这篇文章都能让你收获满满!


🎯 什么是N皇后问题?

想象一下,你有一个N×N的国际象棋棋盘,现在要在棋盘上摆放N个皇后。

问题来了:怎么摆放才能让这N个皇后互不攻击?

在国际象棋中,皇后可以攻击:

  • ♜ 同一行的所有棋子
  • ♜ 同一列的所有棋子
  • ♜ 两条对角线上的所有棋子

所以,N皇后问题就是:在N×N的棋盘上放N个皇后,让她们谁也吃不到谁!

📌 举个栗子:4皇后问题

4皇后问题有2个解,我们来看第一个解:

  0 1 2 3    ← 列号
0 . Q . .   ← 第0行,皇后在第1列
1 . . . Q   ← 第1行,皇后在第3列
2 Q . . .   ← 第2行,皇后在第0列
3 . . Q .   ← 第3行,皇后在第2列
  ↑ ↑ ↑ ↑
  每行每列每条对角线都只有1个皇后!

用坐标表示就是:[(0,1), (1,3), (2,0), (3,2)]

🎨 可视化示意图

方案一:                    方案二:
┌───┬───┬───┬───┐          ┌───┬───┬───┬───┐
│   │ ♛ │   │   │          │   │   │ ♛ │   │
├───┼───┼───┼───┤          ├───┼───┼───┼───┤
│   │   │   │ ♛ │          │ ♛ │   │   │   │
├───┼───┼───┼───┤          ├───┼───┼───┼───┤
│ ♛ │   │   │   │          │   │   │   │ ♛ │
├───┼───┼───┼───┤          ├───┼───┼───┼───┤
│   │   │ ♛ │   │          │   │ ♛ │   │   │
└───┴───┴───┴───┘          └───┴───┴───┴───┘
坐标: [(0,1),(1,3),(2,0),(3,2)]  坐标: [(0,2),(1,0),(2,3),(3,1)]

看到了吗?每个皇后都"和平共处",没有任何两个皇后在同一行、同一列或同一对角线上!


💡 解法一:朴素递归法(适合理解)

🎯 核心思路

逐行放皇后,一行一行来!

放置流程:
第0行:尝试放皇后在第0列、第1列、第2列...第n-1列
  ↓
放好后,去第1行继续放
  ↓
每次放之前,检查会不会和之前的皇后"打架"
  ↓
如果某一行所有位置都不能放,说明前面的摆放有问题
  ↓
【回溯】到上一行重新尝试 ← 这就是回溯算法的精髓!

📖 代码解析

public static int num1(int n) {
    if (n < 1) {
        return 0;
    }
    int[] record = new int[n];  // 记录每行皇后放在哪一列
    return process1(0, record, n);
}

record数组是什么?

 record数组的含义:
 record[0] = 3 表示:第0行的皇后放在第3列
 record[1] = 1 表示:第1行的皇后放在第1列
 record[2] = 4 表示:第2行的皇后放在第4列
 ...

 以4皇后的一个解为例:
 record = [1, 3, 0, 2]
 对应棋盘:
   0 1 2 3
 0 . ♛ . .  ← record[0]=1
 1 . . . ♛  ← record[1]=3
 2 ♛ . . .  ← record[2]=0
 3 . . ♛ .  ← record[3]=2
public static int process1(int i, int[] record, int n) {
    // 基线条件:如果已经处理完所有行(i == n),说明找到了一个合法解
    if (i == n) {
        return 1;
    }
    
    int res = 0;
    
    // 尝试在第i行的每一列放置皇后
    for (int j = 0; j < n; j++) {
        // 检查在(i, j)位置放皇后是否合法
        if (isValid(record, i, j)) {
            record[i] = j;  // 记录:第i行皇后放在第j列
            res += process1(i + 1, record, n);  // 递归处理下一行
        }
    }
    
    return res;  // 返回所有合法方案的数量
}

关键点:

  • i:当前要处理第几行(从0开始)
  • j:尝试在第j列放皇后
  • 如果位置合法,就记录下来,然后递归处理下一行
  • 把所有合法的方案数累加起来

🔍 合法性检查:怎么判断会不会"打架"?

public static boolean isValid(int[] record, int i, int j) {
    // 检查之前所有行的皇后(0到i-1行)
    for (int k = 0; k < i; k++) {
        // 条件1:j == record[k] → 同一列,打架!
        // 条件2:Math.abs(record[k] - j) == Math.abs(i - k) → 同一对角线,打架!
        if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) {
            return false;
        }
    }
    return true;  // 所有检查都通过,可以放!
}
❓ 为什么这样判断对角线?

图解说明:

棋盘坐标系:
  0 1 2 3 4 5
0 . . . . . .
1 . . . . . .
2 . . ♛ . . .  ← 已有皇后在(2,2)
3 . . . . . ?  ← 想在(3,4)放皇后
4 . . . . . .
5 . . . . . .

判断(2,2)和(3,4)是否在同一对角线:
- 行的差距:|3 - 2| = 1
- 列的差距:|4 - 2| = 2
- 1 ≠ 2 → 不在同一对角线 ✓

反例:

  0 1 2 3 4 5
0 . . . . . .
1 . . . . . .
2 . . ♛ . . .  ← 已有皇后在(2,2)
3 . . . . . .
4 . . . . ♛ .  ← (4,4)能放吗?
5 . . . . . .

判断(2,2)和(4,4):
- 行的差距:|4 - 2| = 2
- 列的差距:|4 - 2| = 2
- 2 == 2 → 在同一对角线!✗ 不能放!

数学原理:

如果两个点 (r1, c1) 和 (r2, c2) 在同一条对角线上,那么 |r1-r2| == |c1-c2|

为什么? 因为对角线的斜率是±1,行和列的变化量必须相等!


⚡ 解法二:位运算优化法(高性能)

💡 高能预警:这个解法超级巧妙,用位运算代替了数组,速度快了不止一点点!

🤔 为什么用位运算?

传统方法的瓶颈:

// 解法一:需要数组 + 循环检查
int[] record = new int[n];  // O(n) 空间
for (int k = 0; k < i; k++) {  // O(n) 时间检查
    if (j == record[k] || ...) { ... }
}

位运算的优势:

// 解法二:用1个int就能表示所有状态
int colLim = 0b00001010;  // 第1、3列被占(从右往左数)
// 位运算检查:O(1) 时间!

📊 核心参数解释

public static int process2(
    int limit,       // 限制条件,n皇后就有n个1。比如4皇后:00001111
    int colLim,      // 列限制,哪些列已经被占了
    int leftDiaLim,  // 左对角线限制(左下↙到右上↗)
    int rightDiaLim  // 右对角线限制(右下↘到左上↖)
) {

参数图解(以4皇后为例):

limit = 00001111  (低4位是1,表示只有4列可用)

假设当前状态:
colLim =      00000101  (第0、2列已被占用)
leftDiaLim =  00001000  (第3列被左对角线影响)
rightDiaLim = 00000010  (第1列被右对角线影响)

那么不能放的位置 = colLim | leftDiaLim | rightDiaLim
                =  00001111
                =  所有位置都不能放!需要回溯

📖 完整代码拆解

Step 1:初始化
public static int num2(int n) {
    if (n < 1 || n > 32) {
        return 0;
    }
    // 生成limit:n个1
    // 比如n=4:00001111
    int limit = n == 32 ? -1 : (1 << n) - 1;
    return process2(limit, 0, 0, 0);
}

limit 怎么算的?

1 << n       = 2^n,二进制是 1 后面跟 n 个 0
(1 << n) - 1 = n 个 1

举例:
n = 4:
  1 << 4   = 16    = 00010000
  16 - 1   = 15    = 00001111  ← 低4位都是1!

n = 8:
  1 << 8   = 256   = 100000000
  256 - 1  = 255   = 0011111111  ← 低8位都是1!

为什么n=32时用-1?
因为 1 << 32 会溢出,而 -1 的二进制就是32个1:11111111...1111
Step 2:递归核心逻辑
public static int process2(int limit, int colLim, int leftDiaLim, int rightDiaLim) {
    // 基线条件:所有列都放了皇后
    if (colLim == limit) {
        return 1;  // 找到一个合法方案!
    }
    
    // 🎭 核心魔法:计算哪些位置可以放皇后!
    int pos = limit & (~(colLim | leftDiaLim | rightDiaLim));
    
    int mostRightOne = 0;
    int res = 0;
    
    // 依次尝试每一个可以放的位置
    while (pos != 0) {
        // 提取最右边的1(找到一个可以放皇后的位置)
        mostRightOne = pos & (~pos + 1);
        // 去掉这个1,继续尝试下一个位置
        pos = pos - mostRightOne;
        
        // 递归处理下一行
        res += process2(
            limit, 
            colLim | mostRightOne,           // 更新列限制
            (leftDiaLim | mostRightOne) << 1,  // 更新左对角线限制
            (rightDiaLim | mostRightOne) >>> 1 // 更新右对角线限制
        );
    }
    
    return res;
}
🎭 魔法公式详解
1️⃣ 计算可放位置:pos
int pos = limit & (~(colLim | leftDiaLim | rightDiaLim));

分步解读:

第1步:colLim | leftDiaLim | rightDiaLim
       → 把所有不能放的位置标记为1
       
第2步:~(...)
       → 取反:不能放的变成0,能放的变成1
       
第3步:& limit
       → 只保留有效的n位(去掉高位干扰)

举个栗子:

假设4皇后,当前状态:
colLim:      00001010  (第1、3列被占)
leftDiaLim:  00000100  (第2列被左对角线影响)
rightDiaLim: 00000001  (第0列被右对角线影响)

Step 1:  OR 运算
  00001010
  00000100
  00000001
  --------
  00001111  ← 这些位置都不能放!

Step 2: 取反
  ~00001111 = 11110000

Step 3: AND limit
  11110000
  & 00001111  (limit)
  --------
  00000000  ← 没位置了!需要回溯!
2️⃣ 提取最右边的1
mostRightOne = pos & (~pos + 1);

这是什么黑科技?! 这是一个经典的位运算技巧!

图解原理:

假设 pos = 00101100  (表示第2、3、5列可以放皇后)

Step 1: 取反
  pos    = 00101100
  ~pos   = 11010011

Step 2: 加1(得到补码,相当于-pos)
  ~pos   = 11010011
  +1     =        1
  ----------------
         = 11010100

Step 3: AND 运算
  pos    = 00101100
  ~pos+1 = 11010100
  ---------------
  AND    = 00000100  ← 成功提取最右边的1!

为什么能提取最右边的1?

关键在于:加1后,最右边的1及其右边的0都会翻转

原始:  xxxxx1000  (x表示任意位)
取反:  yyyyY0111  (y是x的反,Y是1的反)
加1:   yyyyY1000  ← 只有最右边的1保持不变!
AND:    000001000  ← 其他位都被消掉了!

为什么要提最右边的1?
因为我们要一个一个地尝试每个可放位置!

3️⃣ 更新限制条件
colLim | mostRightOne                    // 列限制:把新放的列标记为1
(leftDiaLim | mostRightOne) << 1         // 左对角线:左移一位
(rightDiaLim | mostRightOne) >>> 1       // 右对角线:右移一位(无符号右移)
🎯 为什么对角线要移位?

动态图解:

假设在第2行第2列放了皇后:

第0行:  0 0 0 0 0
         ↑
      还没有皇后

第1行:  0 0 0 0 0
         ↑
      还没有皇后

第2行:  0 0 ♛ 0 0  ← 在这放了皇后!
            ↑
         colLim: 00100

第3行:  0 1 0 1 0  ← 对角线影响扩散了!
            ↑
      leftDiaLim:  01000 (左移1位)
      rightDiaLim: 00010 (右移1位)
      
第4行:  1 0 0 0 1  ← 继续扩散!
         ↑
      leftDiaLim:  10000 (再左移1位)
      rightDiaLim: 00001 (再右移1位)

看到了吗? 对角线的影响范围就像"扇形"一样扩散!

为什么要移位?

左对角线(↙↗方向):
  从(2,2)到(3,1),列号减少1 → 左移1位
  从(2,2)到(3,3),列号增加1 → 右移1位
  
所以:
  leftDiaLim << 1   表示左对角线影响向左扩散
  rightDiaLim >>> 1 表示右对角线影响向右扩散

完整流程图:

┌─────────────────────────────────────────────────┐
│  第0行:放皇后在第2列                              │
│  colLim:     00100                              │
│  leftDiaLim: 00000                              │
│  rightDiaLim:00000                              │
└─────────────────┬───────────────────────────────┘
                  ↓
┌─────────────────────────────────────────────────┐
│  第1行:更新限制                                   │
│  colLim:     00100                              │
│  leftDiaLim: 00000 << 1 = 00000                │
│  rightDiaLim:00000 >>> 1 = 00000               │
│  pos = ~(00100) & 11111 = 11011                │
│  → 可以在第0、1、3、4列放                        │
└─────────────────┬───────────────────────────────┘
                  ↓
┌─────────────────────────────────────────────────┐
│  假设在第1行第0列放皇后                            │
│  colLim:     00101                              │
│  leftDiaLim: 00000 << 1 = 00000                │
│  rightDiaLim:00001 >>> 1 = 00000               │
└─────────────────────────────────────────────────┘

📊 两种方法对比

特性解法一(数组)解法二(位运算)
理解难度⭐⭐ 容易⭐⭐⭐⭐ 需要位运算基础
运行速度慢快10-50倍!
时间复杂度O(n!)O(n!),但常数更小
空间复杂度O(n) 数组O(1) 几个int
适用场景学习理解实际使用/面试加分
皇后数限制理论上无限制最多32皇后(int的位数)

📈 性能测试对比

以15皇后为例(测试环境:普通PC):

解法一(数组法):
  方案数: 2,279,184
  耗时:   约 2000ms
  
解法二(位运算):
  方案数: 2,279,184
  耗时:   约 50ms
  
⚡ 性能提升: 40倍!

为什么快这么多?

  1. 位运算 O(1) vs 数组循环 O(n)
  2. CPU对位运算有硬件优化
  3. 减少了函数调用和内存访问

🎯 递归回溯的精髓

什么是回溯算法?

无论哪种解法,核心都是递归 + 回溯:

递归回溯流程图:

        开始
         ↓
    [第0行,尝试第0列]
         ↓
    [第1行,尝试第0列] ← 打架?是 → 尝试第1列
         ↓                    ↓
    [第2行,尝试第0列]      打架?否 → 继续下一行
         ↓
    发现没地方放!
         ↓
    【回溯】回到第1行,换个位置
         ↓
    继续尝试...
         ↓
    直到所有行都放好 → 成功!

核心思想:

走不通就退回来,换条路再走!

回溯算法模板

void backtrack(当前状态) {
    // 1. 基线条件:找到一个解
    if (满足条件) {
        记录结果;
        return;
    }
    
    // 2. 遍历所有可能的选择
    for (每个选择) {
        if (选择合法) {
            // 3. 做选择
            记录选择;
            
            // 4. 递归进入下一层
            backtrack(下一层状态);
            
            // 5. 撤销选择(回溯)
            撤销选择;
        }
    }
}

N皇后问题中的体现:

// 做选择
record[i] = j;

// 递归进入下一层
res += process1(i + 1, record, n);

// 撤销选择(隐含)
// 因为record[i]会在下一次循环中被覆盖,所以不需要显式撤销

🚀 实战技巧

1️⃣ 如何输出具体的摆放方案?

在解法一中,当 i == n 时,record 数组就存储了一个合法方案:

public static int process1(int i, int[] record, int n) {
    if (i == n) {
        // 🎨 打印当前方案
        System.out.println("找到第" + (++count) + "个解:");
        for (int row = 0; row < n; row++) {
            for (int col = 0; col < n; col++) {
                if (record[row] == col) {
                    System.out.print("♛ ");  // 皇后位置
                } else {
                    System.out.print(". ");  // 空位
                }
            }
            System.out.println();
        }
        System.out.println("---");
        return 1;
    }
    // ... 其余代码不变
}

输出效果:

找到第1个解:
. ♛ . . 
. . . ♛ 
♛ . . . 
. . ♛ . 
---
找到第2个解:
. . ♛ . 
♛ . . . 
. . . ♛ 
. ♛ . . 
---

2️⃣ N皇后有多少个解?

N解的数量备注
11平凡解
20无解
30无解
42第一个有解的情况
510
64
740
892经典8皇后问题
9352
10724
……
152,279,184超过200万!

有趣的事实:

  • N=2和N=3为什么无解?你可以自己试试摆放,会发现无论怎么放都会有冲突!
  • N皇后的解的数量不是单调递增的(N=6只有4个解,比N=5还少)

💡 面试加分回答

🎯 标准回答模板

如果面试官问你N皇后问题,你可以这样说:

面试官: “请说一下N皇后问题的解法。”

你: "N皇后问题是经典的回溯算法问题,我有两种解法:

第一种是朴素的数组法:

  • 用 record 数组记录每行皇后的列位置
  • 逐行尝试并检查合法性
  • 时间复杂度 O(n!),空间复杂度 O(n)
  • 优点是容易理解和实现

第二种是位运算优化法:

  • 用三个int变量分别记录列、左对角线、右对角线的占用情况
  • 通过位运算快速计算可放位置
  • 空间复杂度降到 O(1)
  • 实际运行速度快10-50倍

位运算法的核心在于:

  1. 用 pos = limit & ~(colLim | leftDiaLim | rightDiaLim) 快速得到所有可放位置
  2. 用 pos & (-pos) 提取最右边的1,逐个尝试
  3. 对角线限制通过左移/右移来模拟影响范围的扩散

我推荐在面试中使用位运算法,既展示了对回溯的理解,又体现了算法优化能力。"

🌟 进阶追问

面试官: “为什么位运算更快?”

你: "主要有三个原因:

  1. 位运算是O(1)操作,而数组检查需要O(n)的循环
  2. CPU对位运算有硬件级优化,执行速度极快
  3. 减少了内存访问,位运算都在寄存器中完成,避免了缓存未命中"

面试官: “能处理多大的N?”

你: “位运算法最多处理32皇后(因为int是32位)。如果要处理更大的N,可以用 long(64位)或者 BitSet(不限位数),但超过20皇后后计算量会非常大,实际意义不大。”


🎓 总结

核心要点回顾

  1. ✅ N皇后问题 = 在棋盘上放N个皇后,让她们互不攻击
  2. ✅ 解法一(数组法):好理解,适合初学者,用递归+回溯
  3. ✅ 解法二(位运算法):高性能,面试加分,用位运算代替数组
  4. ✅ 核心思想:逐行放置 + 合法性检查 + 走不通就回溯
  5. ✅ 对角线判断:|行差| == |列差| 就在同一条对角线上

📝 知识思维导图

N皇后问题
├── 问题定义
│   ├── N×N棋盘放N个皇后
│   └── 互不攻击(同行、同列、同对角线)
│
├── 解法一:数组法
│   ├── 用record数组记录每行皇后位置
│   ├── 逐行尝试 + 合法性检查
│   └── 时间O(n!),空间O(n)
│
├── 解法二:位运算法 ⚡
│   ├── 用int的位表示状态
│   ├── colLim、leftDiaLim、rightDiaLim
│   ├── pos = limit & ~(colLim | leftDiaLim | rightDiaLim)
│   └── 时间O(n!),空间O(1),速度快40倍
│
└── 核心算法:回溯
    ├── 做选择
    ├── 递归
    └── 撤销选择(回溯)

💪 最后记住一句话:

回溯算法就像走迷宫,走不通就退回来换条路,直到找到所有出口!


🔥 课后练习

基础题

  1. ✍️ 尝试手写4皇后的所有解(共2个)
  2. 💻 用解法一输出8皇后的所有方案(共92个)
  3. ⏱️ 对比两种方法在15皇后时的运行时间

进阶题

  1. 🤔 思考:为什么2皇后和3皇后没有解?
  2. 🎨 实现一个可视化版本,用图形界面展示皇后摆放过程
  3. 📊 画出N=4时的完整搜索树

挑战题

  1. 🏆 尝试用位运算实现16皇后问题(需要用long代替int)
  2. 🔍 优化:如何只输出一个解就停止?
  3. 💡 扩展:N皇后问题有多少个本质不同的解(去除旋转和对称)?

📚 扩展阅读

  • 相关算法:回溯算法、递归算法、位运算优化
  • 类似问题:数独问题、全排列问题、组合总和问题
  • 应用场景:约束满足问题(CSP)、密码学、电路板布线

🎉 恭喜你!掌握了N皇后问题,你就迈入了回溯算法的大门!

💬 觉得文章不错?点赞 + 收藏 + 分享,让更多人看到!

📝 有任何疑问或想法?欢迎在评论区留言讨论!


本文代码基于左程云老师《程序员代码面试指南》课程讲解,感谢左老师的精彩教学!

【N-Queen】N皇后问题(附完整C++代码) 问题分析 N皇后问题是比较经典的问题,它蕴含了回溯的思想,本文章利用回溯算法求解N皇后问题。 算法解析 ①本文章是逐行去搜索皇后的位置,每一行逐列检验该位置是否可以安放一个皇后,如果可以安放则记录列号;否则继续检索本行下一列。 for(int i=0;i<queenNum;i++){//一行中,逐列去检索 if(isAble(rowNum,i)){//检验该位置是否可以安放 column[rowNum] = i;//记录列号 findQueen(rowNum+1);//下一行对下 阅读详情

相关推荐

回溯算法经典案例 1 ——N皇后 Java

问题分析 N 皇后问题研究的是如何将 N 个皇后放置在 N×N 的棋盘上,并且使皇后彼此之间不能相互攻击。 皇后的走法是:可以横直斜走,格数不限。因此要求皇后彼此之间不能相互攻击,等价于要求任何两个皇后都不能在同一行、同一列以及同一条斜线上。 直观的做法是暴力枚举将 N 个皇后放置在 N×N 的棋盘上的所有可能的情况,并对每一种情况判断是否满足皇后彼此之间不相互攻击。暴力枚举的时间复杂度是非常高的,因此必须利用限制条件加以优化。 显然,每个皇后必须位于不同行和不同列,因此将 N个皇后放置在 N×N

AVOP_210的博客 3376

n皇后问题(回溯法)

目录 1.问题描述 2.问题分析 3.完整源码 1.问题描述 八皇后问题是十九世纪著名的数学家高斯于1850年提出的。问题是:在8×8的棋盘上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。可以把八皇后问题扩展到n皇后问题,即在n×n的棋盘上摆放n个皇后,使任意两个皇后都不能处于同一行、同一列或同一斜线上。 2.问题分析 确定问题状态:问题的状态即棋盘的布局状态 构造状态空间树:状态空间树的根为空棋盘,每个布局的下一步可能布局是该布局结点的子结..

qq_55168827的博客 5万+

一篇文章将三极管讲透:三极管从原理到应用,从参数到特性,从入门到精通

晶体三极管(Transistor)是一种半导体电子器件,也是电子工程中最基本的元件之一。它有三个区域,分别是P型半导体,N型半导体和P型半导体,从而形成PNP型晶体三极管或者NPN型晶体三极管。

学习帮的博客 9万+

acwing-843.n-皇后问题

题目描述 n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n,请你输出所有的满足条件的棋子摆法。 输入格式 共一行,包含整数 n。 输出格式 每个解决方案占 n 行,每行输出一个长度为 n 的字符串,用来表示完整的棋盘状态。 其中 . 表示某一个位置的方格状态为空,Q 表示某一个位置的方格上摆着皇后。 每个方案输出完成后,输出一个空行。 注意:行末不能有多余空格。 输出方案的顺序任意,只要不重复且没有

weixin_43211195的博客 1599

必看!DeepSeek从入门到精通!这11个高阶技巧,让你的效率提升10倍

DeepSeek从入门到精通!这11个高阶技巧,让你的效率提升10倍。掌握了上面说的这些技巧,你就能更有效率、更深入地用 DeepSeek 了。 AI 技术还在一直发展,DeepSeek 也会越来越厉害。 希望这份文档能帮你在 AI 这条路上迈出第一步,去探索更多有意思的东西!

AiBot 2709

MySQL从入门到精通、SQL实战题解

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。 MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是...

hestyle的博客 2722

【教程】玩转n8n:从入门到精通,打造自动化工作流平台

本文为n8n学习者和使用者提供一份详尽指南。n8n作为一款拥有超过54K Star的开源自动化工作流平台,支持400+节点,正成为数字化转型和AI应用落地的重要工具。文章从n8n基本概念入手,详细介绍Docker部署方法和汉化方案,并通过两个由浅入深的实例展示n8n在实际工作中的应用。无论您想构建简单的通知系统,还是复杂的AI驱动工作流,本文都将帮助您快速掌握n8n使用技巧,提升工作效率,实现业务自动化。

a18792721831的博客 1万+

UE5 SplineMesh与StaticMesh性能对比:生成1000米路径的帧率与内存实测

本文深度对比了UE5中SplineMesh与StaticMesh在生成1000米路径时的性能差异,包括帧率、内存占用及实现复杂度。实测数据显示,SplineMesh在Draw Call优化和动态变形场景中表现更优,而StaticMesh适合需要复杂材质变化的场景。文章还提供了优化技巧和选型指南,帮助开发者根据项目需求做出科学决策。

weixin_33976326的博客 318

Linux入门教程(非常详细)从零基础入门到精通,看完这一篇就够了!

学Linux就像打怪升级,刚开始可能被命令行吓到,但坚持一个月后,你会发现图形界面才是真正的"新手模式"!每个报错都是进步的机会(虽然有时候真的很想砸键盘…)。现在就打开你的Linux系统,开始敲命令吧!(如果还在用Windows?快去装个WSL!

kernelcraft的博客 1万+

AD9361 FIR 滤波器设计

matlab 得到滤波器系数

weixin_44630490的博客 1万+

手把手教你用GNU Radio和PlutoSDR搭建FM收音机(附完整流程图)

本文提供了一份详细的实践指南,教你如何使用GNU Radio和PlutoSDR搭建一个功能完整的FM收音机。从软硬件环境准备、核心流程图构建,到运行调试与效果优化,手把手带你完成从射频信号接收、下变频、FM解调到音频输出的全过程,是入门软件定义无线电(SDR)的绝佳实践项目。

weixin_29189377的博客 750

n8n邪修指南:无代码玩转数据流,三板斧搞定99%难题!大模型入门到精通,收藏这篇就足够了!

今天我要聊的这三个节点——Edit Fields、Split Out、Aggregate,看起来平平无奇,实际上是整个n8n数据流的"三板斧"。掌握它们,你基本可以扔掉Code节点了。

huang9604的博客 1752

Shell数学计算(算术运算,加减乘除运算)

声明: 本篇博客的学习途径主要为以下网站和课堂讲解,发博客目的仅为学习使用,在该博客的基础上做了一定程序的简略和修改。 参考博客 : 原文链接:http://c.biancheng.net/shell/ Shell数学计算Shell数学计算数学计算命令对整数进行数学运算: (()) / let / $[] /exprShell (())Shell let命令bc命令:一款数学计算器在 Shell 中使用 bc 计算器 Shell数学计算 默认情况下,Shell 不会直接进行算术运算,而是把+两边的数据(数

AKUANer的博客 2万+

收藏这篇就够了!12本大模型入门书籍,从理论到实践,帮你彻底搞懂!

大模型学习必读书单:12本入门指南 精选12本大模型与AI领域必读书籍,涵盖GPT、Transformer等核心技术。书单包括《基于GPT-3,ChatGPT,GPT-4等Transformer架构的自然语言处理》《大模型应用开发极简入门:基于GPT-4和ChatGPT》等,内容涉及自然语言处理、模型开发、机器翻译、图像生成等技术。这些书籍适合不同基础的读者,从原理讲解到实践应用,配套Python代码示例。完整版PDF资料可通过优快云免费获取,帮助开发者系统掌握大模型技术,适合用一年时间循序渐进学习。

libaiup的博客 1807

多智能体强化学习MATD3算法完整复现与分析

多智能体强化学习MATD3算法复现与分析摘要 MATD3算法是多智能体深度强化学习领域的重要进展,通过改进MADDPG算法,引入双Q学习、延迟策略更新和目标策略平滑等技术,显著提升了算法稳定性。本文完整复现了MATD3算法,详细解析了其数学原理,包括部分可观测马尔可夫博弈模型和TD3核心思想。在实现层面,设计了集中式Critic和分布式Actor的神经网络架构,采用PyTorch框架构建了Actor-Critic网络模块,包含精心设计的权重初始化和训练流程。该算法有效解决了多智能体环境中的非平稳性、信用分配

max500600的博客 530

第51节:cesium 范围查询(含源码+视频)

cesium 范围查询

qq_29384639的博客 1498

n8n AI第一课:核心概念与部署选择,大模型入门到精通,收藏这篇就足够了!

在这篇文章里,我会带你深入浅出地了解 n8n 这个超强神器,让你轻松打造属于自己的个人AI助手。准备好,和我一起让AI开口说人话吧!

Y525698136的博客 1217

ANSYS——模态分析的理论基础

ANSYS模态分析理论基础

python_AI_fans的博客 9089

一篇文章带你对全排列从入门到精通

从n个数中选取m个数的组合及全排列 题目描述: 给定两个整数n、m,输出从(1,2,…,n)中选出m个数的所有组合。 输入: 每个测试文件含有多个数据,输入两个整数n,m(0<m<=n<=10)。输入到文件末尾结束。 输出: 输出对应的组合数,每个组合中的数字由小到大排列,对于每组数据的所有组合按字典序排序 /下面这个组合代码能够满足字典排序输出 #include <iostream> using namespace std; int n, m, lst[10] = {0};

笑着的程序员的博客 5284

Windows 11 安装 Miniforge,配置国内源

本文详细介绍了在 Windows 11 系统中安装 Miniforge 的完整流程,包括下载、安装选项设置、配置国内镜像源(如清华大学源)以加速包管理,并启用 mamba 提升依赖解析与安装速度。同时涵盖 conda 与 mamba 的基本使用验证、PowerShell 初始化及环境提示符优化,帮助用户快速搭建高效、开源、免费的 Python 科学计算环境。

寒水馨 · 轻量级技术文档 · hanshuixin.org 4523

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

2025工作流革命!MCP让n8n听懂人话,RAG自动化从入门到精通一篇封神

配置一个从Salesforce到MySQL的数据同步工作流,3天都还没搞定。这是不是你刚接触n8n的样子?

m0_59163425的博客 2435

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

n8n完全指南:从入门到精通的工作流自动化实践

n8n完全指南:从入门到精通的工作流自动化实践

乐于分享,共同成长 3486

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

n8n vs Dify:工作流自动化与 AI 应用的终极对比,大模型入门到精通,收藏这篇就足够了!

本文将深入对比 n8n 和 Dify 的核心功能、适用场景、优劣势,帮助你做出明智选择。

huang9604的博客 1088

一文梳理主流热门 agent 框架:Dify、Coze、n8n、AutoGen、LangChain、CrewAI,大模型入门到精通,收藏这篇就足够了!

随着AI技术的不断进步,智能体框架也将继续演进,未来可能会出现更多专注于特定领域的垂直框架。开发者应密切关注这些框架的最新动态,选择最适合自身需求的工具,以充分发挥AI技术的潜力。

DEVELOPERAA的博客 1803

遗传算法实战:Python实现N皇后问题求解

遗传算法(GA)是一种基于自然选择与遗传机制的全局优化方法,其核心在于编码、适应度评估、选择、交叉与变异等操作构成的迭代进化过程。相比传统搜索,GA擅长处理组合爆炸、非线性、不可导的复杂优化问题,技术价值体现在强鲁棒性、无需梯度、易于并行化。典型应用场景包括路径规划、资源调度、排班优化及约束满足问题——其中N皇后问题正是检验GA建模能力的经典靶标:它将硬约束(行列对角线互斥)巧妙融入排列编码与冲突驱动的适应度函数中,避免惩罚项调参陷阱。本文聚焦Python工程实现,详解种群初始化、浮点安全的fitness设

weixin_33462167的博客 333

n8n邪修指南:别啃技术文档了,这才是掌握n8n最快的捷径!大模型入门到精通,收藏这篇就足够了!

我们称这条路为“正统修炼”,枯燥、漫长,天赋差点就容易走火入魔。但今天,我想私藏揭秘一条“邪修”之路。

2401_82469710的博客 1406
上一篇: 除权除息处理算法:当“公司行动“悄悄扰动你的交易指令(附完整复权因子表)
下一篇: 下降路径最小和问题
纳兰青华
博客等级 码龄8年 94粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值