1.深さ優先検索
1.検索とは、初期状態とターゲット状態を知ることで問題の中間状態をたどるアルゴリズムを指します。一般的には、検索はより複雑な列挙です。
2.深さ優先検索は、深さ方向に検索することです。つまり、すべての実行可能な解決策を列挙し、問題の解決策が見つかるまで試行を続けます。
あなたが迷路にいると想像してください。出発点にいるときは、常にさまざまな分岐点を通過して迷路の終わりを見つける必要があります。次に、開始点から道路に沿って進みます。分岐点に遭遇したら、いずれかの分岐点を選択します。選択したフォークがフォークの前にある場合は、フォークに戻って別のフォークを選択します。フォークに新しいフォークがある場合は、上記のメソッドを再度実行して、エンドポイントを見つけられるようにします。つまり、道路で分岐点に遭遇したときは、常に「深さ」をキーとして進み、行き止まりに触れずに振り返ってはなりません。
さて、行き止まりに遭遇した後に最後のフォークに戻るこの方法は、バックトラックメソッドと呼ばれます。
2.深さ優先の検索バックトラッキング方式。
1.バックトラック方式とは、問題の特定の角度から開始し、考えられるすべての状況を検索し、それらの1つを新しい開始点として使用して、下方への探索を続行することです。最後に到達したら、最後の開始点に戻り、別の状況から検索を開始します。そして、目標を見つけるための継続的な「バックトラッキング」を通じて。
例:
数字の完全な配置:つまり、123の完全な配置は123,132,213,231,312,321です。つまり、1、2、3の3つの数字を使用して3桁の数字が形成され、数字の繰り返しは許可されません。
図に示すように、1、2、3の選択方法は、最初に1を選択し、次に2を選択し、最後に3を選択することを人為的に規定しています。次に、完全なアレンジを実行したい場合は、次のようになります。
最初の数値は最初のボックスであると規定します...というように、数値をボックスに入れるコード:
void dfs(int step)
{
for(i=1;i<=n;i++) //一共有n个数字,在这里,n=3
{
if(book[i]==0) //等于0表示这个数字还未被放入盒子中
{
a[step]=i; //将数字i放在第step个盒子
book[i]=1;
dfs(step+1); //放下一个数字
book[i]=0;
}
}
return;
}
つまり、終了基準は何ですか。つまり、n + 1番目の小さなボックスを処理する場合、それは前のn個のボックスが片付けられたことを意味し、この状況を出力します。つまり:
if(step==n+1)
{
for(i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
return;
}
完全なコードは次のとおりです。
#include<stdio.h>
int a[10],book[10],n;
void dfs(int step)
{
int i;
if(step==n+1)
{
for(i=1;i<=n;i++) //将这种情况打印出来
printf("%d ",a[i]);
printf("\n");
return;
}
for(i=1,i<=n;i++)
{
if(book[i]==0)
{
a[step]=i;
book[i]=1;
dfs(step+1);
book[i]=0;
}
}
return;
}
int main()
{
scanf("%d",&n);
dfs(1);
return 0;
}
3.ディープサーチの例、迷路を通り抜けます。
つまり、2次元配列を使用して迷路を格納し、迷路のサイズはn * m、終点の座標は(p、q)であり、始点から終点までの最短経路を見つけ、右、下、という順序を指定します。左、上。迷路を格納する2次元配列では、0は通過可能なパスを表し、1は障害物を表します。
コードは次のとおりです。
#include<stdio.h>
int n,m,p,q,min=1000000;
int a[20][20],book[20][20];
void dfs(int x,int y,int step) //x,y为当前点的横纵坐标,step表示已经走过的步数。
{
int next[4][2]={{0,1),{1,0},{0,-1},{-1,0}}; //分别为向右走,向下,向左,向上
int tx,ty,k; //tx,ty为下一个点的横纵坐标
if(x==p&&y==q) //判断是否到达终点
{
if(step<min)
min=step;
return;
}
for(k=0;k<=3;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)
{
book[tx][ty]=1;
dfs(tx,ty,step+1);
book[tx][ty]=0;
}
}
return;
}
int main()
{
int i,j,x,y;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]); //读入迷宫
scanf("%d %d %d %d",&x,&y,&p,&q); //读入起点和终点
book[x][y]=1; //标记起点已经走过了,防止重复走
dfs(x,y,0);
printf("%d ",min);
return 0;
}