Who owes who money optimization

后端 未结 10 1273
暗喜
暗喜 2020-12-14 02:18

Say you have n people, each who owe each other money. In general it should be possible to reduce the amount of transactions that need to take place. i.e. if X owes Y £4 and

10条回答
  •  遥遥无期
    2020-12-14 02:57

    I have a solution to the problem written in matlab. It is based on a matrix of who owes who what. The number in the (i,j) means that person j owes person i the number. E.g.

    B owes A 2 and A owes B 1

    of course in this case it is trivial that B should just give A 1

    This becomes more complex with more entries. However, with the algorithm i wrote i can guarantee that no more than N-1 transactions occurs where N is the number of persones 2 in this case.

    Here is the code i wrote.

    function out = whooweswho(matrix)
    %input sanitation
    if ~isposintscalar(matrix)
        [N M] = size(matrix);
        if N ~= M
            error('Matrix must be square');
        end
    
        for i=1:N
            if matrix(N,N) ~= 0
                error('Matrix must have zero on diagonals');
            end
        end
    else
        %construction of example matrix if input is a positive scalar
        disp('scalar input: Showing example of NxN matrix randomly filled');
        N = matrix;
        matrix = round(10*N*rand(N,N)).*(ones(N,N)-eye(N))
    end
    
    %construction of vector containing each persons balance
    net = zeros(N,1);
    for i=1:N
      net(i) = sum(matrix(i,:))-sum(matrix(:,i));
    end
    
    %zero matrix, so it can be used for the result
    matrix = zeros(size(matrix));
    
    %sum(net) == 0 always as no money dissappears. So if min(net) == 0 it
    %implies that all balances are zero and we are done.
    while min(net) ~= 0
      %find the poorest and the richest.
      [rec_amount reciever] = max(net);
      [give_amount giver] = min(net);
      %balance so at least one of them gets zero balance.
      amount =min(abs(rec_amount),abs(give_amount));
      net(reciever) = net(reciever) - amount;
      net(giver) = net(giver) + amount;
      %store result in matrix.
      matrix(reciever,giver) = amount;
    end
    %output equivalent matrix of input just reduced.
    out = matrix;
    

    end

提交回复
热议问题