Diseño del programa examen final examen tema tres: búsqueda

El tercer tema es el algoritmo de búsqueda.

Existen muchos algoritmos de búsqueda, como la búsqueda de profundidad primero (dfs), la búsqueda de amplitud primero (bfs), el algoritmo A *, etc. En este tema, me esfuerzo por hacer que dfs y bfs me resulten más familiares. Y algunas optimizaciones de poda.

(1) Búsqueda de profundidad primero

Para encontrar una solución al problema, comience desde el nodo inicial, encuentre su siguiente nodo y luego continúe buscando a lo largo de este nodo hasta que no haya otro nodo, regrese a su nodo principal y mire a sus otros nodos secundarios Si es así, descienda este subnodo; de lo contrario, continúe rastreando. Hasta que se atraviesen todos los nodos.

Por ejemplo: Higo   Comenzando desde A: A-> B-> E-> C-> F-> H-> G-> D. Esta es una secuencia transversal.

Este es el proceso de búsqueda de búsqueda en profundidad.

Implementación: generalmente implementado con ideas recursivas o pilas .

Para el problema del laberinto, ingrese una matriz bidimensional para representar un laberinto. Un valor de 1 en el laberinto significa caminar, y un valor de 0 significa no caminar. Es necesario encontrar una ruta desde la esquina superior izquierda a la esquina inferior derecha. (Significado general)

Ejemplo: problema de laberinto poj3984 ( https://vjudge.net/problem/POJ-3984)

Esta pregunta especifica una matriz bidimensional de 5X5, "0" significa caminar, "1" significa no caminar, requiere una ruta más corta desde (0, 0) a (4, 4).

Solución del problema: si usa el método de búsqueda de profundidad primero para resolver el problema, debe usar la recursividad.

Sin embargo, la clave para la recursividad son las condiciones para ingresar a la recursión y salir de la recursividad la próxima vez.

La condición para que este problema ingrese la próxima vez de forma recursiva es que el siguiente nodo puede caminar y no ha caminado antes y no ha llegado al final.

Y la condición para la terminación recursiva es: hasta el final.

Entonces, la solución de esta pregunta es dfs:

Código:

#include<iostream>
using namespace std;

int map[5][5];
int nx[4]={0,1,0,-1};
int ny[4]={1,0,-1,0};
int ans=1e9;
bool final[5][5];
bool vis[5][5];
int cnt=0;

void dfs(int steps,int x,int y)
{
	if(x==4&&y==4)  //终止条件,并且记录最短路径 
	{
		if(steps<ans)
		{
			ans=steps;
			for(int i=0;i<5;i++)
				for(int j=0;j<5;j++)
			    	final[i][j]=vis[i][j]; 	   
		}
		return ;
	}
	int xn,yn;
	for(int i=0;i<4;i++)  
	{
		xn=x+nx[i];yn=y+ny[i];
		if(xn>=0&&xn<=4&&yn>=0&&yn<=4&&!map[xn][yn]&&!vis[xn][yn])
		{
			vis[xn][yn]=true;   //更改为true,不能再走 
			dfs(steps+1,xn,yn);  //递归下去 
			vis[xn][yn]=false;  //为之后记录更短路径 
		}
	}
	return ;
}

int main()
{
	for(int i=0;i<5;i++)
	{
		for(int j=0;j<5;j++)
		{
			cin>>map[i][j];
			vis[i][j]=0;
		}
	}
	dfs(0,0,0);
	cout<<"(0, 0)"<<endl;
	for(int i=0;i<5;i++)
	{
		for(int j=0;j<5;j++)
		{
			if(final[i][j])
			    cout<<"("<<i<<", "<<j<<")"<<endl;
		}
	}
	return 0;
 } 

Preste atención a la redacción de la recursividad y configure la matriz de vis de verdadero a falso para registrar el camino más corto, debido a la naturaleza de la recursividad: el viaje anterior al final no volverá de nuevo. Con este entendimiento, el código que escribí es mucho más simple que mi código anterior.

(2) Búsqueda de amplitud primero

La idea de la búsqueda de amplitud es comenzar desde un nodo, encontrar todos los nodos que este nodo puede alcanzar, registrarlos y atravesar estos nodos en secuencia. Y en el proceso de atravesar, encuentre todos los nodos que estos nodos puedan alcanzar y regístrelos. Luego atraviese estos nodos a su vez, y encuentre todos los nodos que estos nodos puedan alcanzar, regístrelos ... siga atravesando de esta manera hasta que todos los nodos hayan sido atravesados ​​o encuentre los nodos que cumplan con los requisitos del problema.

Por ejemplo: la Higo   secuencia transversal a partir de A: A-> B-> C-> D-> E-> F-> G-> H.

Este es el proceso de búsqueda más amplio.

Implementación de bfs: las colas generalmente se usan para acceder a los nodos. Si desea generar la ruta, puede usar el puntero para acceder al estado intermedio.

Nota: La búsqueda de ruta implementada por bfs debe ser la más corta, por lo que la ruta óptima generalmente es manejada por bfs.

Ejemplo: lo mismo es el problema del laberinto anterior (poj3984)

Código:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;

int map[5][5];
int nx[4]={0,1,0,-1};
int ny[4]={1,0,-1,0};
int res;
bool vis[5][5];

struct point
{
	int x,y;
	//point(int n,int m):x(n),y(m)
	//{	};
	point *last;
};

point* bfs()
{
	queue<point *>q;
	point *ans=new point;
	ans->x=0,ans->y=0;
	ans->last=NULL;
	q.push(ans);
	vis[0][0]=true;
	while(!q.empty())
	{
		ans=q.front();q.pop();
		if(ans->x==4&&ans->y==4) return ans;
		int xn,yn;
		for(int i=0;i<4;i++)
		{
			xn=ans->x+nx[i];yn=ans->y+ny[i];
			if(xn>=0&&xn<=4&&yn>=0&&yn<=4&&!map[xn][yn]&&!vis[xn][yn])
			{
				point *e = new point;
				e->x=xn,e->y=yn;
				e->last=ans;
				q.push(e);
				vis[xn][yn]=true;
			}
		}
	}
	return NULL;
}
void output(point *s)
{
	if(s==NULL) return ;
	output(s->last);
	cout<<"("<<s->x<<", "<<s->y<<")"<<endl;
}

int main()
{
	for(int i=0;i<5;i++)
	{
		for(int j=0;j<5;j++)
		{
			cin>>map[i][j];
			vis[i][j]=0;
		}
	}
	output(bfs());
	return 0;
}

Consulte el proceso de salida (aplicación de puntero): https://blog.csdn.net/acmer_sly/article/details/52492245

Lo anterior es la aplicación básica de dfs y bfs. Y dfs tiene un método de optimización: optimización de poda (menos el estado intermedio que no alcanzará el objetivo durante el proceso intermedio).

Optimización de poda :

Por ejemplo: agregue otro juicio después de juzgar si se cumplen las condiciones.

if(steps>ans) return ;

Esto hará que después de encontrar una ruta, después de que se asigne ans, en la búsqueda dfs posterior, si el número de pasos es mayor que el número de pasos de los ans encontrados anteriormente. Entonces, estos pasos adicionales se pueden descartar. Debido a que solicitamos encontrar la ruta más corta, si la cantidad de pasos es mayor que la cantidad de pasos encontrados para una ruta completa, ya no necesitamos considerar esta nueva ruta.

Otra poda: si el paso actual, la posición del punto de búsqueda actual más el número más corto de pasos para llegar al punto final son mayores que el resultado anterior ans, entonces esta ruta no necesita ser considerada. El código es el siguiente:

if((steps+abs(x-4)+abs(y-4))>ans) return ;

(3) algoritmo A *

Un * algoritmo de búsqueda, para no repetir. La idea principal es utilizar un criterio para juzgar el movimiento de cada paso. Este estándar es F, F = G + H. G representa el costo de moverse desde el punto de partida a la posición actual. H representa el costo de la ruta óptima desde la ubicación actual a la ubicación de destino. La F obtenida al sumar estos dos costos se usa para juzgar el próximo movimiento. Finalmente alcanzar la posición de destino. Luego use el puntero para atravesar el camino más corto.

Recomiende un documento, lo leí para comprender el algoritmo A *: https://blog.csdn.net/hitwhylz/article/details/23089415

 

Busque también la pregunta clásica: La pregunta de las ocho reinas.

Hay muchas respuestas detalladas a las preguntas de las Ocho Reinas en el blog. No las repetiré aquí. Elegí algunos blogs que entiendo:

El primer artículo no usó recursividad. Sin embargo, las condiciones de juicio en bucle, como while y if, se usan perfectamente.A través del juicio en bucle, se completa la búsqueda de una solución viable. Continúe buscando la siguiente solución retrocediendo. El código es muy refinado, puedes entenderlo mirando cuidadosamente.

https://blog.csdn.net/qq_326324545/article/details/80919368  

El segundo capítulo tiene algoritmos no recursivos y algoritmos recursivos. Sugiero mirar el algoritmo recursivo, que es casi la misma idea que la anterior, pero utiliza la recursividad. El código es más simplificado.

https://www.cnblogs.com/yjd_hycf_space/p/6670316.html

 

Bueno, el algoritmo de búsqueda está escrito aquí, el examen final llegará pronto, no tengo mucho tiempo ~~

 

 

 

 

 

Publicado 6 artículos originales · me gusta 0 · visitas 184

Supongo que te gusta

Origin blog.csdn.net/morning_zs202/article/details/92415046
Recomendado
Clasificación