DFS(Deapth-First-Seach)

概述

深度優先搜索算法是搜索算法中常見的算法。深度優先搜索屬於圖算法的一種,英文縮寫爲DFS即Depth First Search,其過程簡要來說是對每一個可能的分支路徑深入到不能再深入爲止,而且每個節點只能訪問一次。

基本思路

深度優先遍歷圖的方法是,從圖中某頂點v出發:

  1. 訪問頂點v;
  2. 依次從v的未被訪問的鄰接點出發,對圖進行深度優先遍歷;直至圖中和v有路徑相通的頂點都被訪問;
  3. 若此時圖中尚有頂點未被訪問,則從一個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過爲止。

有些問題我們不能找出確切的數學模型,即找不出一種直接求解的辦法,解決這一類問題,我們一般採用搜索算法。搜索就是按照一定規則用問題的所有可能方法去試探,直到找到問題的解。對於問題的第一個狀態,叫初始狀態,要求的狀態叫目標狀態。因此,搜索就是把規則應用到初始狀態,在其產生的狀態中找到目標狀態。產生新狀態的過程叫做擴展
搜索的要點:

  • 初始狀態
  • 重複產生新狀態
  • 檢查新狀態是否爲目標狀態

基本框架

dfs(狀態)
–if 狀態 是 目標狀態then
dosomething
–else
for 每個新狀態
–if 新狀態合法
»dfs(新狀態)
主程序:
dfs(初始狀態)

用C、C++的僞代碼描述爲

void dfs(狀態)
{
	if (狀態爲目標狀態)
	{
		處理解
	}
	else
	{
		for (每個新狀態)
		{
			if (新狀態合法)
			{
				dfs(新狀態);
			}
		}
	}
}

int main()
{
	dfs(初始狀態);
	return 0;
}

八皇后

八皇后問題是一個以國際象棋爲背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?爲了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。八皇后問題可以推廣爲更一般的n皇后擺放問題:這時棋盤的大小變爲n1×n1,而皇后個數也變成n2。而且僅當 n2 ≥ 1 或 n1 ≥ 4 時問題有解。
分析和詳解

8皇后的解爲92個。

#include <cstdio>
const int MAXN = 100;
int vis[MAXN][MAXN];//表示該點是否訪問過
int ans, n;
/**
* 判斷放置皇后的位置是否合法
* @parma r 皇后所在行
* @prama l 皇后所在列
* @return 合法返回true,非法返回false
*/
bool check(int r, int l)
{
	//橫縱
	for (int i = 0; i < n; ++i)
	{
		if (vis[r][i] || vis[i][l])
		{
			return false;
		}
	}
	//左上角
	for (int i = r-1, j = l-1; i >= 0 && j >= 0; --i, --j)
	{
		if (vis[i][j])
		{
			return false;
		}
	}
	//左下角
	for (int i = r+1, j = l-1; i < n && j >= 0; ++i, --j)
	{
		if (vis[i][j])
		{
			return false;
		}
	}
	//右上角
	for (int i = r-1, j = l+1; i >= 0 && j < n; --i, ++j)
	{
		if (vis[i][j])
		{
			return false;
		}
	}
	//右下角
	for (int i = r+1, j = l+1; i <n && j < n; ++i, ++j)
	{
		if (vis[i][j])
		{
			return false;
		}
	}
	return true;
}
void dfs(int row)
{
	if (row >  n - 1)
	{
		//輸出解,X代表皇后位置
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				if (vis[i][j])
				{
					printf("X");
				}
				else
				{
					printf("O");
				}
			}
			printf("\n");
		}
		printf("\n");
		ans++;
	}
	//擴展
	for (int i = 0; i < n; ++i)
	{
		if (check(row, i))
		{
			vis[row][i] = 1;
			dfs(row + 1);
			vis[row][i] = 0;
		}
	}
}
int main()
{
	scanf("%d", &n);
	dfs(0);
	printf("The number of %d queen question : %d\n", n, ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章