質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2645閲覧

バックトラック法、及び再帰関数の仕組みを理解したい。(迷路問題を解く)

YasuhiroHorii

総合スコア11

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/10 07:55

編集2021/12/10 12:28

前提・実現したいこと

プログラミングの学習課題で再帰関数とバックトラック法を学ぶために簡単な迷路問題のコードを読んでいます。
ソースコードはすでに出来上がったものでちゃんとゴールまでのルートを表示してくれます。
しかし、「バックトラックしたあとに一度訪問したノードにまた進んでしまわないのか?」という疑問が生まれ、なかなかスッキリと解消できる説明が思い浮かびません。学習はじめたばかりの初歩の初歩的な質問で恐縮ですが、どなたか解説いただけると幸いです。
もし言葉足らずだったり、不足している情報があったらご指摘ください。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

ソースコード
#迷路 maze=           [[".",".",".","."] ,[".","x","x","x"] ,[".",".",".","x"] ,["x","x",".","."]] #迷路を表示 def print_maze(maze): for raw in maze: raw_print="" for value in raw: raw_print+= value + "" print (raw_print) #本題の迷路を解く関数(再帰関数とバックトラック) def solve_maze_helper(maze,sol,pos_row,pos_col): num_row=len(maze) num_col=len(maze[0]) #Base Case if pos_row==num_row-1 and pos_col==num_col-1: return sol if pos_row>=num_row or pos_col>=num_col: return None if maze[pos_row][pos_col]=='x': return None #Recursive Case #右に進む sol.append("r") sol_going_right=solve_maze_helper(maze,sol,pos_row,pos_col+1) if sol_going_right is not None: return sol_going_right #右にいけない>バックトラック>下に進む sol.pop() sol.append("d") sol_going_down=solve_maze_helper(maze,sol,pos_row+1,pos_col) if sol_going_down is not None: return sol_going_down #解なし>バックトラック sol.pop() return None

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2021/12/10 11:05

質問を編集して、コードは markdown 記法で ```コード``` というように囲ってください。
YasuhiroHorii

2021/12/10 12:30

失礼しました。チュートリアルを良く見ずに投稿してしまっていました。ご指摘感謝です。
guest

回答2

0

ベストアンサー

どこまで理解されているのかよくわからないので、さわりだけ。

この迷路は、とある場所に居るときに、次の行動が右と下にしか行かないルールです。これは、以下の2つしか迷路を進む手順が定義されていないことからわかります。

text

1 sol.append("r") 2 sol.append("d")

ということは、

「バックトラックしたあとに一度訪問したノードにまた進んでしまわないのか?」

については、「戻らないのだからそんなことは起きない 」ということです。

また、「バックトラックは戻るのでは」という認識かもしれませんが、そうではありません。
「右に行ってみて、その先に解がなければ、右に行かない」がバックトラックです。 その部分を解説するとこうです

python

1 sol.append("r") #右に行くことにする。 2 sol_going_right=solve_maze_helper(maze,sol,pos_row,pos_col+1) 右に行ってみる 3 if sol_going_right is not None: # 右に行って答えがあれば、 4 return sol_going_right # それが答え 5 #右にいけない>バックトラック>下に進む 6 sol.pop() # 右に行って答が無ければ右にいくのをやめる

バックトラックの説明で「引き換えす」というような説明をするし、ある意味そうなのですが、単に引き返すわけではなく、その「枝」を捨てるようにするのがポイントです。

少しは役に経つでしょうか。

投稿2021/12/10 15:14

TakaiY

総合スコア13790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YasuhiroHorii

2021/12/12 15:56 編集

回答ありがとうございます。 バックトラック=「戻る」というイメージが確かに根強くありました。ポイントは戻ることよりも、無駄な選択肢をどんどん減らしていくことにある、、一言で言えば消去法みたいなものでしょうか。 答えがない>バックトラック のときに、sol.pop() return None でその試行は除けられていくという理解であってますでしょうか。
TakaiY

2021/12/13 01:07

sol.pop()が2つありますが、その両方でその枝が切り取られているということですね。
YasuhiroHorii

2021/12/15 07:36

ありがとうございました。 再帰関数、バックトラックの挙動が自分の当初のイメージと大分違っていたのが分かって良かったです。 丁寧な解説感謝です。
guest

0

「バックトラックしたあとに一度訪問したノードにまた進んでしまわないのか?」

また進んでしまいます。そしてまた失敗して戻ってくるだけなので問題ありません。


1つ戻る>右or下に行ける選択肢がある>どちらも失敗>最初にふりだし と無限にループしたりしないのかな?とも思ったのですが、そうならずにいずれゴールにたどり着くよう軌道修正されるのは、上のコードだとどこで表現されているか教えていただけますでしょうか?

右に行った時と下に行った時では違うルートを通ることになります。同じノードに戻ってくるとは言っても、同じ経路で呼び出されることはないので無限に失敗し続けるということはありません。
呼び出されるまでの経路に注目してコードを読んでみてください。

投稿2021/12/10 12:02

編集2021/12/10 19:40
yudedako67

総合スコア2047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YasuhiroHorii

2021/12/10 13:47

回答ありがとうございます。 1つ戻る>右or下に行ける選択肢がある>どちらも失敗>最初にふりだし と無限にループしたりしないのかな?とも思ったのですが、そうならずにいずれゴールにたどり着くよう軌道修正されるのは、上のコードだとどこで表現されているか教えていただけますでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問