Оптимизация решения проблемы «Простой балансировки нагрузки» в Codingame

Оптимизация решения проблемы «Простой балансировки нагрузки» в Codingame

Описание

В настоящее время я решаю проблему «Простой балансировки нагрузки» в Codingame, цель которой — распределить k задания между N серверами, чтобы минимизировать разницу между максимальной и минимальной нагрузкой.

Первоначальная настройка и текущий подход

import sys
import math

# Auto-generated code below aims at helping you parse
# the standard input according to the problem statement.

n = int(input())  # Number of servers
k = int(input())  # Number of jobs to distribute

# Read initial loads of servers
arr = []
for i in input().split():
    arr.append(int(i))

def load_diff(n, k, arr):
    arr.sort()
    while k > 0:
        arr[0] += 1
        k -= 1
        arr.sort()
    return arr[-1] - arr[0]

result = load_diff(n, k, arr)
print(result)

Текущий подход

  • Сортировка: я сортирую список arr после каждого распределения заданий, чтобы поддерживать порядок, гарантируя, что в первую очередь регулируется наименьшая нагрузка на сервер.
  • Увеличение нагрузки: я повторяю k раз, увеличивая нагрузку сервера с минимальной нагрузкой для распределения заданий.
  • Окончательный расчет: после распределения всех работ я рассчитываю и распечатываю разницу между максимальной и минимальной нагрузкой.

Дополнительный контекст

  • Проблема с производительностью: при выполнении всех тестовых случаев все проходят успешно, кроме тестового примера 4, в котором происходит тайм-аут (Le délai d'exécution du processus a été dépassé). Это говорит о том, что мое решение может быть недостаточно оптимизировано для эффективной обработки больших входных данных или конкретных крайних случаев.

  • Ссылка на вызов: Простая балансировка нагрузки в Codingame

Что я пробовал и чего ожидал

Подход:

  • Сортировка и распределение. Первоначально я сортировал список arr после каждого распределения заданий, чтобы поддерживать порядок и убедиться, что в первую очередь регулируется наименьшая нагрузка на сервер. Затем я повторил k раз, увеличивая нагрузку сервера с минимальной нагрузкой для распределения заданий.
  • Ожидаемый результат: я ожидал, что этот подход позволит эффективно распределить задания между серверами, минимизируя при этом разницу между максимальной и минимальной нагрузкой.
  • Фактический результат: хотя большинство тестовых случаев прошли успешно, в тестовом примере 4 произошел тайм-аут (Le délai d'exécution du processus a été dépassé), что указывает на то, что мое решение может быть недостаточно оптимизировано для больших входных данных или определенных крайних случаев.

Запрос руководства

Эта проблема является частью задачи по программированию на Codingame, и мне нужен совет по улучшению производительности и эффективности моего решения.

Любые предложения или помощь!

Вот два возможных способа ускорить решение: (1) Попробуйте добавить более 1 к arr[0] на каждой итерации цикла. Можете ли вы легко вычислить значение j так, чтобы можно было безопасно использовать arr[0] += j; k -= j вместо arr[0] += 1; k -= 1? (2) Попробуйте использовать heapq вместо многократной сортировки массива.

Stef 19.06.2024 18:50

(3) Представьте, что тестовый пример — это arr=[1,2,3,4,5,6,7,8,9,10,1000,2000,3000] и k=1000. Тогда, после нескольких итераций, массив будет выглядеть так: [10,10,10,10,10,10,10,10,10,10,1000,2000,3000] с k=955. Тогда вместо увеличения только минимума вы можете одновременно увеличивать все «равные минимумы».

Stef 19.06.2024 18:56

(Возможно, мой совет (2) по использованию heapq не так уж и хорош)

Stef 19.06.2024 18:56

@ryyyn Вопросы по алгоритмам не выходят за рамки темы Stack Overflow. Тег существует не просто так.

Unmitigated 19.06.2024 19:11

@Stef Вы на правильном пути к достижению равных минимумов; мы можем выполнить двоичный поиск наибольшего минимума, которого можно достичь.

Unmitigated 19.06.2024 19:14
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы хотим сделать минимальный элемент массива (количества заданий на каждом сервере) как можно большим, чтобы минимизировать разницу между максимальным и минимальным элементом. Чтобы сделать это эффективно, мы можем выполнить двоичный поиск наибольшего значения x, чтобы мы могли увеличить все элементы массива меньше x до значения x, используя не более k заданий. Если мы можем увеличить все элементы до максимального значения и еще остались задания для распределения, ответ будет либо 0, либо 1, в зависимости от того, можно ли равномерно распределить оставшиеся задания по n серверам.

def load_diff(n, k, arr):
    low = min(arr)
    high = max(arr)
    while low <= high:
        mid = low + high >> 1
        if sum(max(0, mid - x) for x in arr) > k:
            high = mid - 1
        else:
            low = mid + 1
    if high < max(arr):
        return max(arr) - high
    return min(1, (k - (n * max(arr) - sum(arr))) % n)

Спасибо за помощь и разъяснения <3

Kernel-rb 19.06.2024 20:16

@Kernel-rb Рад помочь.

Unmitigated 19.06.2024 20:18

Другие вопросы по теме