Nếu bạn lặp lại vấn đề theo một cách hơi khác (nhưng tương đương), một thuật toán sẽ trở nên rõ ràng hơn:
Có bên tham gia: người, và một người phục hồi. Đặt là số tiền bữa tiệc nên có sau khi bữa ăn kết thúc và được trả tiền. Ví dụ: nếu Alice có 36 đô la và nợ 25 đô la , Bob có 12 đô la và nợ 11 đô la và Carl có 30 đô la và nợ 25 đô la , chúng tôi nói rằng là nhà hàng và có:n - 1 p i i p 0nn−1piip0
p=(61,11,1,5)
Đó là, khi bữa ăn kết thúc nhà hàng nên có $ 61, Alice nên có $ 11, Bob nên có $ 1 và Carl nên có $ 5.
Bây giờ hãy để liệt kê tất cả các hóa đơn liên quan. Ví dụ:mbm
b=(1,5,10,20,1,1,5,5,10,20)
Các mệnh giá của các hóa đơn không quan trọng, nhưng tôi đã chọn các mệnh giá tiền giấy của Mỹ cho ví dụ này vì chúng quen thuộc.
Chúng tôi đang tìm cách giảm thiểu số lượng hóa đơn mà tay thay đổi, vì vậy chúng tôi kết hợp một "chi phí" với người rời với hóa đơn bằng cách sử dụng một ma trận . Các mục nhập 0 trong ma trận này cho biết các hóa đơn mà mỗi bên bắt đầu bằng ( cho tất cả vì nhà hàng bắt đầu không có hóa đơn).j { 0 , 1 } C C 0 , j = 0 jij{0,1}CC0,j=0j
Tiếp tục ví dụ của chúng tôi:
C=⎡⎣⎢⎢⎢0011001100110011010101010101010101100110⎤⎦⎥⎥⎥
chỉ ra rằng Alice bắt đầu với $ 1, $ 5, $ 10, $ 20, Bob bắt đầu với $ 1, $ 1, $ 5, $ 5 và Carl bắt đầu với $ 10 và $ 20.
Một lần nữa, mục tiêu là giảm thiểu số lượng hóa đơn đổi tay. Nói cách khác:
Minimize:subject to:and∑i=0n−1∑j=0m−1Ci,jxi,j∑i=0n−1xi,j=1 for 0≤j<m,∑j=0m−1xi,jbj=pi for 0≤i<n,xi,j≥0
Ràng buộc đầu tiên nói rằng giải pháp chỉ có thể chỉ định một hóa đơn cụ thể cho một bên và thứ hai đảm bảo rằng mọi người đều trả số tiền phù hợp.
Đây là vấn đề lập trình 0,1 INTEGER và hoàn thành NP (xem [ Karp 1972 ]). Trang Wikipedia về lập trình tuyến tính có thông tin về các thuật toán khác nhau có thể được sử dụng cho các loại vấn đề này.
Có nhiều giải pháp tối ưu; bằng tay giải pháp đầu tiên cho ví dụ tôi nghĩ ra là:
x=⎡⎣⎢⎢⎢0100100001001000101000000001100010001000⎤⎦⎥⎥⎥
có nghĩa là Alice trả chính xác $ 5 và $ 20, Bob trả chính xác $ 1, $ 5 và $ 5, và Carl trả quá $ 10 và $ 20 và sau đó xóa $ 5 khỏi bảng.
Tôi cũng đã sử dụng mô-đun Chương trình tuyến tính số nguyên hỗn hợp của hệ thống Sage Math có khả năng sử dụng các phụ trợ bộ giải khác nhau ( GLPK , COIN , CPLEX hoặc Gurobi ). Giải pháp đầu tiên mà nó đưa ra là
x=⎡⎣⎢⎢⎢0100100001001000001010000000100110001000⎤⎦⎥⎥⎥
gần như giống nhau ngoại trừ việc Carl lấy "5 đô la" khác mà Bob đặt lên bàn.
Xây dựng vấn đề theo cách này thỏa mãn tất cả các thuộc tính bạn liệt kê (bạn có thể ngoại suy hóa đơn nào kết thúc ở đâu từ và ma trận giải pháp ). Ngoại lệ có lẽ là # 4 đã được thảo luận trong các ý kiến của câu hỏi. Tôi không rõ bạn muốn làm gì trong tình huống không có giải pháp khả thi nào cho tập hợp các phương trình tuyến tính:xCx
Xác định một tập hợp con người có thể trả tổng số giảm? Hoặc có lẽ một tập hợp con người vẫn có thể trả toàn bộ hóa đơn, tức là họ trả tiền cho bạn của họ.
Tuyên bố cuối cùng của bạn làm cho có vẻ như bạn quan tâm đến trường hợp các mệnh giá của các hóa đơn được cố định, tuy nhiên điều này không làm thay đổi vấn đề.
Trong mọi trường hợp, cũng có một giải pháp trong đó mọi người thanh toán bằng thẻ tín dụng.O(1)