В похожем вопросе я спросил, как распределять целые числа с использованием весов. Мне любопытно, как можно было бы подойти к этой проблеме, если бы было введено минимальное значение для каждого «ведра» распределения. При установлении минимального значения это кажется гораздо более сложной проблемой. Вот моя жадная попытка, которая не работает:
def distribute(available, weights_and_mins):
distributed_amounts = []
total_weight = sum([i[0] for i in weights_and_mins])
for weight, minimum in weights_and_mins:
weight = float(weight)
p = weight / total_weight
distributed_amount = round(p * available)
if distributed_amount < minimum:
distributed_amount = minimum
distributed_amounts.append(distributed_amount)
available -= distributed_amount
total_weight -= weight
return [int(i) for i in distributed_amounts]
print distribute(10, ((10,1), (2,5), (2,4)))
print distribute(1000, ((10,1), (2,5), (2,4)))
В настоящее время значения распределяются как [7, 5, 4], что составляет 16, что на 6 больше, чем мы должны распределить. Вывод должен быть [1, 5, 4], так как это удовлетворяет минимальным требованиям для всех столбцов. По мере роста стоимости, которую мы должны распределить, распределения должны быть все ближе и ближе к правильному взвешенному распределению. Например, распределяя 1000, алгоритм правильно распределяет значения как [714, 143, 143].
В качестве примечания: моя цель — распределить доступное пространство (ширину) между несколькими столбцами. Все столбцы имеют минимальный размер, необходимый для того, чтобы «обойти» и отобразить хотя бы часть своих данных, а некоторые столбцы нуждаются в большем количестве места по мере роста доступного пространства. Я упомянул это как одно из реальных применений этого алгоритма, но я не хочу, чтобы это было обсуждением дизайна графического интерфейса.
Какие есть решения этой проблемы? Чем проще, тем лучше.
[7, 5, 5]
в качестве вывода для первого фрагмента. - person Blender   schedule 02.02.2012available - sum(minima)
. - person John Machin   schedule 02.02.2012