Skip to content

Commit

Permalink
Merge branch 'master' into add-view-command
Browse files Browse the repository at this point in the history
  • Loading branch information
Aulud committed Oct 29, 2019
2 parents ceb07c5 + 31149c6 commit b1bdbb1
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions docs/DeveloperGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,70 @@ Step 3. The user executes `activity t/Lunch p/Alex p/David` command to create an
** Pros: Easy to implement. Low possibility of bugs.
** Cons: Significantly decreases usability of the application.

// tag::algorithm[]
=== Debt simplification algorithm
The algorithm is inspired by https://pure.tue.nl/ws/portalfiles/portal/2062204/623903.pdf[this paper].

We can gurantee the removal of all needless payments.
The amount of money each person has to hand is minimized.
We are unable to minimize the number of transactions made.
The paper gives an overview of that problem and why it is NP-complete (subset-sum).

==== Operation details
The amounts each person owes to another is represented by a graph in an adjacency matrix.
The algorithm represents the payments to be made as a matrix.
There are some other data structures to facilitate its operation, but the code is generally well commented and they are not major player so we will skip them.
Also note that the matrices are necesarrily skew-symmetric: for example if A owes B $10, then B owes A $-10.

To rephrase our gurantee in this context will be: we want to minimize weights.
We do not care about the number of edges.
Certainly we do not mean each person repeatedly pays out $1, $1, $1!
Our idea of "minimum weights" refer to the total amount someone has to handle.

The lower bound for the amount someone has to handle is the balance.
We create a balance sheeet for the users which is expanded as people enter the activity.
Each expense added, the algorithm retrieves from it:
* who is involved,
* who paid,
* how much has been paid,
splits everything correctly, and updates all the data structures appropriately.

Someone's balance is positive if he received more than he owes.
Then, a negative balance indicates them lending more than they received.
The algorithm simply finds any two people whose balances have opposing signs.
It is unimportant what is the magnitude of their balances (we do not need to take them in any order).
What then happens is then the person with the smallest magnitude of balance neutralizes his balance by paying or being paid by the other party.
The algorithm terminates when all balances are 0.

==== Proof of optimality
This is a short proof of optimality since we want it to be called "algorithm", not "heuristic".

In essence what we are constructing is a bipartite graph.
The algorithm never allows someone who owes to be paid, or someone who is owed to pay even more.
Hence we can classify all nodes into those with leaving edges (payers) and those with entering edges (payee).

In a bipartite graph the amount each person handles is minimized.
To see why, we have to keep in mind that the algorithm always neutralizes one of the parties' balance.
That is to say, we will not be left with the case where someone who could pay off all his debts "overpaying".
In such a case, someone will then have to pay him back, which means it is no longer bipartite.

==== Time and Space complexity
We take O(N^2) space and O(N) time.
Updating of the balance sheet and matrices by the expense command is performed in O(1) time.

==== Design Considerations

===== Aspect: Precision

* **Alternative 1 (current choice):** Just use `double`.
** *Pros*: Easy, straightforward, good enough.
** *Cons*: Floating point precision might stack up.
** *Reason for choice*: For everyday purposes it is highly unlikely currencies (normally at most 2 decimal points) require any higher precision. This is for normal friends, not stockbrokers.

* **Alternative 2:** Implement a `Rational` class for rational numbers.
** Pros: Guranteed precision.
** Cons: Seems overkill and needlessly over-engineered.

=== List feature

The List mechanism is facilitated by the combination of three classes `MainWindow`, `Model` and `Context`.
Expand Down

0 comments on commit b1bdbb1

Please sign in to comment.