Tối ưu hóa nhân chuỗi ma trận


9

Thách thức này là tính toán thứ tự nhân hiệu quả nhất cho một sản phẩm của một số ma trận.

Kích thước của ma trận được chỉ định trên một dòng đầu vào tiêu chuẩn. Bạn nên in ra đầu ra tiêu chuẩn một danh sách các số nguyên cho biết thứ tự thực hiện phép nhân để giảm thiểu tổng chi phí nhân.

ví dụ 1

đầu vào

5x6 6x12 12x100 100x7

đầu ra

3 2 1

Dòng đầu vào sẽ là một danh sách các kích thước ma trận được phân tách bằng dấu cách, mỗi kích thước là số lượng hàng, theo sau là một x, theo sau là số cột. Ví dụ, có 4 ma trận để nhân với nhau (vì vậy tổng 3 phép nhân) và vì phép nhân ma trận là kết hợp nên chúng có thể được thực hiện theo bất kỳ thứ tự nào.

Đầu ra phải là thứ tự thực hiện các phép nhân để giảm thiểu tổng chi phí. Đây phải là một danh sách các số nguyên được phân tách bằng dấu cách biểu thị chỉ số của phép nhân để thực hiện tiếp theo. Đối với ma trận N, danh sách này phải chứa các số từ 1 đến N-1. Ví dụ 1, đầu ra 3 2 1có nghĩa là bạn nên thực hiện 12x100 * 100x7phép nhân trước, sau đó là 6x12 * 12x7phép nhân (ma trận thứ hai nhân với kết quả của bước trước đó), sau đó cuối cùng là 5x6 * 6x7phép nhân.

Các phép nhân ma trận sẽ luôn luôn tương thích, tức là số lượng cột của ma trận sẽ khớp với số lượng hàng của ma trận tiếp theo. Giả sử chi phí nhân hai ma trận AxB * BxCA*B*C.

Mã của bạn phải xử lý danh sách lên tới 100 ma trận, mỗi kích thước lên tới 999 và thực hiện trong thời gian hợp lý.

ví dụ 2

đầu vào

5x10 10x5 5x15 15x5

đầu ra

1 3 2

hoặc là

3 1 2

ví dụ 3

đầu vào

22x11 11x78 78x123 123x666 666x35 35x97 97x111 111x20 20x50

đầu ra

2 3 4 5 6 7 8 1

Lưu ý: để xác minh, tổng chi phí tốt nhất cho ba ví dụ là 9114, 750 và 1466344.

Mã ngắn nhất sẽ thắng!


Bạn có chắc chắn về ví dụ cuối cùng? Tổng chi phí được cung cấp bởi mã của tôi là 1466344.
Howard

@Howard: Đúng, bạn nói đúng, một lỗi trong mã của tôi. Đã sửa.
Keith Randall

Câu trả lời:


1

Ruby, 176 172 205 ký tự

Đây là một phiên bản khác (một vài ký tự dài hơn) cũng sẽ chạy cho đầu vào lớn trong thời gian hợp lý.

q=(gets.split<<$_[/\d+$/]).map &:to_i
r=Hash.new{|h,i|h[i]=Hash.new{|h,j|h[j]=1e12;h[j]=i==j ?[0,[]]:(i...j).map{|k|a,c=r[i][k];b,d=r[k+1][j];[a+b+q[i-1]*q[k]*q[j],c+d+[k]]}.min}}
$><<r[1][q.size-1][1]*' '

Phiên bản đầu tiên: triển khai đệ quy thẳng trong Ruby. Nó thực hiện một tìm kiếm hoàn chỉnh và do đó có thể chậm trên các đầu vào lớn.

k=->m{m[2]?(1..m.size-2).map{|l|s=k[m[0,l]+m[l+1..-1]];[m[l-1]*m[l]*m[l+1]+s[0],[l]+s[1].map{|u|u<l ?u:u+1}]}.min: [0,[]]}
$><<k[(gets.split<<$_[/\d+$/]).map &:to_i][1]*' '

Một phần của thách thức là xử lý 100 ma trận trong một thời gian hợp lý, điều mà mã này không có.
Keith Randall

@KeithRandall Ah, tôi đã không đọc câu đó (và tôi không thích nó - đó là một sự kiềm chế rất mạnh mẽ). Tôi sẽ cố gắng xây dựng một giải pháp có thể xử lý trường hợp này.
Howard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.