índice
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!