16

That title probably doesn't make sense. Assume the following:

  • A owes B $5
  • C owes B $10
  • B owes D $15

In this basic situation there are three transactions but it can be reduced to two transactions:

  • A gives D $5
  • C gives D $10

Given a much more complicated graph, what algorithms exist to minimize the total number of transactions?

knpwrs
  • 15,691
  • 12
  • 62
  • 103
  • I assume your target "complicated" graph is large. Is it also sparse? Is it "organic" like (say) a social network, with power-log distributed vertex degrees? – phs Sep 12 '13 at 19:17
  • I am facing the same problem (settlements, reducing transactions). Any improvement on the central counterparty algorithm? I have read around this, and seen mention of the 'maximum flow, minimum cost' problem, and the network simplex problem, but I can't map them to this situation. – Steve Hibbert Jan 25 '17 at 19:19

3 Answers3

8

It seems to me the first thing you have to figure out how much each person is up/down after all transactions take place. For your example, that would be:

A :  -5
B :   0
C : -10
D : +15

Once you have that, you just have to make them all zero. Take your highest gain, and start adding losses to it. At this point it's basically a bin-packing problem.

Geobits
  • 22,218
  • 6
  • 59
  • 103
  • 2
    Although, if your graph has disconnected components, you will get the correct distribution from a value standpoint, you might have some bogus "transactions" in the mix... – twalberg Sep 12 '13 at 19:25
  • True. I assumed you could have a transaction between any two nodes. In the OP, the answer he comes up with has `A->D` and `C->D`, neither of which are in the original. In that light, it's really not much of a "graph" at all, just a set of transactions. – Geobits Sep 12 '13 at 19:31
  • How do you know that your algorithm (take highest gain and start adding losses) leads to the most efficient allocation? – templatetypedef Sep 12 '13 at 19:51
  • That's the greedy version. In that case, you don't know it will be optimal. That's why I mentioned bin-packing, since the amount of literature available on similar problems is much more than I was willing to type out at work. – Geobits Sep 12 '13 at 19:55
  • See the detail version here.. https://www.geeksforgeeks.org/minimize-cash-flow-among-given-set-friends-borrowed-money – Manish Kumar Oct 11 '21 at 15:04
0

It might be inefficient, but you could use Integer Programming.

Precompute net flow into/out of node i, i.e. Fi = total debts + total credits

Let M be a large number.

Let Yij be decision variable denoting amount node i pays to node j (ordered pairs).

Let Xij be binary variable to indicate that a transaction took place between i & j (unordered pairs)

Optimize the following:

min sum_{i,j} Xij

sum_{j!=i} Yij = Fi

Yij + Yji= <= M*Xij

Tom Swifty
  • 2,864
  • 2
  • 16
  • 25
0

You can try the greedy method. So

If A owes money to B and B owes C then A owes C the minimum of (A->B, B->C). And A->B -= min(A->B, B->C). If after this operation A->B becomes zero then you remove it. Loop till you cannot perform any further operation ie, there're no cycles in the graph.:

do{
    bool stop = true;
    G.init() // initialize some sort of edge iterator
    while(edge = G.nextedge()){  //assuming nextedge will terminate after going through all edges once

        foreach(outedge in edge.Dest.Outedges){ //If there's any node to 'move' the cost
            minowed = min(edge.value, outedge.value)
            G.edge(edge.Src, outedge.Dest).value += minowed
            edge.value -= minowed
            outedge.value -= minowed
            if(edge.value == 0) G.remove(edge)
            if(outedge.value == 0) G.remove(outedge)
            stop = false
        }
    }
}while(!stop)

This amounts to basically removing any cycles from a graph to making it a DAG.

Arun R
  • 873
  • 6
  • 10