乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      迷宮中的老鼠

       長沙7喜 2019-06-29

      之前我們已經(jīng)討論了采用回溯(Backtracking)方法來解決國際象棋中馬的遍歷問題。

      為了讓大家更加熟悉回溯方法,我們將在后面的課程中再分析幾個例子。

      今天先看一個使用回溯方法解決老鼠走迷宮的問題。

      下圖是一個迷宮,其中涂上灰色的方格,老鼠不能進入,請找出老鼠從起點到終點的線路。老鼠只能向兩個方向移動:向前和向下,在下面的例子中也就是只能向右或向下移動。(注意,這是迷宮問題的一個簡單版本。 而在更復(fù)雜的版本中,老鼠可以在4個方向上移動或甚至可以跳著走)

      下圖表示一條從起點到終點的可行路徑。


      算法思路

      我們把老鼠迷宮問題做一個抽象。

      假設(shè)迷宮是一個N*N的二維矩陣(矩陣簡稱為M),矩陣中的每個元素M[i][j](0≤i≤N-1,0≤j≤N-1)是一個單元格方塊。

      其中最左上方的塊,即M[0][0]是老鼠出發(fā)的格子,而最右下的格子M[N-1][N-1]是它的出口。 

      問題就變成從格子M[0][0]開始,尋找到達(dá)M[N-1][N-1]的路徑。 

      在老鼠闖蕩迷宮矩陣的過程中,我們用0和1來表示老鼠是否可以進入某個方格。如果某方格M[i][j]被標(biāo)注為0,那么表示它是一個死胡同,老鼠無法進入該方格;而如果它被標(biāo)注為1,則表示老鼠可以進入它。

      因此上面的例子對應(yīng)的抽象矩陣為:

        {1, 0, 0, 0}

        {1, 1, 0, 1}

        {0, 1, 0, 0}

        {1, 1, 1, 1}

      樸素算法的思路

      樸素算法生成從起點格子到終點格子的所有路徑,并逐個檢查每個路徑是否能滿足約束條件。

      如有還有未經(jīng)驗證的路徑

      {

          生成下一條路徑

          如果此路徑的所有方格都為1

         {

             輸出這條路徑;

         }

      }

      樸素算法需要列舉所有可行的路徑,可能效率會不高,特別是迷宮比較大的時候。

      回溯算法的思路

      下面是回溯算法的解題思路。

      從起點方格開始,如果當(dāng)前所在的方格已經(jīng)是終點方格

           打印輸出找到的路徑矩陣,結(jié)束

      否則

          a)將當(dāng)前方格標(biāo)記為1

          b)在水平方向向右移動一個方格并遞歸檢查是否該移動可以找到解

          c)如果在上述步驟中選擇的移動沒有找到解

               那么向下移動一個方格并并遞歸檢查此移動是否可以找到解

         d)如果上述方法都不起作用,則將該方格標(biāo)記為0,表示需要回退(Backtracing)并返回false

      代碼實現(xiàn)

      以下是老鼠迷宮問題的c/C++代碼實現(xiàn)。 它以二維矩陣形式打印出一種可能的解決方案。 最后的輸出是一個矩陣,顯示為1的格子是老鼠經(jīng)過的格子。

      #include <stdio.h> 

      // 迷宮大小 

      #define N 4 

      bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N]); 

      /* 該函數(shù)可以輸出找到的解矩陣[N][N] */

      void printSolution(int sol[N][N]) 

          for (int i = 0; i < N; i++) { 

              for (int j = 0; j < N; j++) 

                  printf(' %d ', sol[i][j]); 

              printf('\n'); 

          } 

      /* 該函數(shù)檢查坐標(biāo)(x,y)是否是一個有效的方格 */

      bool isSafe(int maze[N][N], int x, int y) 

          // 如果(x,y)超出了迷宮的范圍返回false 

          if (x >= 0 && x < N && y >= 0 && y < N && maze[x][y] == 1) 

              return true; 

          return false; 

      /*

      使用回溯算法解決迷宮問題。主要思路:

      使用solveMazeUtil()來尋找路徑。 如果沒有找到可行的路徑,則返回false

      否則返回true并打印出找到的路徑(采用1來表示)

      請注意,可能有多個解決方案,這里只找出一個可行的解決方案

      */

      bool solveMaze(int maze[N][N]) 

          int sol[N][N] = { { 0, 0, 0, 0 }, 

                            { 0, 0, 0, 0 }, 

                            { 0, 0, 0, 0 }, 

                            { 0, 0, 0, 0 } }; 

          if (solveMazeUtil(maze, 0, 0, sol) == false) { 

              printf('Solution doesn't exist'); 

              return false; 

          } 

          printSolution(sol); 

          return true; 

      /*采用遞歸函數(shù)來解決迷宮問題*/

      bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N]) 

          //如果(x,y)正好是目標(biāo)方格,那么返回true 

          if (x == N - 1 && y == N - 1) { 

              sol[x][y] = 1; 

              return true; 

          } 

          //檢查(x,y)是否是一個合法的方格

          if (isSafe(maze, x, y) == true) { 

              // mark x, y as part of solution path 

              //把(x,y)標(biāo)記為路徑中的一個方格

              sol[x][y] = 1; 

              /*向x方向,也就是右邊移動*/

              if (solveMazeUtil(maze, x + 1, y, sol) == true) 

                  return true; 

              /* 如果向x方向移動,沒有找到合適的路徑,那么,改向y方向,也就是向下移動*/

              if (solveMazeUtil(maze, x, y + 1, sol) == true) 

                  return true; 

              /* 如果以上的移動步驟,無法找到路徑,那么,將(x,y)標(biāo)記為0*/

              sol[x][y] = 0; 

              return false; 

          } 

          return false; 

      // 主程序

      int main() 

          int maze[N][N] = { { 1, 0, 0, 0 }, 

                             { 1, 1, 0, 1 }, 

                             { 0, 1, 0, 0 }, 

                             { 1, 1, 1, 1 } }; 

          solveMaze(maze); 

          return 0; 

      輸出的樣子如下:

       1  0  0  0 

       1  1  0  0 

       0  1  0  0 

       0  1  1  1 

      請你試著運行看看是否能得到正確的答案。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多