R
R
Romario212018-06-25 17:20:43
Algorithms
Romario21, 2018-06-25 17:20:43

Algorithm for uniform distribution of requests?

C#, Java
Comrades, I ask for help.
There is a list of managers with the number of applications on hand
. A new batch of applications comes into the system, the task is to equally distribute them among managers. So that everyone would have approximately the same number. At the initial moment, all managers have a different number of hands
Lena - 1
Olya - 10
Ivan -35
Sergey - 75

Example: A new batch of applications has arrived: 35pcs.
Lena - (was) 1 + 22 (from the pack) \u003d 23 (became)
Olya - (was) 10 + 13 (from the pack) \u003d 23 (became)
Ivan -35
Sergey - 75

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Pavlov, 2018-06-26
@Romario21

foreach (var newOrder in newOrders)
{
    // ищем минимальное количество заявок среди всех менеджеров
    var minOrdersCount = managers.Min(m => m.Orders.Count);
    // ищем менеджера с найденным количеством (если несколько - берём первого)
    var manager = managers.First(m => m.Orders.Count == minOrdersCount);
    // даём заявку менее занятому менеджеру
    manager.Orders.Add(newOrder);
}

This algorithm is not the fastest - first, the number of applications from all managers is constantly searched, then the search for a manager with a minimum number of applications.
Here is a more complicated algorithm, there are fewer searches for all managers (especially when there are a large number of new applications):
class Manager
{
    public string Name { get; private set; }
    public List<int> Orders { get; private set; }

    public Manager(string name, int ordersCount = 0)
    {
        Name = name;
        Orders = ordersCount > 0
            ? Enumerable.Range(1, ordersCount).ToList()
            : new List<int>();
    }
}

static void Main(string[] args)
{
    var managers = new Manager[]
    {
        new Manager("Лена", 1), 
        new Manager("Оля", 10), 
        new Manager("Иван", 35), 
        new Manager("Сергей", 75), 
    };
    var newOrders = Enumerable.Range(1, 35).ToList();
    var newOrdersCount = newOrders.Count;
    var ordersAssigned = 0;

    while (ordersAssigned < newOrdersCount)
    {
        var ordersCounts = managers.Select(m => m.Orders.Count).OrderBy(count => count).Distinct().ToArray();
        var addingOrdersCount = ordersCounts.Length > 1 ? ordersCounts[1] - ordersCounts[0] : ordersCounts.First();
        var managersWithMinOrders = managers.Where(m => m.Orders.Count == ordersCounts[0]).ToArray();
        // нашли менеджеров с минимальным количеством заявок
        if (managersWithMinOrders.Length * addingOrdersCount < newOrdersCount)
        { // заполняем самых незанятых менеджеров до того же уровня занятости
          // т.е. добавляем Лене (10 - 1) = 9 заявок
            foreach (var manager in managersWithMinOrders)
            {
                for (int i = 0; i < addingOrdersCount; i++)
                {
                    manager.Orders.Add(newOrders[ordersAssigned]);
                    ordersAssigned++;
                }
            }
        }
        else
        {
            // незанятых менеджеров нет, заполняем оставшиеся заявки по менеджерам по очереди
            while (ordersAssigned < newOrdersCount)
            {
                var managerIndex = ordersAssigned % managersWithMinOrders.Length;
                managersWithMinOrders[managerIndex].Orders.Add(newOrders[ordersAssigned]);
                ordersAssigned++;
            }
        }
    }

    foreach (var manager in managers)
    {
        Console.WriteLine("{0}: {1} заявок", manager.Name, manager.Orders.Count);
    }
    Console.ReadKey();
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question