Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create algorithm to minimise total number of transactions #58

Merged
merged 21 commits into from
Aug 26, 2022

Conversation

IsaacCheng9
Copy link
Owner

@IsaacCheng9 IsaacCheng9 commented Aug 26, 2022

Summary

  • Created an algorithm to minimise the total number of transactions.
    • This recalculates the transactions required to reach a zero-state in debts every time there is an update to the debts (expense added/debt settled).
  • As the underlying problem is np-complete, this algorithm is a heuristic.
    • It runs in O(k * n log n), where k is the number of debts and n is the number of users.
    • The algorithm calculates the total net debt for each user, then creates two min-heaps (one for debt and one for credit).
    • It pops from the min-heaps and creates the transaction between the two popped users until it reaches a zero-state in debt.
  • In the future, we could optimise the algorithm to O(n log n) by denormalising the user debts.
    • The algorithm currently spends O(k) time going through all debts and calculating the net debt for each user.
    • If we store this in a separate collection and update it every time a debt pair is updated, we'll save repeated work.

Note that this hasn't been implemented in the front-end yet – we should add a switch that allows the user to turn this on (and a hint explaining what it does), as it may otherwise cause confusion. I've created issue #59 to track this.

Related Issues

Fixes issue #8.

Resources

Example

Originally six transactions -> four transactions after algorithm applied:

FairSplit - Minimising Transactions@2x

[
  {
    _id: new ObjectId("6308be56359b0cfb02ccb0c3"),
    from: 'user4',
    to: 'user2',
    amount: 2000,
    __v: 0
  },
  {
    _id: new ObjectId("6308c0ef359b0cfb02ccb0d9"),
    from: 'user1',
    to: 'user4',
    amount: 2000,
    __v: 0
  },
  {
    _id: new ObjectId("6308cc75bc58e8af84d40c7f"),
    from: 'user1',
    to: 'user3',
    amount: 1000,
    __v: 0
  },
  {
    _id: new ObjectId("6308ccc7bc58e8af84d40c8b"),
    from: 'user4',
    to: 'user5',
    amount: 2000,
    __v: 0
  },
  {
    _id: new ObjectId("6308ccdebc58e8af84d40c9b"),
    from: 'user6',
    to: 'user5',
    amount: 3000,
    __v: 0
  },
  {
    _id: new ObjectId("6308ccf3bc58e8af84d40cad"),
    from: 'user5',
    to: 'user1',
    amount: 4000,
    __v: 0
  }
]
-------------------------------------------------------------
Map(6) {
  'user4' => 2000,
  'user2' => -2000,
  'user1' => -1000,
  'user3' => -1000,
  'user5' => -1000,
  'user6' => 3000
}
Heap {
  cmp: [Function (anonymous)],
  nodes: [
    { username: 'user4', amount: 2000 },
    { username: 'user6', amount: 3000 }
  ]
}
Heap {
  cmp: [Function (anonymous)],
  nodes: [
    { username: 'user1', amount: 1000 },
    { username: 'user5', amount: 1000 },
    { username: 'user3', amount: 1000 },
    { username: 'user2', amount: 2000 }
  ]
}




Heap {
  cmp: [Function (anonymous)],
  nodes: [
    { username: 'user4', amount: 1000 },
    { username: 'user6', amount: 3000 }
  ]
}
Heap {
  cmp: [Function (anonymous)],
  nodes: [
    { username: 'user3', amount: 1000 },
    { username: 'user5', amount: 1000 },
    { username: 'user2', amount: 2000 }
  ]
}




Heap {
  cmp: [Function (anonymous)],
  nodes: [ { username: 'user6', amount: 3000 } ]
}
Heap {
  cmp: [Function (anonymous)],
  nodes: [
    { username: 'user5', amount: 1000 },
    { username: 'user2', amount: 2000 }
  ]
}




Heap {
  cmp: [Function (anonymous)],
  nodes: [ { username: 'user6', amount: 2000 } ]
}
Heap {
  cmp: [Function (anonymous)],
  nodes: [ { username: 'user2', amount: 2000 } ]
}




Heap { cmp: [Function (anonymous)], nodes: [] }
Heap { cmp: [Function (anonymous)], nodes: [] }

Copy link
Collaborator

@gkSideProjects gkSideProjects left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great stuff, everything working as expected!

@IsaacCheng9 IsaacCheng9 merged commit 525b6f6 into main Aug 26, 2022
@IsaacCheng9 IsaacCheng9 deleted the minimise-number-of-transactions branch August 26, 2022 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create algorithm for minimising number of transactions
2 participants