В настоящее время я решаю проблему «Простой балансировки нагрузки» в 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 раз, увеличивая нагрузку сервера с минимальной нагрузкой для распределения заданий.Le délai d'exécution du processus a été dépassé), что указывает на то, что мое решение может быть недостаточно оптимизировано для больших входных данных или определенных крайних случаев.Эта проблема является частью задачи по программированию на Codingame, и мне нужен совет по улучшению производительности и эффективности моего решения.
Любые предложения или помощь!
(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. Тогда вместо увеличения только минимума вы можете одновременно увеличивать все «равные минимумы».
(Возможно, мой совет (2) по использованию heapq не так уж и хорош)
@ryyyn Вопросы по алгоритмам не выходят за рамки темы Stack Overflow. Тег существует не просто так.
@Stef Вы на правильном пути к достижению равных минимумов; мы можем выполнить двоичный поиск наибольшего минимума, которого можно достичь.






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