python数独求解_用Python解数独[7]:递归(完结篇)

本文详细介绍了使用Python实现数独求解的递归算法,通过递归函数解决复杂数独问题的过程,包括递归的原理及在数独解算中的应用。文章以一个中级难度的数独题目为例,展示了递归如何逐步找到正确答案。
摘要由CSDN通过智能技术生成

616fb55b6bb78e561ca21beb671335ba.png

目录

  1. 用Python解数独[0]
  2. 用Python解数独[1]:求每个单元格的行值域
  3. 用Python解数独[2]:求列值域和九宫格值域
  4. 用Python解数独[3]:求总值域
  5. 用Python解数独[4]:缩减值域
  6. 用Python解数独[5]:检测唯一值缩减值域
  7. 用Python解数独[6]:递归获得最终答案
  8. 用Python解数独[7]:递归(完结篇)

[2][2] 递归函数详解

这篇文章我们将详细讲一讲递归函数

# 检查值域列表是否合法:行检测,列检测,九宫格检测
def soduku_checkRepeat(s_value_range):
    temp_col = list(zip(*s_value_range))
    temp_matrix = matrix_invert(s_value_range)
    return row_checkRepeat(s_value_range) and row_checkRepeat(temp_col) and row_checkRepeat(temp_matrix)

# 计算值域列表取值总的组合数(各单元格值域长度相乘)
def sodukuRate(s_row_vrange):
    rate = 1
    for i in s_row_vrange:
        for j in i:
            rate *= len(j)
    return rate

# 主函数,输入值域列表,如遇到多个取值的单元格,依次尝试值域里的每个值,通过递归的方法检测值是否正确
def trial(total_value_range):
    for i in range(9):
        for j in range(9):
            if len(total_value_range[i][j]) > 1:
                for k in total_value_range[i][j]:
                    test_value = copy.deepcopy(total_value_range)
                    test_value[i][j] = [k]
                    test_value = reduce_totalValueRange(generator_soduku(test_value))
                    if soduku_checkRepeat(test_value):
                        if sodukuRate(test_value) == 1:
                            return test_value
                        else:    
                            if trial(test_value):
                                return trial(test_value)
                    else:
                        continue
                return False

我们先举几个简单的例子,看下什么是递归

#斐波那契数列通项公式
def f(n):
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        a =  f(n-1) + f(n-2)
        return a

斐波那契数列,用数学表达式就是:

f(1) = 1,f(2) = 1
若n>2,则f(n) = f(n-1)+f(n-2)

其实这里就已经应用了递归!若求f(5)的值,则必须求f(4)和f(3)的值,若求f(4)和f(3)的值,则需要求f(3),f(2)和f(2)和f(1)的值,f(2)和f(1)是我们已知的值,然后就可以依次求出f(3),f(4)直到f(5)的值。我们可以用数学表达式演示一下:

--> f(5) = f(4) + f(3)
--> f(4) = f(3) + f(2) , f(3) = f(2) + f(1)
--> f(3) = f(2) + f(1) , f(2) = 1 , f(2) = 1 , f(1) = 1
--> f(2) = 1 , f(1) = 1
--> f(3) = 2 , f(2) = 1 , f(2) = 1 , f(1) = 1
--> f(4) = 3 , f(3) = 2
--> f(5) = 5

我们举完例子再看一下“递归”的定义

程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。 [1]

这个斐波那契数列的例子,就用到了递归,当n > 2时,我们返回的不是一个常数,而是f(n-1)+f(n-2),即在f(n)中“直接或间接调用自身”。

我们再回到数独函数,在使用trial()递归函数之前,数独各个单元格的值域如下图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值