Thuật toán hiệu quả cho 'unumming' một tập hợp các khoản tiền


24

Cho nhiều số tự nhiên X, hãy xem xét tập hợp tất cả các tổng có thể:

sums(X)={iAi|AX}

Ví dụ: trong khi .sums({1,5})={0,1,5,6}sums({1,1})={0,1,2}

Thuật toán hiệu quả nhất để tính toán hoạt động nghịch đảo (được đo bằng kích thước của tập hợp đầu vào của tổng) là gì? Cụ thể là có thể tính toán một cách hiệu quả bất kỳ điều nào sau đây:

  1. Cho dù một tập hợp nhất định là một tập hợp hợp lệ. (Ví dụ: là hợp lệ nhưng thì không.){ 0 , 1 , 3 }{0,1,2}{0,1,3}
  2. Một multiset tổng hợp cho tập đã cho.
  3. Các nhỏ nhất MultiSet rằng khoản tiền để các thiết lập nhất định. (Ví dụ: và cả hai đều thành nhưng trước đây nhỏ hơn.){ 1 , 1 , 1 } { 0 , 1 , 2 , 3 }{1,2}{1,1,1}{0,1,2,3}

1
Bạn có thể có thể cho chúng ta những MultiSet của tiền chứ không phải là bộ của tiền? Điều này sẽ tạo ra sự đối xứng dễ chịu (nhìn thấy khi bạn bắt đầu với nhiều giá trị).
DW

1
Một câu hỏi khác - bạn có quan tâm nhất đến kết quả lý thuyết (ví dụ, độ phức tạp tiệm cận) hoặc giải pháp thực tế (sơ đồ có thể hoạt động tốt trong thực tế)? Nếu sau này, bạn có ý tưởng về các giá trị tiêu biểu cho các tham số: ví dụ: kích thước của multiset X, kích thước của phần tử lớn nhất trong multiset X, bội số cao nhất không? Điều này có thể ảnh hưởng đến việc áp dụng "búa lớn" như người giải ILP hay người giải SAT là hợp lý.
DW

@DW Tôi chắc chắn quan tâm đến việc sử dụng tập hợp các khoản tiền hơn là nhiều trang (mặc dù đó cũng có thể là một vấn đề thú vị). Ngoài ra, đây ban đầu là một vấn đề toán học giải trí, vì vậy tôi chủ yếu quan tâm đến các giới hạn phức tạp hơn là một giải pháp thực tế.
Uri Granta

3
Nếu bạn được cung cấp nhiều khoản tiền, thì việc này rất đơn giản để làm điều này một cách tham lam (xem ví dụ math.stackexchange.com/questions/201545/ Lỗi ).
jschnei

@UriZarfaty bộ được đưa ra làm đầu vào đã được sắp xếp? Cuối cùng điều này được thiết lập hay nhiều trang? Bình luận vẫn đề nghị rằng bạn muốn thiết lập tinh khiết.
Ác

Câu trả lời:


9

Dung dịch

Giải pháp có hai phần. Đầu tiên chúng tôi khám phá tập tối thiểu, sau đó chúng tôi chứng minh rằng nó có thể đại diện cho tập hợp sức mạnh. Giải pháp được điều chỉnh để thực hiện lập trình.

Thuật toán đặt tối thiểu

  1. Tìm phần tử cực đại từ tập tổng (đa). P , bộ tối thiểu tiềm năng (đa) ban đầu trống.amP

  2. Trừ khi chỉ có một nhóm, đại diện cho theo tất cả các cách có thể là một cặp tổng cộng với một m , S i j = { ( a i , a j ) | a i + a j = a m }amamSij={(ai,aj)|ai+aj=am}

  3. Kiểm tra xem tất cả các yếu tố từ bộ tổng hợp được bao gồm.

  4. Tìm yếu tố tối đa từ tất cả các S i j (có nghĩa với nhau) với các tài sản sau đây: cho mỗi S i j , một s là một trong hai trong S i j , hoặc chúng ta có thể tìm thấy một p từ tập các khoản tiền để một p + a s nằm trong S i j .asSijSijasSijapap+asSij

  5. Nếu đó là trường hợp mà không chứa một s , chỉ số tiền một s + một p , loại bỏ một p + một s từ S i j (hoặc chỉ cần đặt một dấu để bỏ qua nó) và chèn một pmột s trong S i j thay thế.Sijasas+apap+asSijapasSij

  6. Nếu một phần tử hiện diện trong tất cả các remove nó từ tất cả S i j lần (hoặc chỉ cần đặt một dấu để bỏ qua nó và không để chạm vào nó nữa) và thêm nó vào danh sách các yếu tố tiềm năng thiết lập tối thiểu P .SijSijP

  7. Lặp lại cho đến khi tất cả trốngSij

  8. Nếu một số vẫn không trống và chúng tôi không thể tiếp tục, hãy thử lại với giá trị tối đa từ tất cả S i j .SijSij

  9. Tái hiện những bước đệ quy mà không cần gỡ bỏ và tiếp tục với thuật toán bảo hiểm thiết lập quyền lực hơn . (Trước đó, bạn có thể thực hiện kiểm tra an toàn rằng P bao gồm tất cả các phần tử không thể được biểu diễn dưới dạng tổng của hai phần tử để chúng phải nằm trong tập hợp bên dưới để chắc chắn. Ví dụ: phần tử tối thiểu phải nằm trong P. )PPP

(10. Quan sát rằng một giải pháp tập hợp tối thiểu là mục tiêu của thuật toán không thể chứa nhiều hơn một lần lặp lại của cùng một số.)

Thí dụ:

{2,3,5,7,8,10,12,13,15}

Thể hiện 15 theo tất cả các cách có thể dưới dạng tổng của hai số từ tập hợp tổng.

(13,2),(12,3),(10,5),(8,7)

Cố gắng tìm số tối đa trong tất cả các nhóm hoặc có thể được biểu diễn dưới dạng tổng. Rõ ràng chúng ta có thể bắt đầu tìm kiếm nó từ 8, không có điểm nào vượt lên trên nó.

13 từ nhóm thứ nhất là 13 = 8 + 5 nên 13 là tốt, nhưng 12 từ nhóm thứ hai không ổn vì không có 4 để tạo 12 = 8 + 4 trong tập hợp tổng. Tiếp theo chúng tôi thử với 7. Nhưng ngay lập tức 13 không thể được bảo hiểm, không có 6.

Tiếp theo, chúng tôi thử 5. 13 = 5 + 8, 12 = 5 + 7, 10 = 5 + 5 và cuối cùng là 8 = 5 + 3 hoặc 7 = 5 + 2 nhưng không phải cả hai. Các nhóm hiện nay:

((5,8),2),((5,7),3),((5,5),5),((5,3),7)

5 đang lặp lại trong tất cả các nhóm vì vậy chúng tôi trích xuất nó . Chúng tôi trích xuất 5 chỉ một lần từ mỗi nhóm.P={5}

(8,2),(7,3),(5,5),(3,7)

Rõ ràng không có điểm nào cao hơn 5 nên chúng tôi thử lại 5 lần. 8 = 5 + 3, 7 = 5 + 2, vì vậy tất cả đều ổn

((5,3),2),((5,2),3),(5,5),(3,(5,2))

Trích xuất một 5 lần nữa từ tất cả các nhóm vì nó đang lặp lại. (Điều này không phổ biến nhưng trường hợp của chúng tôi được tạo ra một cách có chủ ý để hiển thị những việc cần làm trong trường hợp chúng tôi có sự lặp lại.) P={5,5}

(3,2),(2,3),(5),(3,2)

Bây giờ chúng tôi thử với 3 và có 5 = 3 + 2. Thêm nó vào nhóm.

(3,2),(2,3),(3,2),(3,2)

Bây giờ trích xuất 3 và 2 vì chúng lặp lại ở mọi nơi và chúng tôi ổn và các nhóm trống.P={5,5,3,2}

(),(),(),()

Bây giờ, chúng ta cần tạo lại các bước đệ quy mà không cần xóa, điều này đơn giản có nghĩa là thực hiện ở trên mà không thực sự loại bỏ các phần tử khỏi chỉ đặt chúng trong P và đánh dấu không thay đổi nó nữa.SijP

( ( 5 , 8 ) , 2 ) , ( ( 5 , 7 ) , 3 ) , ( ( 5 , 5 ) , 5 ) , ( ( 5 , 3 ) , 7

(13,2),(12,3),(10,5),(8,7)
( ( 5 , ( 5 , 3 ) ) , 2 ) , ( ( 5 , ( 5 , 2 ) ) , 3 ) , ( ( 5 , ( 3 , 2 ) ) , 5 ) , ( ( 5 , 3 ) , ( 5 , 2 ) )
((5,8),2),((5,7),3),((5,5),5),((5,3),7)
((5,(5,3)),2),((5,(5,2)),3),((5,(3,2)),5),((5,3),(5,2))

Bảo hiểm bộ điện

Mục đích của phần này là để kiểm tra xem tập tối thiểu tìm thấy có thể bao gồm tập tổng công suất không. Có thể là một giải pháp được tìm thấy có thể bao gồm tất cả các khoản tiền đã cho, nhưng chúng không phải là các khoản tiền được thiết lập. (Về mặt kỹ thuật, bạn có thể chỉ cần tạo một tập hợp tổng năng lượng từ tập tối thiểu tìm thấy và kiểm tra xem mỗi tổng, như tập hợp sức mạnh, có nằm trong tập tổng ban đầu không. . Bạn có thể thực hiện phần này trong khi tua lại đệ quy.)

  1. Mã hóa tất cả các yếu tố từ tập tối thiểu bằng cách sử dụng các lũy thừa liên tiếp là 2. Thứ tự không quan trọng. Mã hóa cùng một phần tử với một giá trị mới nhiều lần như nó đang lặp lại. Bắt đầu từ C = 1, mọi phần tử tiếp theo đều có C = 2C.

(2=[1],3=[2],5=[4],5=[8])
  1. Thay thế các phần tử trong danh sách đệ quy được khôi phục,

((5,(5,3)),2),((5,(5,2)),3),((5,(3,2)),5),((5,3),(5,2))

với mã hóa: 2 với 1, 3 với 2, 5 với 4 và 5 khác với 8. Quan sát rằng mỗi phần tử có mã hóa khác nhau mặc dù chúng được lặp lại.

((4,(8,2)),1),((4,(8,1)),2),((4,(2,1)),8),((8,2),(4,1))
  1. Thu thập tất cả các khoản tiền trung gian, tại thời điểm chúng tôi có (1,2,4,8)

((4,(10)),1),((4,(9)),2),((4,(3)),8),((10),(5))

(1,2,3,4,5,8,9,10)

((14),1),((13),2),((7),8),(15)

(1,2,3,4,5,8,9,10,13,14,15)

{(15),(15),(15),(15)}
  1. 2m1mm=4

  2. 12m1

(6,7,11,12)

  1. Biện minh cho sự vắng mặt của họ theo cách sau: thể hiện mỗi số ở dạng nhị phân

(6=01102) (7=01112) (11=10112) (12=10102)

đại diện cho tổng 3 + 5 vì 0110 2 bao gồm phần tử thứ hai và thứ ba từ ( 2601102(2=[1],3=[2],5=[4],5=[8]){2,3,5,7,8,10,12,13,15}, vì vậy tất cả đều ổn.

701112(2=[1],3=[2],5=[4],5=[8])

1112

Nếu bất kỳ biểu diễn nhị phân nào tương ứng với tổng không thể tìm thấy, hãy báo cáo rằng không có giải pháp.

(2,3,5,5)

Thảo luận

Nó là cần thiết để cung cấp thuật toán sẽ kiểm tra xem các khoản tiền có bao gồm việc hoàn thành bộ năng lượng hay không, đó là những gì được ẩn trong việc mở rộng nhị phân. Ví dụ: nếu chúng tôi loại trừ 8 và 7 khỏi ví dụ ban đầu, phần đầu tiên vẫn sẽ cung cấp giải pháp, chỉ phần thứ hai sẽ báo cáo các kết hợp thiếu.

mnlog(m)mlog2(m)mnlog(m)

mlogmmlog2(m)

mlog3(m)

Các phần của thuật toán giả định rằng chúng ta có thể tìm thấy cặp tổng trong thời gian tuyến tính và điều này đòi hỏi phải sắp xếp.

Bắt đầu không chính xác

Phần đầu tiên của thuật toán có thể thất bại, nếu chúng ta đã khởi động nó sai. Ví dụ 2,3,4,5,6,7,8,9,10,11,12,13,152,3,4,6Sij

5,4,3,3

2,2,3,4,42,3,4,6

Mục đích của thuật toán này là cung cấp một giải pháp một khi chúng ta đã bắt đầu tất cả một cách chính xác.

Cải tiến

Bước 4. là bước có thể được nâng cấp theo cách này: thay vì tối đa, chúng tôi có thể thử mọi phần tử theo thứ tự giảm dần thỏa mãn điều kiện đã cho. Chúng tôi tạo ra một chi nhánh riêng cho mỗi. Nếu một số chi nhánh không đưa ra giải pháp, hãy hủy bỏ nó.

Ví dụ cho 2,3,4,5,6,7,8,9,10,11,12,13,157,6,5,4theo những cách riêng biệt vì tất cả chúng đều vượt qua bài kiểm tra đầu tiên. (Không có lý do để sử dụng 2 hoặc 3 vì chúng tôi biết rằng chúng phải nằm trong bộ cơ bản.) Và chỉ cần tiếp tục theo cách đó cho đến khi chúng tôi thu thập tất cả các phiên bản có thể đi đến cuối. Điều này sẽ tạo ra một giải pháp bao phủ toàn bộ sẽ khám phá nhiều hơn một tập hợp cơ bản.

Một điều nữa, vì chúng ta biết rằng chúng ta không thể có nhiều hơn một lần lặp lại nếu trường hợp là tối thiểu, chúng ta có thể kết hợp điều này trong thuật toán của mình.

Nhìn chung, điều kiện ở bước 4. rằng một số phải lặp lại trong mỗi nhóm hoặc có khả năng tạo ra một số tiền đủ mạnh để đưa chúng ta ra khỏi vùng nước hàm mũ trực tiếp, đó sẽ là một thuật toán chỉ đơn giản là thử mọi kết hợp và tạo ra sức mạnh đặt trên mỗi cho đến khi chúng tôi tìm thấy một trận đấu.


1
Rộng hơn: Tôi thấy một mô tả văn bản của một thuật toán, nhưng (a) không có mã giả và (b) không có bằng chứng về tính chính xác. Tại sao bạn nghĩ rằng phương pháp này cung cấp một thuật toán sẽ hoạt động chính xác trên tất cả các đầu vào có thể? Những gì biện minh? Bạn có một bằng chứng về sự đúng đắn cho điều này?
DW

Tôi nghĩ rằng vấn đề đã mất khoảng 30 giờ làm việc cùng nhau (tốc độ 30 lần mỗi giờ, tốt ...). Nhưng không có tùy chọn trả tiền.

Cuối cùng đọc câu trả lời trong chi tiết nó xứng đáng. Công việc tuyệt vời
Uri Granta

1

LƯU Ý: Điều này không hoàn toàn hoạt động nói chung, xem ví dụ mẫu của Uri bên dưới.

YY

  • 0Y
  • Hãy để yYyXY
  • z1<<znYYY=Y+{0,y}0Yi=1,,nzi+yYziYziyYzi+yYzi+yYziY
  • Yy,y,

1yO(n)O(n2)

Y={0,1,3,4,5,6,7}{0,1,3,4,6}{0,1,3,5,6}yY{a+ky}YY


Rõ ràng là Y 'không dẫn đến ngõ cụt? Rốt cuộc, có thể có nhiều chữ Y sao cho Y = Y '+ {0, y}. Ví dụ {0,1,2,3,4} = {0,2,3} + {0,1} = {0,1,2,3} + {0,1} nhưng phân tách trước dẫn đến a ngõ cụt.
Uri Granta

Đó là sự thật, và là một vấn đề thực sự. Tôi sẽ phải xem nếu nó có thể được sửa chữa. Cảm ơn!
lật Klaus

YkY=Y+{0,y,,y}{0,y,,y}kbản sao , sau đó recurse trên Y ' . yY
DW
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.