Пример #1
0
            public void Optimize()
            {
                var Optimizer = new SpendingOptimizer(matrix);

                Optimizer.Optimize();
                matrix = Optimizer.GetResult();
            }
Пример #2
0
        public async Task OptimizeSpendingForGroup(long groupId)
        {
            var currentGroup = await DbContext.Groups
                               .Include(x => x.Members)
                               .SingleOrDefaultAsync(x => x.Id == groupId);

            if (currentGroup == null)
            {
                throw new ResourceGoneException("group_gone");
            }

            var currentGroupSettleMents = DbContext.Settlements.Where(x => x.GroupId == groupId);

            var Spendings = await GetSpendingsForGroup(groupId);

            Dictionary <int, long> NumberToId = new Dictionary <int, long>();
            Dictionary <long, int> IdToNumber = new Dictionary <long, int>();
            {
                int i = 0;
                foreach (var MemberId in currentGroup.Members.Select(x => x.UserId))
                {
                    NumberToId.Add(i, MemberId);
                    IdToNumber.Add(MemberId, i);
                    i++;
                }
            }



            int ingroup = NumberToId.Count;

            long[,] owes = new long[ingroup, ingroup];
            for (int i = 0; i < ingroup; i++)
            {
                var iSpending = Spendings.Where(x => x.CreditorUserId == NumberToId[i]);
                foreach (DaoSpending ds in iSpending)
                {
                    foreach (DaoDebtor dd in ds.Debtors)
                    {
                        owes[IdToNumber[dd.DebtorUserId], i] += dd.Debt ?? 0;
                    }
                }
            }

            foreach (var settlement in currentGroupSettleMents)
            {
                if (currentGroup.Members.Any(x => x.UserId == settlement.From) && currentGroup.Members.Any(x => x.UserId == settlement.To))
                {
                    owes[IdToNumber[settlement.To], IdToNumber[settlement.From]] += settlement.Amount;
                }
            }

            for (int i = 0; i < ingroup; i++)
            {
                owes[i, i] = 0;
            }

            var Optimizer = new SpendingOptimizer(owes, ingroup);

            Optimizer.Optimize();
            owes = Optimizer.GetResult();
            var oldOptimized = await DbContext.OptimizedDebt.Where(x => x.GroupId == groupId).ToListAsync();

            DbContext.OptimizedDebt.RemoveRange(oldOptimized);
            for (int i = 0; i < ingroup; i++)
            {
                for (int j = 0; j < ingroup; j++)
                {
                    if (owes[i, j] > 0)
                    {
                        DaoOptimizedDebt optdebt = new DaoOptimizedDebt()
                        {
                            GroupId    = groupId,
                            UserOwesId = NumberToId[i],
                            UserOwedId = NumberToId[j],
                            OweAmount  = owes[i, j]
                        };
                        await DbContext.OptimizedDebt.AddAsync(optdebt);
                    }
                }
            }
            await DbContext.SaveChangesAsync();

            //save results
        }