定义
数独是源自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'