回溯算法解决数独Lua实现

这里写图片描述


sudoko = {
	{8, 0, 0, 0, 0, 0, 0, 0, 0},  
	{0, 0, 3, 6, 0, 0, 0, 0, 0},  
	{0, 7, 0, 0, 9, 0, 2, 0, 0},  
	{0, 5, 0, 0, 0, 7, 0, 0, 0},  
	{0, 0, 0, 0, 4, 5, 7, 0, 0},  
	{0, 0, 0, 1, 0, 0, 0, 3, 0},  
	{0, 0, 1, 0, 0, 0, 0, 6, 8},  
	{0, 0, 8, 5, 0, 0, 0, 1, 0},  
	{0, 9, 0, 0, 0, 0, 4, 0, 0}
};  

function check(row,  line,number,matrix)
	--判断该行该列是否有重复数字  
	for  i = 1 ,9 do 
		if matrix[row][i] == number or  matrix[i][line] == number then
			return false
		end
	end
	--判断小九宫格是否有重复 
	local tempRow = math.ceil (row / 3)  - 1
	
	local  tempLine =math.ceil (line/ 3) - 1
	for  i = 1,3 do 
		for j = 1,3 do 
			if (matrix[tempRow * 3 + i][tempLine * 3 + j] == number) then

				return false
			end
		end
	end
	return  true
end

function printArray(matrix)
	for k,v in ipairs(matrix) do
		print(table.concat(v,","))
	end
end

function backTrace(i,j,matrix)
	--结尾
	if  i == 9 and  j  == 10   then
		printArray(matrix)
		return 
	end 
	--到达列尾
	if  j == 10   then
		j = 1
		i = i +1	
	end
	if  (matrix[i][j] == 0) then
		for  k = 1 ,9 do 
			if check(i, j, k,matrix) then
				matrix[i][j] = k
				backTrace(i, j + 1,matrix)
				--回溯还原
				  matrix[i][j] = 0; 
			end 
		end
		
	else 
		--下个位置
		backTrace(i, j + 1,matrix);  
	end
end 

backTrace(1,1,sudoko)
--优化版本
sudoko = {}
--初始化
sudoko.matrix = {
	{8, 0, 0, 0, 0, 0, 0, 0, 0},  
	{0, 0, 3, 6, 0, 0, 0, 0, 0},  
	{0, 7, 0, 0, 9, 0, 2, 0, 0},  
	{0, 5, 0, 0, 0, 7, 0, 0, 0},  
	{0, 0, 0, 0, 4, 5, 7, 0, 0},  
	{0, 0, 0, 1, 0, 0, 0, 3, 0},  
	{0, 0, 1, 0, 0, 0, 0, 6, 8},  
	{0, 0, 8, 5, 0, 0, 0, 1, 0},  
	{0, 9, 0, 0, 0, 0, 4, 0, 0}
};  
sudoko.count = 0

function sudoko:check(row,  line,number)
	local  matrix = self.matrix
	--判断该行该列是否有重复数字  
	for  i = 1 ,9 do 
		if matrix[row][i] == number or  matrix[i][line] == number then
			return false
		end
	end
	--判断小九宫格是否有重复 
	local tempRow = math.ceil (row / 3)  - 1
	local  tempLine =math.ceil (line/ 3) - 1
	for  i = 1,3 do 
		for j = 1,3 do 
			if (matrix[tempRow * 3 + i][tempLine * 3 + j] == number) then
				return false
			end
		end
	end
	return  true
end

function sudoko:printArray()
	local  matrix = self.matrix
	for k,v in ipairs(matrix) do
		print(table.concat(v,","))
	end
	print("统计backTrace调用次数:" .. self.count)
end

function sudoko:backTrace(i,j)
	local  matrix = self.matrix
	--统计函数调用次数
	self.count = self.count + 1
	--结尾
	if  i >= 9 and  j  >= 10   then
		self:printArray()
		return true
	end 
	--到达列尾
	if  j == 10   then
		i = i +1	
		j = 1 
	end
	if  (matrix[i][j] == 0) then
		for  k = 1 ,9 do 
			if self:check(i, j, k) then
				matrix[i][j] = k
				if self:backTrace(i, j + 1)    then
					return  true 
				end
				--回溯还原
				matrix[i][j] = 0; 
			end 
		end
	else 
		--下个位置
		return self:backTrace(i, j + 1);  
	end
end 


sudoko:backTrace(1,1)

优化之后backTrace函数调用次数72097次,之前3031697次
参考
http://blog.csdn.net/tianyaleixiaowu/article/details/50912924

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骇客之技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值