回答編集履歴

2

更新

2020/03/03 00:00

投稿

asm
asm

スコア15149

test CHANGED
@@ -34,7 +34,7 @@
34
34
 
35
35
  def min_key
36
36
 
37
- @hash.select{|k,v| v.size != 0}.map(&:first).min
37
+ @hash.select{|k,v| !v.empty?}.map(&:first).min
38
38
 
39
39
  end
40
40
 
@@ -46,7 +46,9 @@
46
46
 
47
47
  def empty?
48
48
 
49
- @hash.values.all?(&:empty?)
49
+ @hash.delete_if{|k,v| v.empty?}
50
+
51
+ .empty?
50
52
 
51
53
  end
52
54
 
@@ -56,7 +58,7 @@
56
58
 
57
59
  def distance(start, goal)
58
60
 
59
- [start,goal].transpose.map{|s,g| (s-g).abs}.sum
61
+ (start[0]-goal[0]).abs + (start[1]-goal[1]).abs
60
62
 
61
63
  end
62
64
 
@@ -70,21 +72,23 @@
70
72
 
71
73
  que.push([start,[]], distance(start, goal))
72
74
 
73
- close = Set.new(start)
75
+ close = Set[]
74
76
 
75
77
  until que.empty?
76
78
 
77
79
  now, route = que.pop
78
80
 
81
+ next unless close.add?(now)
82
+
79
83
  next_route = route + [now]
84
+
85
+ return next_route if now == goal
80
86
 
81
87
  dist = next_route.size
82
88
 
83
- return next_route if now == goal
84
-
85
89
  dirs = directions.map{|dx,dy| [now[0] + dx, now[1] + dy] }
86
90
 
87
- .select{|pos| !except.include?(pos) && close.add?(pos) }
91
+ .select{|pos| !except.include?(pos) }
88
92
 
89
93
  dirs.each do |to|
90
94
 
@@ -98,7 +102,19 @@
98
102
 
99
103
 
100
104
 
101
- except = [[3,10],[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13], [0,14], [1,0],[2,0],[3,0],[4,0],[0,4],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0], [14,0]]
105
+ except = [
106
+
107
+ [3,10], # [4,11],[4,9],[5,10],
108
+
109
+ *Array.new(15){|i| [0,i] },
110
+
111
+ *Array.new(15){|i| [i,0] },
112
+
113
+ # *Array.new(14){|i| [14,i+1]},
114
+
115
+ # *Array.new(14){|i| [i+1, 14]},
116
+
117
+ ]
102
118
 
103
119
  p a_star([1,13],[4,10],except)
104
120
 

1

追記

2020/03/03 00:00

投稿

asm
asm

スコア15149

test CHANGED
@@ -1,3 +1,105 @@
1
1
  A*で使う推定距離は実際の距離より短ければなんでもいいので
2
2
 
3
3
  壁を通った場合の距離でも問題ありません。
4
+
5
+
6
+
7
+ **追記**
8
+
9
+
10
+
11
+ 実装してみた
12
+
13
+
14
+
15
+ ```ruby
16
+
17
+ require 'set'
18
+
19
+
20
+
21
+ class PriorityQueue
22
+
23
+ def initialize
24
+
25
+ @hash = Hash.new{|h,k| h[k] = [] }
26
+
27
+ end
28
+
29
+ def push(val, priority)
30
+
31
+ @hash[priority].push val
32
+
33
+ end
34
+
35
+ def min_key
36
+
37
+ @hash.select{|k,v| v.size != 0}.map(&:first).min
38
+
39
+ end
40
+
41
+ def pop
42
+
43
+ @hash[min_key].pop
44
+
45
+ end
46
+
47
+ def empty?
48
+
49
+ @hash.values.all?(&:empty?)
50
+
51
+ end
52
+
53
+ end
54
+
55
+
56
+
57
+ def distance(start, goal)
58
+
59
+ [start,goal].transpose.map{|s,g| (s-g).abs}.sum
60
+
61
+ end
62
+
63
+
64
+
65
+ def a_star(start, goal, except)
66
+
67
+ directions = [[0,1],[0,-1],[1,0],[-1,0]]
68
+
69
+ que = PriorityQueue.new
70
+
71
+ que.push([start,[]], distance(start, goal))
72
+
73
+ close = Set.new(start)
74
+
75
+ until que.empty?
76
+
77
+ now, route = que.pop
78
+
79
+ next_route = route + [now]
80
+
81
+ dist = next_route.size
82
+
83
+ return next_route if now == goal
84
+
85
+ dirs = directions.map{|dx,dy| [now[0] + dx, now[1] + dy] }
86
+
87
+ .select{|pos| !except.include?(pos) && close.add?(pos) }
88
+
89
+ dirs.each do |to|
90
+
91
+ que.push([to,next_route], dist + distance(to, goal))
92
+
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+
99
+
100
+
101
+ except = [[3,10],[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13], [0,14], [1,0],[2,0],[3,0],[4,0],[0,4],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0], [14,0]]
102
+
103
+ p a_star([1,13],[4,10],except)
104
+
105
+ ```