最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#用遞歸算法解決八皇后問題

 更新時間:2016年06月15日 10:34:49   作者:張玉彬  
在軟件編程中,這種思路確是一種解決問題最簡單的算法,它通過一種類似于蠻干的思路,一步一步地往前走,每走一步都更靠近目標(biāo)結(jié)果一些,直到遇到障礙物,我們才考慮往回走。

1.引子

  中國有一句古話,叫做“不撞南墻不回頭",生動的說明了一個人的固執(zhí),有點貶義,但是在軟件編程中,這種思路確是一種解決問題最簡單的算法,它通過一種類似于蠻干的思路,一步一步地往前走,每走一步都更靠近目標(biāo)結(jié)果一些,直到遇到障礙物,我們才考慮往回走。然后再繼續(xù)嘗試向前。通過這樣的波浪式前進(jìn)方法,最終達(dá)到目的地。當(dāng)然整個過程需要很多往返,這樣的前進(jìn)方式,效率比較低下。

2.適用范圍

  適用于那些不存在簡明的數(shù)學(xué)模型以闡明問題的本質(zhì),或者存在數(shù)學(xué)模型,但是難于實現(xiàn)的問題。

3.應(yīng)用場景

  在8*8國際象棋棋盤上,要求在每一行放置一個皇后,且能做到在豎方向,斜方向都沒有沖突。國際象棋的棋盤如下圖所示:

http://img.jbzj.com/file_images/article/201606/201606151029091.jpg

4.分析

  基本思路如上面分析一致,我們采用逐步試探的方式,先從一個方向往前走,能進(jìn)則進(jìn),不能進(jìn)則退,嘗試另外的路徑。首先我們來分析一下國際象棋的規(guī)則,這些規(guī)則能夠限制我們的前進(jìn),也就是我們前進(jìn)途中的障礙物。一個皇后q(x,y)能被滿足以下條件的皇后q(row,col)吃掉

1)x=row(在縱向不能有兩個皇后)

2)y=col(橫向)

3)col + row = y+x;(斜向正方向)

4)col - row = y-x;(斜向反方向)

遇到上述問題之一的時候,說明我們已經(jīng)遇到了障礙,不能繼續(xù)向前了。我們需要退回來,嘗試其他路徑。

我們將棋盤看作是一個8*8的數(shù)組,這樣可以使用一種蠻干的思路去解決這個問題,這樣我們就是在8*8=64個格子中取出8個的組合,C(64,80) = 4426165368,顯然這個數(shù)非常大,在蠻干的基礎(chǔ)上我們可以增加回溯,從第0列開始,我們逐列進(jìn)行,從第0行到第7行找到一個不受任何已經(jīng)現(xiàn)有皇后攻擊的位置,而第五列,我們會發(fā)現(xiàn)找不到皇后的安全位置了,前面四列的擺放如下:

http://img.jbzj.com/file_images/article/201606/201606151029092.png

第五列的時候,擺放任何行都會上圖所示已經(jīng)存在的皇后的攻擊,這時候我們認(rèn)為我們撞了南墻了,是回頭的時候了,我們后退一列,將原來擺放在第四列的皇后(3,4)拿走,從(3,4)這個位置開始,我們再第四列中尋找下一個安全位置為(7,4),再繼續(xù)到第五列,發(fā)現(xiàn)第五列仍然沒有安全位置,回溯到第四列,此時第四列也是一個死胡同了,我們再回溯到第三列,這樣前進(jìn)幾步,回退一步,最終直到在第8列上找到一個安全位置(成功)或者第一列已經(jīng)是死胡同,但是第8列仍然沒有找到安全位置為止

總結(jié)一下,用回溯的方法解決8皇后問題的步驟為:

1)從第一列開始,為皇后找到安全位置,然后跳到下一列

2)如果在第n列出現(xiàn)死胡同,如果該列為第一列,棋局失敗,否則后退到上一列,在進(jìn)行回溯

3)如果在第8列上找到了安全位置,則棋局成功。

8個皇后都找到了安全位置代表棋局的成功,用一個長度為8的整數(shù)數(shù)組queenList代表成功擺放的8個皇后,數(shù)組索引代表棋盤的col向量,而數(shù)組的值為棋盤的row向

量,所以(row,col)的皇后可以表示為(queenList[col],col),如上圖中的幾個皇后可表示為:

queenList[0] = 0;  queenList[1] = 3;   queenList[2] = 1;  queenList[3] = 4;   queenList = 2;

我們看一下如何設(shè)計程序:

首先判斷(row,col)是否是安全位置的算法:

bool IsSafe(int col,int row,int[] queenList)
{
 //只檢查前面的列
 for (int tempCol = 0; tempCol < col; tempCol++)
 {
  int tempRow = queenList[tempCol];
  if (tempRow == row)
  {
   //同一行
   return false;
  }
  if (tempCol == col)
  {
   //同一列
   return false;
  }
  if (tempRow - tempCol == row - col || tempRow + tempCol == row + col)
  {
   return false;
  }
 }
 return true;
}

設(shè)定一個函數(shù),用于查找col列后的皇后擺放方法:

/// <summary>
/// 在第col列尋找安全的row值
/// </summary>
/// <param name="queenList"></param>
/// <param name="col"></param>
/// <returns></returns>
public bool PlaceQueue(int[] queenList, int col)
{
 int row = 0;
 bool foundSafePos = false;
 if (col == 8) //結(jié)束標(biāo)志
 {
  //當(dāng)處理完第8列的完成
  foundSafePos = true;
 }
 else
 {
  while (row < 8 && !foundSafePos)
  {
   if (IsSafe(col, row, queenList))
   {
    //找到安全位置
    queenList[col] = row;
    //找下一列的安全位置
    foundSafePos = PlaceQueue(queenList, col + 1);
    if (!foundSafePos)
    {
     row++;
    }
   }
   else
   {
    row++;
   }
  }
 }
 return foundSafePos;
}

調(diào)用方法:

static void Main(string[] args)
{
 EightQueen eq = new EightQueen();
 int[] queenList = new int[8];
 for (int j = 0; j < 8; j++)
 {
  Console.WriteLine("-----------------"+j+"---------------------");
  queenList[0] = j;
  bool res = eq.PlaceQueue(queenList, 1);

  if (res)
  {
   Console.Write(" ");  
   for (int i = 0; i < 8; i++)
   {
    Console.Write(" " + i.ToString() + " ");  
   }
   Console.WriteLine("");
   for (int i = 0; i < 8; i++)
   {
    Console.Write(" "+i.ToString()+" ");      
    for (int a = 0; a < 8; a++)
    {       
     if (i == queenList[a])
     {
      Console.Write(" q ");
     }
     else
     {
      Console.Write(" * ");
     }
    }
    Console.WriteLine("");
      
   }
   
   Console.WriteLine("---------------------------------------");
  }
  else
  {
   Console.WriteLine("不能完成棋局,棋局失敗!");
  }
 }
 Console.Read();
}

遞歸算法PlaceQueue,完成這樣的功能:它尋找第col列后的皇后的安全擺放位置,如果該函數(shù)返回了false,表示當(dāng)前進(jìn)入了死胡同,需要進(jìn)行回溯,直到為0-7列都找

到了安全位置或者找遍這些列都找不到安全位置的時候終止。

用遞歸算法解決8皇后問題的示例程序:

http://xiazai.jb51.net/201606/yuanma/EightQueens(jb51.net).rar

相關(guān)文章

  • 使用C#代碼在PDF文檔中添加、刪除和替換圖片

    使用C#代碼在PDF文檔中添加、刪除和替換圖片

    在當(dāng)今數(shù)字化文檔處理場景中,動態(tài)操作PDF文檔中的圖像已成為企業(yè)級應(yīng)用開發(fā)的核心需求之一,本文 將介紹如何在.NET平臺使用C#代碼在PDF文檔中添加、刪除和替換圖片,需要的朋友可以參考下
    2025-04-04
  • C#最小二乘法擬合曲線成直線的實例

    C#最小二乘法擬合曲線成直線的實例

    這篇文章主要介紹了C#最小二乘法擬合曲線成直線的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Entity?Framework使用ObjectContext類

    Entity?Framework使用ObjectContext類

    這篇文章介紹了Entity?Framework使用ObjectContext類的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C# 配置文件app.config 和 web.config詳解

    C# 配置文件app.config 和 web.config詳解

    在 C# 的應(yīng)用開發(fā)中,配置文件就像是幕后的大管家,默默管理著應(yīng)用程序的各種設(shè)置,下面通過本文介紹 C# 中極為重要的兩個配置文件,app.config 和 web.config的相關(guān)知識,感興趣的朋友一起看看吧
    2025-04-04
  • C#中橋接模式的具體使用

    C#中橋接模式的具體使用

    橋接模式是一種結(jié)構(gòu)型設(shè)計模式,用于將抽象部分與實現(xiàn)部分分離,本文就來介紹一下C#中橋接模式的具體使用,感興趣的可以了解一下
    2024-11-11
  • C# .NET實現(xiàn)掃描識別圖片中的文字

    C# .NET實現(xiàn)掃描識別圖片中的文字

    本文以C#及VB.NET代碼為例,介紹如何掃描并讀取圖片中的文字。文中的示例代碼介紹詳細(xì),對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2021-12-12
  • C# 對XML基本操作代碼總結(jié)

    C# 對XML基本操作代碼總結(jié)

    C# 對XML基本操作包括讀取節(jié)點的數(shù)據(jù),添加節(jié)點。讀取節(jié)點屬性,修改節(jié)點屬性等
    2011-10-10
  • C#無限欄目分級程序代碼分享 好東西

    C#無限欄目分級程序代碼分享 好東西

    C#無限欄目分級程序代碼分享 好東西...
    2006-12-12
  • C#實現(xiàn)把指定數(shù)據(jù)寫入串口

    C#實現(xiàn)把指定數(shù)據(jù)寫入串口

    這篇文章主要介紹了C#實現(xiàn)把指定數(shù)據(jù)寫入串口,直接給出示例代碼,需要的朋友可以參考下
    2015-06-06
  • C#接口INotifyPropertyChanged使用方法

    C#接口INotifyPropertyChanged使用方法

    這篇文章介紹了C#接口INotifyPropertyChanged的使用方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01

最新評論

平安县| 汉中市| 海口市| 汝阳县| 龙门县| 双峰县| 城固县| 广宁县| 盐城市| 富锦市| 哈巴河县| 洛川县| 威宁| 千阳县| 泸州市| 裕民县| 香格里拉县| 宿迁市| 佛坪县| 灵石县| 曲水县| 平谷区| 栖霞市| 崇左市| 子洲县| 河东区| 彰武县| 平顺县| 巴林左旗| 武汉市| 云梦县| 湘阴县| 宁德市| 江津市| 三明市| 来安县| 黄冈市| 新巴尔虎右旗| 西平县| 突泉县| 新津县|