迷路の問題を解決するためのバックトラックアルゴリズム(C言語)

バックトラックはまた、ヒューリスティック、候補解と問題の大きさ1つずつテスト列挙特定の順序に制限を放棄する最初の質問として知られている。彼らは現在の候補解を見つけると、次の選択に、解決することはできません候補解、現在の候補ならば、問題の規模のリフティングは、現在の候補ソリューションの規模を拡大し、現在の候補解が問題の規模など、すべての要件を満たしている場合、テストに引き続き、ということを継続するために、他のすべての要件を満たし、要件を満たしていません。候補解の問題を解決する。バックトラックに、現在の候補ソリューションは、現在の候補ソリューションのサイズを拡張バックトラッキングと呼ばれる候補解を見つけるために、次の処理を放棄し、暫定的に前方になるためのプロセスをテストするために継続します。

プログラムを終了させることができることを確実にするため、調整に、数ある充填シーケンスを与えられていることを確認する必要がありませんモデル生成シーケンスを順次溶液が試験される候補に設定されている充填の数に応じて特定の順序を必要とする、テスト再度、この順に一つずつ、テスト候補を生成します。

迷路のために、私はそれを確実にするために、ソートする方法を解空間上のバックトラックの難しさで使用したいシーケンスの数が再びテストされていません。埋めるために断念した二次元の迷路では、開始点から始めて、各ポイントを隣人ドメインで計算は、フィルタから右、左の順、次の目標の検索で、道路が入力され、すなわち、決してバックポイント前方向に応じて、順序付けられたモデルを構成することができる。即ち迷路次の表

{1,1,1,1,1,1,1,1,1,1、
    0,0,0,1,0,0,0,1,0,1、
    1,1,0,1,0 、0,0,1,0,1、
    1,0,0,0,0,1,1,0,0,1、
    1,0,1,1,1,0,0,0,0,1 、
    1,0,0,0,1,0,0,0,0,0、
    1,0,1,0,0,0,1,0,0,1、
    1,0,1,1,1 、0,1,1,0,1、
    1,1,0,0,0,0,0,0,0,1、
    1,1,1,1,1,1,1,1,1,1 }

開始点から始めて、...すべての4つの方向は、フロントとセットポイントプラス1の方向、およびその上で背中合わせに行くする方法を探索していない場合は選択した点列は、次のポイントに順序付けられたシーケンスを構成する見つけるシーケンシャル...

 1  2  3  4  5  6  7  8  9  10
 バツ  1  1  1  2  3  3  3  2  ...
 と  0  1  2  2  2  3  4  4  ...
 C  1  1  3  3  1  1  2  1  ...

する#include <stdio.hに>
する#include <STDLIB.H>
の#define N1 10
の#define N2 10
のtypedef構造体ノード
{
int型は、x、x座標メモリ//
int型のy; // Yセーブ座標
INT Cを; //ポイントセーブ方向点に位置していてもよい、右、左に2アップ、3、右4,1表す
} linkstack。

トップlinkstack [100];
//ラビリンス行列
INT迷路[N1] [N2] = {1,1,1,1,1,1,1,1,1,1、
    0,0,0,1,0、 0,0,1,0,1、
    1,1,0,1,0,0,0,1,0,1、
    1,0,0,0,0,1,1,0,0,1、
    1,0,1,1,1,0,0,0,0,1、
    1,0,0,0,1,0,0,0,0,0、
    1,0,1,0,0、 0,1,0,0,1、
    1,0,1,1,1,0,1,1,0,1、
    1,1,0,0,0,0,0,0,0,1、
    1,1,1,1,1,1,1,1,1,1}。

INT I、J、K、M = 0。

メイン()
{
//初期化トップ[]、左へのすべての方向の数
(I = 0、I <N1 * N2; I ++)用
{
TOP [I] .C = 1;
}
のprintfは(「迷路は次のとおり/ N「);

//元のラビリンスマトリックス印刷
(; I <N1 I ++ I = 0)するための
{
 ため(J = 0; J <N2; J ++)
 のprintf(迷路[I] [J] "*":? "");
 のprintf ( "/ N-");
}
I = 0; TOP [I] .X = 1; TOP [I] .Y = 0;
迷路[1] [0] = 2;
/ *バックトラッキング* /
実行
{
 IF(トップ[I] .C <5) // ヒューリスティックは、さらに前方
 {
  IF(TOP [I] .X 5 && == TOP [I] == .Y。9)を見出した組み合わせ//
  {
   //印刷パス
   printf( "ウェイ%Dのは、次のとおり/ N-"、M ++);
   (; J、J = 0 <= I; J ++)
   {
    のprintf( "(%のD、%のD) - >"、トップ[J]。 X、トップ[J] .Y);
   }
   のprintf( "/ N-")。

   //選択されたパス迷路印刷
   用(J = 0; J <N1、J ++)
   {
    ため(K = 0; K <N2; K ++)
    {
     IF(迷路[J] [K] == 0)のprintf( " ");
     他IF(迷路[J] [K] == 2)のprintf(" O ");
     他のprintf(" * ");
    }
    のprintf(" "/ N-);
   }

   迷路[トップ[I] .X] [TOP [I]・Y] = 0;
   トップ[I] .C = 1。
   私 - ;
   トップ[I] .C + = 1;
   継続する;
  }
  スイッチ(TOP [I] .C)//向前试探
  {
   ケース1:
    {
     IF(迷路[TOP [I] .X] [トップ[I]・Y + 1] == 0)
     {
      I ++。
      トップ[I] .X = TOP [I-1] .X。
      トップ[I] .Y = TOP [I-1]・Y + 1。
      迷路[トップ[I] .X] [TOP [I] .Y] = 2;
     }
     他
     {
      トップ[I] .C + = 1;
     }
     ブレーク;
    }
   ケース2:
    {
     IF(迷路[TOP [I] .X-1] [TOP [I] .Y] == 0)
     {
      I ++。
      トップ[I] .X = TOP [I-1] .X-1。
      トップ[I] .Y = TOP [I-1] .Y。
      迷路[トップ[I] .X] [TOP [I] .Y] = 2;
     }
     他
     {
      トップ[I] .C + = 1;
     }
     ブレーク;
    }
   ケース3:
    {
     IF(迷路[TOP [I] .X] [TOP [I] .Y-1] == 0)
     {
      I ++。
      トップ[I] .X = TOP [I-1] .X。
      トップ[I] .Y = TOP [I-1]・Y-1。
      迷路[トップ[I] .X] [TOP [I] .Y] = 2;
     }
     他
     {
      トップ[I] .C + = 1;
     }
     ブレーク;
    }
   ケース4:
    {
     IF(迷路[TOP [I] .X + 1] [TOP [I] .Y] == 0)
     {
      I ++。
      トップ[I] .X = TOP [I-1]・X + 1。
      トップ[I] .Y = TOP [I-1] .Y。
      迷路[トップ[I] .X] [TOP [I] .Y] = 2;
     }
     他
     {
      トップ[I] .C + = 1;
     }
     ブレーク;
    }
  }
 }
 他//回溯
 {
  IF(I == 0)のリターン; //已找完所有解
  迷路[TOP [I] .X] [TOP [I]・Y] = 0;
  トップ[I] .C = 1。
  私 - ;
  トップ[I] .C + = 1;
 }
}、一方(1);
}

リリース元の4件の記事 ウォンの賞賛1 ビュー5545

おすすめ

転載: blog.csdn.net/robinhzp/article/details/316642
おすすめ