🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

アルゴリズム

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

Q&A

解決済

1回答

829閲覧

A*アルゴリズムで特定の座標のコストを上げたい

minokiti

総合スコア45

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

アルゴリズム

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

0グッド

0クリップ

投稿2021/01/05 09:25

RubyでA*アルゴリズムを作りたいと思っています。
(下はasmさんの書いたコードにちょっと付け足しました。asmさんすみません...)

Ruby

1@water = [[2,4], [2,5]] 2class PriorityQueue 3 def initialize 4 @hash = Hash.new{|h,k| h[k] = [] } 5 end 6 def push(val, priority) 7 @hash[priority].push val 8 end 9 def min_key 10 @hash.select{|k,v| v.size != 0}.map(&:first).min 11 end 12 def pop 13 @hash[min_key].pop 14 end 15 def empty? 16 @hash.values.all?(&:empty?) 17 end 18end 19def distance(start, goal) 20 (start[0]-goal[0]).abs + (start[1]-goal[1]).abs 21end 22def a_star(start, goal, except) 23 directions = [[0,1],[0,-1],[1,0],[-1,0]] 24 que = PriorityQueue.new 25 que.push([start,[]], distance(start, goal)) 26 close = Set.new(start) 27 until que.empty? 28 now, route = que.pop 29 next_route = route + [now] 30 #付け足した部分 31 if @water.include?(now) 32 dist = next_route.size + 1 33 else 34 dist = next_route.size 35 end 36 return next_route if now == goal 37 dirs = directions.map{|dx,dy| [now[0] + dx, now[1] + dy] } 38 .select{|pos| !except.include?(pos) && close.add?(pos) } 39 dirs.each do |to| 40 que.push([to,next_route], dist + distance(to, goal)) 41 end 42 end 43end 44except = [[3,4], [1,2], [3,6]] 45p a_star([1,1], [3,5], except)

自分は初心者ですが自分なりに if @water.include?(now) のところを考えてみたんですがどのように書けばいいのか分かりません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

修正前にコストがdist = next_route.sizeで求まっていたのは、
すべての場所に移動するコストが1だったからです。

今回の修正で、その前提が崩れたわけですから、
ルート上の場所をすべて確認して、それぞれのコストを求めて足し合わせなければなりません。

@waterに含まれていればコスト2、それ以外ならコスト1なので、素直に作れば以下のようになります。

ruby

1dist = next_route.sum{|pos| @water.include?(pos) ? 2 : 1}

ただ、これだと毎回計算して遅くなるので、asmさんもおっしゃっていた通り、
now,routeに加えてdistqueueに保存するのが良いでしょう。

そちらの方法については、自分で考えてみてください。

投稿2021/01/05 20:59

actorbug

総合スコア2420

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

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

minokiti

2021/01/06 08:25

ありがとうございました???? なんとなくわかったような気がするので、もう一度自分で考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問