day15 p2: proper Bellman-Ford
This commit is contained in:
115
day15/part2.jl
115
day15/part2.jl
@@ -171,10 +171,35 @@ function neighbor_idx(nrows, ncols, y, x)
|
|||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function relax(nrows, ncols, R, costs, row, col; first=false)
|
||||||
|
idx = neighbor_idx(nrows, ncols, row, col)
|
||||||
|
c = minimum(costs[i] for i in idx) + R[row, col]
|
||||||
|
if first || c < costs[row, col]
|
||||||
|
costs[row, col] = c
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function relax_all(nrows, ncols, R, costs)
|
||||||
|
relaxed = false
|
||||||
|
for row in 1:nrows
|
||||||
|
for col in 1:ncols
|
||||||
|
v_relaxed = relax(nrows, ncols, R, costs, row, col)
|
||||||
|
relaxed = relaxed || v_relaxed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return relaxed
|
||||||
|
end
|
||||||
|
|
||||||
function get_costs(R)
|
function get_costs(R)
|
||||||
costs = zeros(Int, size(R))
|
costs = zeros(Int, size(R))
|
||||||
dirs = zeros(Int, size(R))
|
dirs = zeros(Int, size(R))
|
||||||
nrows, ncols = size(R)
|
nrows, ncols = size(R)
|
||||||
|
|
||||||
|
# first pass, unconditional update looking only right/down. Avoids
|
||||||
|
# having to add an infinity value
|
||||||
|
costs[1,1] = 0
|
||||||
for col in 2:ncols
|
for col in 2:ncols
|
||||||
costs[1, col] = costs[1, col-1] + R[1, col]
|
costs[1, col] = costs[1, col-1] + R[1, col]
|
||||||
end
|
end
|
||||||
@@ -190,90 +215,24 @@ function get_costs(R)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if false
|
edges = ( (nrows-2)*(ncols-2)*4
|
||||||
# more passes
|
+(nrows+ncols-4)*3
|
||||||
for i in 1:max(nrows, ncols)
|
+4*2 )
|
||||||
for col in ncols-1:-1:1
|
max_passes = (nrows*ncols - 1) * edges
|
||||||
rcost = costs[end, col+1] + R[end, col]
|
|
||||||
if rcost < costs[end, col]
|
i = 1
|
||||||
costs[end, col] = rcost
|
while i <= max_passes
|
||||||
end
|
relaxed = relax_all(nrows, ncols, R, costs)
|
||||||
end
|
if !relaxed
|
||||||
for row in nrows-1:-1:1
|
break
|
||||||
dcost = costs[row+1, end] + R[row, end]
|
|
||||||
if dcost < costs[row, end]
|
|
||||||
costs[row, end] = dcost
|
|
||||||
end
|
|
||||||
for col in ncols-1:-1:1
|
|
||||||
rcost = costs[row, col+1] + R[row, col]
|
|
||||||
if rcost < costs[row, col]
|
|
||||||
costs[row, col] = rcost
|
|
||||||
end
|
|
||||||
dcost = costs[row+1, col] + R[row, col]
|
|
||||||
if dcost < costs[row, col]
|
|
||||||
costs[row, col] = dcost
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
i += 1
|
||||||
end
|
end
|
||||||
end
|
println("passes ", i)
|
||||||
|
|
||||||
for i in 1:max(nrows, ncols)
|
|
||||||
|
|
||||||
for row in nrows:-1:1
|
|
||||||
for col in ncols:-1:1
|
|
||||||
idx = neighbor_idx(nrows, ncols, row, col)
|
|
||||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
|
||||||
if c < costs[row, col]
|
|
||||||
costs[row, col] = c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for row in nrows:-1:1
|
|
||||||
for col in 1:ncols
|
|
||||||
idx = neighbor_idx(nrows, ncols, row, col)
|
|
||||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
|
||||||
if c < costs[row, col]
|
|
||||||
costs[row, col] = c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for row in 1:nrows
|
|
||||||
for col in ncols:-1:1
|
|
||||||
idx = neighbor_idx(nrows, ncols, row, col)
|
|
||||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
|
||||||
if c < costs[row, col]
|
|
||||||
costs[row, col] = c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for row in 1:nrows
|
|
||||||
for col in 1:ncols
|
|
||||||
idx = neighbor_idx(nrows, ncols, row, col)
|
|
||||||
c = minimum(costs[i] for i in idx) + R[row, col]
|
|
||||||
if c < costs[row, col]
|
|
||||||
costs[row, col] = c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return costs, dirs
|
return costs, dirs
|
||||||
end
|
end
|
||||||
|
|
||||||
#=
|
|
||||||
cost, path = least_risk(risk_map)
|
|
||||||
|
|
||||||
display(path)
|
|
||||||
println()
|
|
||||||
|
|
||||||
println("cost = ", cost)
|
|
||||||
=#
|
|
||||||
|
|
||||||
costs, dirs = get_costs(risk_map)
|
costs, dirs = get_costs(risk_map)
|
||||||
|
|
||||||
if length(costs) < 1000
|
if length(costs) < 1000
|
||||||
|
|||||||
Reference in New Issue
Block a user