バックトラッキングアルゴリズム - ロボットの動作範囲

バックトラッキングアルゴリズム - ロボットの動作範囲

[[415476]]

この記事はWeChatの公開アカウント「Magic Programmer K」から転載したもので、著者はMagic Programmer Kです。この記事を転載する場合は、マジカルプログラマーKの公開アカウントまでご連絡ください。

序文

行列があります。ロボットは座標 (0,0) のグリッドから移動を開始できます。ロボットは一度に 1 つのグリッドを左、右、上、または下に移動できますが、行と列の座標の合計が K より大きいグリッドには入ることができません。ロボットが移動できるグリッドの合計数と移動軌跡を求めます。

この記事では、この問題の解決策を紹介します。興味のある開発者は、ぜひこの記事をお読みください。

実装のアイデア

マトリックス内のパスの検索に関する前回の記事では、バックトラッキング アルゴリズムを使用してマトリックス内のグリッドにアクセスする方法を学びました。この記事で説明する問題は、グリッドにアクセスする前に判断のレイヤーを作成します。条件が満たされている場合は入力できますが、そうでない場合は入力できません。

私たちが下すべき判断は、訪問するグリッドの座標の桁の合計を計算することです。それが K (最大アクティビティ範囲) より大きい場合、訪問できません。

桁の合計: 数値内の各位置の値の合計と値の合計。たとえば、19 の数字の合計は 1 + 9 = 10 です。

現在のグリッドが訪問されたかどうかを判定する

まず、ロボットがこのグリッドまで歩いたかどうかを示すために、元の行列と同じサイズの行列を作成する必要があります。

js では指定サイズの 2 次元配列を直接作成することはできません。作成の考え方は以下のとおりです。

  • 行列の長さを持つ配列を作成する
  • 作成した配列を走査し、行列の0番目の配列の長さをサイズとする配列を作成し、走査した各項目に値を割り当てます。

グリッドにアクセスできるかどうかを判断する

グリッドにアクセスするときは、アクセスするグリッドがアクセス可能かどうかを判断する必要があります。行座標と列座標の合計を計算し、それらを合計して、結果がロボットの最大動作範囲 (K) より大きいかどうかを判断する必要があります。

数字の合計を計算する方法は 2 つあります。

  • 数字を文字列に変換し、各文字を走査して抽出し、それを数字に変換して合計します。
  • 数値に対して剰余演算を実行し、結果を加算し、数値が0以下になるまで数値自体に対して/10演算を実行します。

ロボットを動かし始める

ロボットを動かすときには、次の 7 つのパラメータが必要です。

  • 行列の行の総数
  • 行列の列の総数
  • 入力するグリッドの行座標
  • グリッドに入る列の座標
  • 最大可動範囲
  • アクセス アイデンティティ マトリックス
  • パスマトリックス

まず、境界条件の判定(再帰終了条件)を行う必要があります。条件が満たされた場合、グリッドにアクセスできず、トラバース可能なグリッドは 0 であることを意味します(直接 0 を返します)。

  • アクセスするグリッドの行座標がマトリックス内の行の総数より大きい
  • 訪問するグリッドの行座標が0未満です
  • アクセスするグリッドの列座標がマトリックス内の列の総数より大きい
  • アクセスするグリッドの列座標が0未満です
  • 現在のグリッドは訪問済みです
  • 現在のグリッドには入力できません

上記の条件がすべて満たされている場合、現在のグリッドにアクセスできることを意味します。現在のグリッドの値はアクションの軌跡に保存され、現在のグリッドは訪問済みとしてマークされ、歩いたグリッドの数 + 1 になり、現在のグリッドの他の 4 方向のグリッドに入ることができるかどうかを再帰的に確認します。

再帰スタックがクリアされると、ロボットが進入できるグリッドの合計数とその移動軌跡が取得されます。

実装コード

次に、上記のアイデアを TypeScript コードに変換します。

グリッドは関数を入力できますか?

まず、現在のグリッドに入ることができるかどうかを判断する関数の実装を見てみましょう。

  1. /**
  2. * ロボットがターゲットグリッドに入ることができるかどうかを判定する
  3. * @param row 行座標
  4. * @param col 列座標
  5. * @param ターゲット臨界点
  6. * @プライベート
  7. */
  8. プライベートチェックパス(行: 数値、列: 数値、ターゲット: 数値): ブール値 {
  9. // 2つの座標の桁の合計は臨界点以下でなければならない
  10. sumOfDigits(行) + sumOfDigits(列) <= ターゲットを返します
  11. }
  12.  
  13. // 文字列を文字列に変換する
  14. エクスポート関数sumOfDigits(ターゲット: 数値): 数値 {
  15. finalVal = 0 とします。
  16. 定数 computeVal = target.toString();
  17. ( i = 0 とします; i < computeVal.length; i++) {
  18. finalVal += Number(computeVal[i]);
  19. }
  20. finalValを返します
  21. }
  22.  
  23. // 桁の合計 - モジュロ演算の実装
  24. エクスポート関数sumOfDigitsForModular(ターゲット: 数値): 数値 {
  25. finalVal = 0 とします。
  26. (ターゲット > 0) の間 {
  27. finalVal += Math.floor(ターゲット % 10);
  28. ターゲット /= 10;
  29. }
  30. finalValを返します
  31. }

ロボット移動機能

ロボットを指定されたグリッドに移動するためのコードは次のとおりです。

  1. /**
  2. * ロボットを動かし始める
  3. * @param rows行列の行の総数
  4. * @param cols 行列の列の総数
  5. * @param row グリッドに入力する行座標
  6. * @param col グリッドに入力する列座標
  7. * @param しきい値最大アクティビティ範囲
  8. * @param isVisited 訪問識別マトリックス
  9. * @param 行列パス行列
  10. * @プライベート
  11. */
  12. rivate開始移動(
  13. 行数: 数、
  14. 列: 番号、
  15. 行: 番号、
  16. col: 番号、
  17. 閾値: 数値、
  18. isVisited: 配列<配列<ブール値>>,
  19. 行列: 配列<配列<T>>
  20. ): 番号 {
  21. //境界条件判定
  22. もし (
  23. 行 >=||
  24. 行 < 0 ||
  25. 列 >= 列数 ||
  26. 列 < 0 ||
  27. isVisited[行][列] ||
  28. !this.checkPath(行、列、しきい値)
  29. ){
  30. 0を返します
  31. }
  32. //現在訪問しているグリッドの内容を記録する
  33. this.path += `${matrix[row][col]} -> `;
  34. // 現在のグリッドが訪問されたことを示します
  35. isVisited[行][列] = true ;
  36. // グリッドアクセス番号 + 1
  37. 戻る
  38. 1 +
  39. this.startMoving(行数、列数、行 + 1、列数、しきい値、isVisited、行列) +
  40. this.startMoving(行数、列数、行、列 + 1、しきい値、isVisited、行列) +
  41. this.startMoving(行数、列数、行 - 1、列数、しきい値、isVisited、行列) +
  42. this.startMoving(行数、列数、行、列 - 1、しきい値、isVisited、行列)
  43. );
  44. }

主な機能

最後に、以下に示すように、メイン関数の実装を見てみましょう。

  1. /**
  2. * タイトル:
  3. * 地面には m 行 n 列の正方形のグリッドがあります。
  4. * ロボットは座標(0, 0)のグリッドから移動を開始します。
  5. * 一度に 1 つのグリッドを左、右、上、または下に移動できますが、行と列の数字の合計が k より大きいグリッドには入ることができません。
  6. * たとえば、k が 18 の場合、3+5+3+7=18 なので、ロボットは (35, 37) のマスに入ることができます。
  7. * しかし、3+5+3+8=19 なので、(35, 38) のマスに入ることはできません。ロボットはいくつのマスまで到達できるでしょうか?
  8. * @param 行列 行列
  9. * @param 閾値臨界点(最大活動範囲)
  10. */
  11. パブリック移動カウント(行列: Array<Array<T>>, しきい値 = 0): 数値 {
  12. 閾値<0 || 行列の長さ<=0の場合{
  13. 0を返します
  14. }
  15. // グリッドの行と列の合計数を取得します
  16. 定数= 行列の長さ;
  17. 定数列 = 行列[0].長さ;
  18. // グリッドが訪問されたかどうかを示すマーカー配列を作成します
  19. const isVisited: Array<Array<boolean>> = new Array( rows );
  20. ( i = 0 とします; i < isVisited.length; i++) {
  21. isVisited[i] = 新しい配列(cols);
  22. }
  23. // 位置 0,0 から移動を開始し、移動するグリッドの総数を計算します
  24. this.startMoving(行数、列数、0、0、しきい値、isVisited、行列 )を返します
  25. }

完全なコードについては、Backtracking.ts#L80 をご覧ください。

テストケースの作成

次に、上記のコードが正しく実行できるかどうかを確認するために、以下に示すように行列を作成します。

  1. 定数pathArr = [
  2. [ "a" "b" "t" "g" ],
  3. [ "c" "f" "c" "s" ],
  4. [ "j" "d" "e" "h" ]
  5. ];
  6.  
  7. const バックトラッキング = new Backtracking<string>();
  8. const totalCount = backtracking.movi​​ngCount(pathArr, 4);
  9. 定数 path = バックトラッキング.path;
  10. コンソール.log(
  11. 「ロボットが移動できるグリッドの合計数は次のとおりです:」
  12. 合計数、
  13. "、動作の軌跡は次のようになります: "
  14. パス.substr(0, パス.長さ - 3)
  15. );

実行結果は次のとおりです。

<<:  交通分野における人工知能、ビッグデータ、その他の技術の応用に関する簡単な議論

>>:  Nacos ランダムウェイト負荷分散アルゴリズム

ブログ    
ブログ    
ブログ    

推薦する

...

AlphaFold2の最初の公開PyTorchバージョンが複製可能になりました。コロンビア大学のオープンソースで、1,000以上のスターが付いています。

ちょうど今、コロンビア大学のシステム生物学助教授であるモハメッド・アルクライシ氏が、AlphaFol...

スマートビジョンが AI アプリケーションに及ぼす 5 つの影響

インテリジェントビジョンは人工知能への扉です。この扉が開かれなければ、人工知能に関する詳細な研究を行...

人工知能とモノのインターネットの統合は、今後10年間で最大のイノベーションの機会となるかもしれない

先日終了した全国人民代表大会と中国人民政治協商会議では、「科学技術イノベーション」という言葉が頻繁に...

...

AIに「子犬」を認識させますか? Facebookは変化を感知できるAIを構築

[[389144]]今まで見たことのない犬種や色であっても、私たちは一目見てその犬を認識することがで...

GPU の無駄遣いをやめよう: FlashAttention がアップグレードされ、長いテキストの推論速度が 8 倍に向上

最近、ChatGPT や Llama のような大規模言語モデル (LLM) がかつてない注目を集めて...

人工知能とビッグデータの時代において、一般の人々はどうやってお金を稼ぐのでしょうか?

将来、旅行には自動運転車、食事にはプログラムされたスナックストリート、ヘアカットにはロボット理髪師、...

...

人工知能は創造的な仕事を促進できるでしょうか?

今日、ほぼすべての AI 作業は機械学習の成功に基づいています。機械学習には分析を検討するための十分...

音声認識、マッチングアルゴリズム、モデルに関する簡単な説明

[[185868]]スピーチの基本概念スピーチは複雑な現象です。それがどのように生成され、どのように...

会話型ロボットをよりスマートにするために製品設計を最適化するにはどうすればよいでしょうか?

01.人間は日々、環境、社会、他の人々、物と密接に関わっています。このタイプの接続は、一方向、双方...

...