遗传算法解决数独suduko难题,附python代码实现

定义
数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复 。
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。
算法思想
遗传算法,具体思想感兴趣的可以百度下,这里主要讲解每个部分如何设置。

代码实现:

# -*- coding: utf-8 -*-
# @Time    : 2022/5/4 10:01
# @Author  : kunkun
# @File    : algorithm4_impr.py
# ------------------------------
# 遗传算法改进
import random
import time

rows = 'ABCDEFGHI'  # 行标号
cols = '123456789'  # 列标号

"""
    对于每一个空,除去自己
    可填列 col = 8 ,可填行 row = 8, block = 3,总数 8+8+3=19
    一共有81个空
    最大分数 score = 19 * 81 = 1539
"""
max_score = 200  # 1539  # 适应度评分?c

var_rate = 0.1  # 变异率
quan = 1000  # 种群成员个数
times = 500  # 遗传最大代数

total_score = []
"""
    准备部分
"""


# 把行列链接,给每个格子编号
def cross(a, b):
    return [s + t for s in a for t in b]


# 格子编号
boxes = cross(rows, cols)
# boxes = ['A1', 'A2', 'A3', 'A4', 'A5', 'A6'...]
# 每一行、列、九宫格的标号
row_units = [cross(r, cols) for r in rows]
# row_units = [['A1', 'A2', 'A3', 'A4', 'A5', 'A6',...],...]
column_units = [cross(rows, c) for c in cols]
# colum_units = [['A1', 'B1', 'C1', 'D1', 'E1', 'F1',...],...]
square_units = [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in ('123', '456', '789')]
# [['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2',...],...]
# 链接
unitlist = row_units + column_units + square_units
# 每一个空所在的行列九宫格元素
units = dict((s, [u for u in unitlist if s in u]) for s in boxes)
# units = {'A1': [['A1', 'A2', 'A3', 'A4', 'A5', 'A6',...], ['A1', 'B1', 'C1', 'D1', 'E1', 'F1',...], ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2',...]],...]
# 每一个空的需要不重复的位置
peers = dict((s, set(sum(units[s], [])) - set([s])) for s in boxes)
# peers = {'A1': {'A6', 'C1', 'C2', 'D1', 'E1', 'A2', 'A3', 'B1', 'F1', 'B2', 'A5', 'A4',...},...]
# 不能和A1重复的位置


"""
    打印部分
"""


# 输入:sudoku 字典
# 输出:打印结果
def display(values):
    width = 3
    line = '+'.join(['-' * (width * 3)] * 3)
    for r in rows:
        print(''.join(str(values[r + c]).center(width) + ('|' if c in '36' else '')
                      for c in cols))
        if r in 'CF':
            print(line)
    return


# Input: sudoku string
# Output: sudoku dict
#        Keys: 'A1/A2...'
#        Values: '1-9' or "."
# return {'A1': '1', 'A2': '-', 'A3': '-', 'A4': '3', 'A5': '-',...]
def grid_values(grid):
    chars = []
    digits = '123456789'
    for c in grid:
        if c in digits:
            chars.append(c)
        if c == '.':
            chars.append("-")
    # assert len(chars) == 81
    return dict(zip(boxes, chars))


"""
    种群制造部分
"""


# Input: sudoku string
# Output: sudoku dict.
# return {'A1': 1, 'A2': 5, 'A3': 4, 'A4': 3, 'A5': 5, 'A6': 6, 'B1': 2, 'B2'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值