El problema de las ocho reinas de las notas de estudio de Lua

 

Tabla de contenido

1. Introducción al blog

2. Contenido

3. Empuje

4. Conclusión


1. Introducción al blog

Una de las notas del estudio de Lua, la redacción de la versión Lua del problema de las ocho reinas, un caso típico del algoritmo de retroceso, el editor usa Sublime

Nota: parte del código fuente de este blog está tomado de la programación de Lua (cuarta edición) traducido por Mei Longkui


2. Contenido

 

--检查(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 - - - - 

El contenido es muy simple. Veamos el código fuente directamente. La última función addQueen es el núcleo. Después de ejecutarse, generará todas las permutaciones y combinaciones que cumplan con la regla de las ocho reinas en la consola. Aunque esta solución puede generar todas las combinaciones que cumplen con las reglas, observemos el código central. addQueen es equivalente a intentar ordenar cada columna y cada fila de la primera columna. Si no coincide, descarte el contenido anterior. Esto se considera exhaustivo y no se ajusta a el método de optimización de retroceso. Modificaremos ligeramente el código a continuación.

 

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

--当前列所处的位置
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)

Hemos mejorado ligeramente la escritura de addQueen. Aquí hemos agregado dos variables, una es la tabla colIndexList usada para registrar los datos actuales, y la otra es la lastSucRow usada para registrar el punto de retroceso. La idea central de addQueen es que Empiezo desde Los datos de la primera fila de la primera columna para iniciar el juicio. Si se cumplen las condiciones de la regla de las ocho reinas, los datos del punto se registran en colIndexList y la tienda se registra como el punto de retroceso, y luego se juzga el punto en la siguiente columna, si la siguiente columna Si hay un punto que está satisfecho, continúe, si el punto no está satisfecho, puede volver al punto de retroceso en la columna anterior para continuar juzgando. Si la longitud de los datos alcanza 8, entonces genera una matriz cuadrada. Esta forma de escribir genera el primer conjunto de datos que cumple con las condiciones. Al agregar cambios, se puede ingresar cualquier cantidad de datos que cumpla con las reglas.

 

--当前列所处的位置
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)

Mire el código anterior, hemos realizado cambios menores en comparación con el conjunto de códigos anterior, agregando dos nuevas variables targetSucIndex para determinar el número de matrices cuadradas de salida, sucIndex para registrar el número de datos de salida actuales, lo hacemos en el método addQueen Después el cambio, generará y detendrá la operación cuando se cumpla la longitud de 8 datos. Ahora, después del cambio, después de que se cumpla la longitud de 8, el punto actual se utilizará como punto de retroceso para continuar el cálculo, de modo que cuando el número de datos de salida es menor que el número de destino, continuará Para el cálculo, tenga en cuenta que hay 92 tipos de condiciones, por lo que no importa cuán grandes sean los datos de destino, el cálculo se detendrá después de generar todos los datos que cumplan las normas.


3. Empuje

Github: https: //github.com/KingSun5


4. Conclusión

        Si crees que el artículo del blogger está bien escrito, es posible que desees prestar atención al blogger y dar me gusta a la publicación del blog. Además, la capacidad del blogger es limitada. Si hay algún error en el artículo, comenta y critica. .

       Grupo de intercambio QQ: 806091680 (Chinar)

       Este grupo fue creado por el blogger de CSDN Chinar, ¡lo recomiendo! ¡Yo también estoy en el grupo!

Supongo que te gusta

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