Mercurial > lbo > hg > juliaplay
changeset 19:5625644a818d
DP: a few more problems
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 28 Feb 2023 21:51:15 +0100 |
parents | f099b399e2f0 |
children | 9a9329349f98 |
files | julia/dp.jl |
diffstat | 1 files changed, 78 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/julia/dp.jl Tue Feb 28 15:17:55 2023 +0100 +++ b/julia/dp.jl Tue Feb 28 21:51:15 2023 +0100 @@ -219,3 +219,81 @@ max(without_current, with_current) end +"""Maximum Matrix Points +https://www.techiedelight.com/collect-maximum-points-matrix-satisfying-given-constraints/ +""" +function max_matrix_points(mat::AbstractMatrix{Int}, start=(1,1), P=0, Pmax=[0], Ps=fill((0,0), 100))::Int + row, col = start + if any(start .> size(mat)) + return 0 + end + opts = if iseven(row) + [(0, -1), (1, 0)] + else + [(0, 1), (1, 0)] + end + @show (start, opts) + + max_pts = mat[start...] + for opt = opts + ix = start .+ opt + if any(ix .< (1,1)) || any(ix .> size(mat)) || mat[ix...] < 0 + continue + end + cand = mat[start...] + max_matrix_points(mat, ix, P+mat[start...], Pmax, Ps) + max_pts = max(max_pts, cand) + Pmax[1] = max(Pmax[1], P+max_pts) + if max_pts == cand && (P+max_pts) == Pmax[1] + Ps[P+1] = start + end + end + if max_pts == mat[start...] + Pmax[1] = max(Pmax[1], P+max_pts) + if (P+max_pts) == Pmax[1] + Ps[P+1] = start + end + end + + max_pts +end + +function matmul_operations(a, b, c)::Int + 2 * (a*c) * b +end + +function matmul_opt(matrices::AbstractVector{<:Pair}, startix=1, endix=length(matrices))::Pair{Int,Tuple} + if length(matrices) <= 2 + a, b = (matrices[begin]) + b, c = (matrices[end]) + matmul_operations(a, b, c) => tuple(matrices...) + elseif endix - startix == 1 + a, b = (matrices[startix]) + b, c = (matrices[endix]) + matmul_operations(a, b, c) => tuple(matrices[startix:endix]...) + elseif endix == startix + 0 => tuple(matrices[startix]) + else + for i = startix+1:endix + @assert matrices[i-1][2] == matrices[i][1] + end + first_axis(p::Pair) = p[1] + first_axis(t::Tuple) = first_axis(t[1]) + last_axis(p::Pair) = p[2] + last_axis(t::Tuple) = last_axis(t[end]) + + # Choices: first * (rest), (first * second) * rest + minops, minsplit = 1e21, nothing + # split *after* i + for i = startix:endix-1 + leftops, left = matmul_opt(matrices, startix, i) + rightops, right = matmul_opt(matrices, i+1, endix) + ops = leftops + rightops + matmul_operations(first_axis(left), last_axis(left), last_axis(right)) + if leftops+rightops < ops + minsplit = (left, right) + minops = ops + end + end + minops => minsplit + end +end +