Этот вопрос беспокоит меня уже несколько дней, и я не знаю, как его решить.Я очень старался решить ее самостоятельно, но теперь я был бы очень признателен за помощь и указатель в правильном направлении.
Проблема:
Учитывая набор чисел и максимальные пределы, для которых каждое число может быть больше или меньше, чем следующий номер, определите количество действительных порядков чисел в соответствии с ограничениями.
Пример:
Числа: 20, 30, 36, 40
Максимальная сумма, на которую число может превышать следующее число: 16
Максимальная сумма, на которую число можетбыть меньше следующего числа: 8
Здесь будет 3 действительных заказа:
36 40 30 20
40 36 30 20
40 3036 20
Я разработал способ генерирования всех допустимых перестановок, используя рекурсию и деревья, но, к сожалению, это занимает слишком много времени в случаях, когда существует много допустимых порядков списка (приближается к n! Время выполнения, я считаю,).Мне кажется, что есть более быстрый, более математический способ решения этой проблемы с помощью комбинаторики, которого я просто не вижу.Буду признателен за любые советы, спасибо!
РЕДАКТИРОВАТЬ: Вот код для алгоритма перестановки, который я придумал.Последняя часть кода тестирует его на примере, который я привел выше.Это написано в Python 3.6.
class block:
def __init__(self, val, children):
self.val = val
self.children = children
# Gets all the possible children of the current head within the limits
def get_children(head, nums, b, visited, u, d):
global total
if all(visited):
total += 1
return
for i in range(b):
if not visited[i]:
if head.val - nums[i] <= d and nums[i] - head.val <= u:
head.children.append(block(nums[i], []))
visited[i] = True
get_children(head.children[-1], nums, b, visited, u, d)
visited[i] = False
# Display all the valid permutations of the current head
def show(head, vals, b):
vals.append(head.val)
if head.children == [] and len(vals) == b:
print(*vals)
return
for child in head.children:
show(child, vals[:], b)
# Test it out with the sample
b, nums, u, d = 4, [20, 30, 36, 40], 8, 16
visited = [False for x in range(b)]
total = 0
heads = []
for i in range(b):
heads.append(block(nums[i], []))
visited[i] = True
get_children(heads[-1], nums, b, visited, u, d)
visited[i] = False
show(heads[-1], [], b)
print(total)
Это печатает:
36 40 30 20
40 30 36 20
40 36 30 20
3