Simplify the global payback matrix

Added a new feature. The "global payback matrix" is now simplified in
order to minimize the number of exchanges between members.
This commit is contained in:
Phyks 2013-11-12 19:54:52 +01:00
parent 38e8bcc766
commit 06abe6bbc6
3 changed files with 52 additions and 1 deletions

1
TODO
View File

@ -1,5 +1,4 @@
* Notifications by e-mail for users
* Simplify matrix
* Mask invoices when user is not concerned in "show all invoices"
Improvements :

View File

@ -97,3 +97,11 @@
return mail ($to, $subject, $msg, $header);
}
// Function to sort an array by abs desc
function sort_array_abs($a, $b) {
if(abs($a) == abs($b))
return 0;
return (abs($a) < abs($b)) ? 1 : -1;
}

View File

@ -952,6 +952,50 @@
}
}
// Now, let's simplify the matrix ! :)
// First, get the total balance by user (gains - debts)
$balances = array();
$simplified_balances = array();
foreach($_POST['users_in'] as $user) {
$balances[$user] = 0;
foreach($_POST['users_in'] as $user2) {
if(!empty($users_in[$user][$user2])) {
$balances[$user] -= $users_in[$user][$user2];
}
if(!empty($users_in[$user2][$user])) {
$balances[$user] += $users_in[$user2][$user];
}
$simplified_balances[$user][$user2] = 0;
}
}
// Do while $balances is not identically filled with zeros
while(count(array_unique($balances)) != 1 or $balances[key($balances)] != 0) {
// Sort balances in abs values, desc
uasort($balances, "sort_array_abs");
// Get the largest one in abs
// The following largest with opposite sign must pay him back the max
reset($balances);
$user1 = key($balances);
foreach($balances as $user2=>$value) {
if($value * $balances[$user1] < 0) {
if($balances[$user1] > 0) {
$simplified_balances[$user2][$user1] = abs($value);
$balances[$user1] -= abs($value);
$balances[$user2] += abs($value);
}
else {
$simplified_balances[$user1][$user2] = abs($value);
$balances[$user1] += abs($value);
$balances[$user2] -= abs($value);
}
break;
}
}
}
$global_payback->setUsersIn($users_in);
if($global_payback->getUsersIn()->isEmpty()) {