O problema das oito rainhas das notas de estudo da Lua

 

índice

1. Introdução ao blog

2. Conteúdo

3. Empurre

4. Conclusão


1. Introdução ao blog

Uma das notas de estudo de Lua, a escrita da versão Lua do problema das oito rainhas, um caso típico do algoritmo de backtracking, o editor usa Sublime

Nota: parte do código fonte deste blog é retirado da programação Lua (quarta edição) traduzida por Mei Longkui


2. Conteúdo

 

--检查(n,c)是否不会被攻击
function isplaceok(a,n,c)
	for i=1,n-1 do
		if (a[i] == c) or           --同一行
			(a[i]-i == c-n) or 		--对角线
			(a[i] + i == c+n) then	--对角线
			return false
		end
	end
	return true --不会被攻击
end

--打印棋盘
function printsolution(a)
	for i=1,8 do
		for j=1,8 do
			io.write(a[i]==j and "X" or "-"," ")
		end
		io.write("\n")
	end
	io.write("\n")
end

function addQueen(a,n)
	if n > 8 then
		printsolution(a)
	else
		for c=1,8 do
			if isplaceok(a,n,c) then
				a[n] = c
				addQueen(a,n+1)
			end
		end
	end
end

addQueen({},1)


-----------------------输出示例
X - - - - - - - 
- - - - X - - - 
- - - - - - - X 
- - - - - X - - 
- - X - - - - - 
- - - - - - X - 
- X - - - - - - 
- - - X - - - - 

O conteúdo é muito simples. Vejamos o código-fonte diretamente. A última função addQueen é o núcleo. Após a execução, ela produzirá todas as permutações e combinações que estão em conformidade com a regra das Oito Rainhas no console. Embora esta solução possa exibir todas as combinações que cumpram as regras, vamos observar o código principal. addQueen é equivalente a tentar organizar todas as colunas e todas as linhas da primeira coluna. Se não corresponder, descarte o conteúdo anterior. Isso é considerado exaustivo e não está em conformidade com o método de otimização de retrocesso. Modificaremos ligeiramente o código a seguir.

 

-----------------------------回溯算法 输出第一种满足情况

--当前列所处的位置
local colIndexList = {}
--上次回溯记录
local lastSucRow   = 0
-- 检查(n,c)是否不会被攻击
function isplaceok(a,n,c)
	for i=1,n-1 do
		if (a[i] == c) or           --同一行
			(a[i]-i == c-n) or 		--对角线
			(a[i] + i == c+n) then	--对角线
			return false
		end
	end
	return true --不会被攻击
end
--打印棋盘
function printsolution(a)
	for i=1,8 do
		for j=1,8 do
			io.write(a[i]==j and "X" or "-"," ")
		end
		io.write("\n")
	end
	io.write("\n")
end
function addQueen(col,recallTag)
	if col<1 then return end   									--小于1的列不执行
	if recallTag then   										--判断本次执行是否为回溯
		colIndexList[col] = nil									--回溯则当前序列表内值置空						
		if lastSucRow == 8 then									--回溯点已为当前列最大值则继续向前回溯
			lastSucRow = colIndexList[col-1] or 0
			addQueen(col-1,true)
			return
		end
	end
	for i=lastSucRow+1,8 do
		if isplaceok(colIndexList,col,i) then   				--符合要求停止循环
			colIndexList[col] = i
			if col == 8 then									--已够8列则输出
				printsolution(colIndexList)
			else							    				--不够则继续添加
				lastSucRow = 0									--设置回溯点
				addQueen(col+1)
			end	
			break
		else
			if i == 8 then										--改列没有满足的要求
				lastSucRow = colIndexList[col-1] or 0
				addQueen(col-1,true)							--回溯到上一列
			end
		end
	end
end
addQueen(1)

Melhoramos um pouco a escrita de addQueen. Aqui adicionamos duas variáveis, uma é a tabela colIndexList usada para registrar os dados atuais e a outra é a últimaSucRow usada para registrar o ponto de retrocesso. A ideia central de addQueen é que Eu começo com os dados na primeira linha da primeira coluna para iniciar o julgamento. Se as condições da regra das oito rainhas forem atendidas, os dados do ponto são registrados na colIndexList e o armazenamento é registrado como o ponto de retrocesso, e então o ponto na próxima coluna é julgado, se a próxima coluna Se houver um ponto que é satisfeito, continue, se o ponto não for satisfeito, você pode voltar ao ponto de retrocesso na coluna anterior para continuar a julgar. Se o comprimento dos dados chegar a 8, produza uma matriz quadrada. Esta forma de escrever produz o primeiro conjunto de dados que atende às condições. Adicionar alterações pode inserir qualquer quantidade de dados que atenda às regras.

 

--当前列所处的位置
local colIndexList 			= {}
--上次回溯记录
local lastSucRow   			= 0
local targetSucIndex 		= 100
local sucIndex 				= 0
-- 检查(n,c)是否不会被攻击
function isplaceok(a,n,c)
	for i=1,n-1 do
		if (a[i] == c) or           --同一行
			(a[i]-i == c-n) or 		--对角线
			(a[i] + i == c+n) then	--对角线
			return false
		end
	end
	return true --不会被攻击
end
--打印棋盘
function printsolution(a)
	for i=1,8 do
		for j=1,8 do
			io.write(a[i]==j and "X" or "-"," ")
		end
		io.write("\n")
	end
	io.write("\n")
end
function addQueen(col,recallTag)
	if col<1 then return end   									--小于1的列不执行
	if recallTag then   										--判断本次执行是否为回溯
		colIndexList[col] = nil									--回溯则当前序列表内值置空						
		if lastSucRow == 8 then									--回溯点已为当前列最大值则继续向前回溯
			lastSucRow = colIndexList[col-1] or 0
			addQueen(col-1,true)
			return
		end
	end
	for i=lastSucRow+1,8 do
		if isplaceok(colIndexList,col,i) then   				--符合要求停止循环
			colIndexList[col] = i
			if col == 8 then									--已够8列则输出
				sucIndex = sucIndex + 1
				printsolution(colIndexList)
				if sucIndex < targetSucIndex then				--不够则继续回溯
					lastSucRow = i
					addQueen(col,true)						    --回溯到上一列
				end
			else							    				--不够则继续添加
				lastSucRow = 0									--设置回溯点
				addQueen(col+1)
			end	
			break
		else
			if i == 8 then										--改列没有满足的要求
				lastSucRow = colIndexList[col-1] or 0
				addQueen(col-1,true)							--回溯到上一列
			end
		end
	end
end
addQueen(1)

Observe o código acima, fizemos pequenas alterações em comparação com o conjunto de códigos anterior, adicionando duas novas variáveis ​​targetSucIndex para determinar o número de matrizes quadradas de saída, sucIndex para registrar o número de dados de saída atuais, fazemos no método addQueen Depois a mudança, ele emitirá e parará a operação quando o comprimento de 8 dados for atingido. Agora, após a alteração, após o comprimento de 8 ser atingido, o ponto atual será usado como o ponto de retrocesso para continuar o cálculo, de modo que quando o número de dados de saída é menor que o número de destino, ele continuará. Para cálculo, observe que existem 92 tipos de condições, então não importa o tamanho de seus dados de destino, o cálculo ainda irá parar após a saída de todos os dados que atendem as regras.


3. Empurre

Github : https: //github.com/KingSun5


4. Conclusão

        Se você acha que o artigo do blogger está bem escrito, você pode querer prestar atenção nele e gostar da postagem do blog. Além disso, a capacidade do blogger é limitada. Se houver algum erro no artigo, comente e critique .

       Grupo de troca QQ: 806091680 (Chinar)

       Este grupo foi criado pelo blogueiro da CSDN Chinar, recomendo! Eu também estou no grupo!

Acho que você gosta

Origin blog.csdn.net/Mr_Sun88/article/details/105282338
Recomendado
Clasificación