สมมุติว่ามีเพื่อนไม่กี่คน พวกเขายืมเงินซึ่งกันและกัน ดังนั้นจะมีกระแสเงินสดบางส่วนในเครือข่าย งานของเราคือการลดกระแสเงินสดในเครือข่าย สมมติว่ามีเพื่อนสามคน P1, P2 และ P3 กระแสเงินสดในหมู่พวกเขาเป็นดังนี้ -

กระแสเงินสดนี้ไม่ใช่ขั้นต่ำ เราต้องย่อให้เล็กสุด จากนั้นไดอะแกรมสุดท้ายจะเป็นเช่น −

เพื่อแก้ปัญหานี้เราจะใช้วิธีโลภ ที่นี่ในแต่ละขั้นตอนจะชำระจำนวนเงินทั้งหมดสำหรับหนึ่งคนและเกิดขึ้นอีกสำหรับ n-1 คนที่เหลืออยู่ มาถึงคำถามว่า จะเลือกคนแรกยังไงดี? คำตอบคือ ให้คำนวณจำนวนเงินสุทธิของทุกๆ คนที่ได้รับยอดสุทธิโดยการหักหนี้ทั้งหมดออกจากเครดิตทั้งหมด เมื่อคำนวณจำนวนเงินสุทธิแล้ว ให้หาโหนดสองโหนดซึ่งมีค่าต่ำสุดและสูงสุด บุคคลสองคนนี้เป็นเจ้าหนี้และลูกหนี้ส่วนใหญ่ บุคคลที่มีค่าต่ำสุดคือคนแรก อัลกอริทึมเป็นเหมือนด้านล่าง −
-
สำหรับทุกคน Pi จาก 0 ถึง n – 1 ทำตามขั้นตอนต่อไปนี้
-
คำนวณจำนวนเงินสุทธิสำหรับทุกคน Net mount สำหรับบุคคลที่ฉันสามารถคำนวณได้โดยการลบผลรวมของหนี้ทั้งหมดออกจากผลรวมของเครดิตทั้งหมด
-
ค้นหา Pc เจ้าหนี้สูงสุดและ Pd ลูกหนี้สูงสุด สมมติว่าจำนวนเงินสูงสุดที่จะให้เครดิตแก่เจ้าหนี้สูงสุดคือ max_credit และจำนวนเงินสูงสุดที่หักจากลูกหนี้สูงสุดเรียกว่า max_debit
-
set x:=ขั้นต่ำของ max_credit และ max_debit จากนั้นเดบิต x จาก Pd และให้เครดิต x ไปยังพีซี
-
หาก x เท่ากับ max_credit ให้นำ Pc ออกจากชุดและเกิดซ้ำสำหรับ n-1 คนต่อไป
-
ถ้า x เหมือนกับ max_debit ให้ลบ Pd ออกจากกลุ่มบุคคลและเกิดขึ้นอีกสำหรับ n-1 คนถัดไป
ตัวอย่าง
#include<iostream>
#include<algorithm>
#define N 3
using namespace std;
int getMinIndex(int arr[]) {
int minInd = 0;
for (int i=1; i<N; i++)
if (arr[i] < arr[minInd])
minInd = i;
return minInd;
}
int getMaxIndex(int arr[]) {
int maxInd = 0;
for (int i=1; i<N; i++)
if (arr[i] > arr[maxInd])
maxInd = i;
return maxInd;
}
void cashFlowTask(int amount[]) {
int max_credit = getMaxIndex(amount), max_debit = getMinIndex(amount);
if (amount[max_credit] == 0 && amount[max_debit] == 0)
return;
int min_val = min(-amount[max_debit], amount[max_credit]);
amount[max_credit] -= min_val;
amount[max_debit] += min_val;
cout << "P" << max_debit << " sends " << min_val << " to " << "P" << max_credit << endl;
cashFlowTask(amount);
}
void minCashFlow(int graph[][N]) {
int amount[N] = {0};
for (int p=0; p<N; p++)
for (int i=0; i<N; i++)
amount[p] += (graph[i][p] - graph[p][i]);
cashFlowTask(amount);
}
int main() {
int graph[N][N] = {
{0, 1000, 2000},
{0, 0, 5000},
{0, 0, 0},};
minCashFlow(graph);
} ผลลัพธ์
P1 sends 4000 to P2 P0 sends 3000 to P2