前向检测+启发式(约束满足问题) LeetCode37. Sudoku Solver

约束满足问题

约束满足问题简称CSP问题(Constraint Satisfaction Problem)。
CSP问题表示一组具有约束条件的变量集。它可以定义为一个三元组<V, D, C>,其中,V表示变量的集合,D表示各个变量域的集合,C表示约束条件的集合。
局部状态是对一些变量的一个赋值,目标状态则是对所有变量的一个赋值。求解CSP问题就是给定局部状态求解目标状态。

前向检测解决CSP问题

前向检测是一种深度优先搜索策略,它是回溯法的一种扩展。它采用了“向前看”的策略,即对一个变量进行赋值时,修改约束条件下相关变量的值域。其过程如下:
1. 选择一个变量。
2. 遍历变量值域。
3. 根据变量的赋值,调整相关变量的值域空间。若不会导致DWO(Domain Wipe Out)则往下递归。
4. 若有解则结束。否则恢复相关变量的值域空间,并回到步骤2。
5. 该局部状态无解
对于步骤1选择变量,可使用启发式搜索优化。如MRV启发式,优先选择值域空间小的变量。)

LeetCode37. Sudoku Solver

数独问题可以抽象为一个CSP问题。每个格子代表一个变量;变量的值域都是1~9;约束条件是同行同列同九宫格不可有相同取值。
使用前向检测+MRV启发式搜索求解。

思路

启发式搜索指每次选择取值范围最小的那个格子。前向检测则是每填一个格子,就调整其他格子的取值范围。以此过程递归回溯即可。

核心步骤

  1. 取值域最小的格子
  2. 保存当前状态(值域)
  3. 遍历格子的值域
  4. 对格子进行赋值,并修改相关变量值域。
  5. 递归搜索,有解返回。无解恢复状态。回到第三步
  6. 无解返回。

代码

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;


// 格子0~8 * 0~8, 取值1~9
class Solution {
   
    public:
        void solveSudoku(vector<vector<char>>& board) {
   
            init(board);
            solve(board);
        }

        bool solve(vector<vector<char>>& board)
        {
   
            // 取一个格子
            pair<int, int> cell = selectCell(board);
            if (cell.first == -1 && cell.second == -1) return true;
            if (domain[cell.first][cell.second][0] == 0) 
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值