Самый простой способ для создания списка является просто сделать:
def comparisons(seq):
return [abs(a-b) for a, b in zip(seq, seq[1:])]
Что касается вашего сравнения, максимальное значение всегда будет максимально сопровождаемый минимальный, повторный. Например: для длины 4:
[3, 0, 3, 0]
Поскольку это будет производить максимальную разницу каждый раз. Будет одна из этих максимальных разностей (length-1
) для каждого элемента в строке сравнения (длиной length-1
). Следовательно, максимум будет (length-1)**2
.
Однако, как представляется, означает, что максимум для длины 3 был 3
, так почему [0, 2, 0]
не действует (производство [2, 2]
, который суммирует в 4
)?
Вы упомянули, что все целые числа от 0
до length-1
должны быть включены, но это делает некоторые из ваших примеров (например: [0, 1, 0]
) недействительными. Это также противоречит идее, что любые элементы могут быть повторены (если список длины n должен содержать от 0 до n-1, он не может иметь повторений).
Если этот случай верен, тогда ваш вопрос будет несколько похож на проблему создания матрицы сглаживания.
В случае заказа диапазона от 0 до len-1, чтобы получить максимальную разницу, оптимальный алгоритм должен работать от 0 и ниже от len-1, добавляя низкие значения к самой высокой стороне 'из списка, и наоборот:
from collections import deque
from itertools import permutations
from operator import itemgetter
def comparisons(seq):
return [abs(a-b) for a, b in zip(seq, seq[1:])]
def best_order(n):
temp = deque([0, n-1])
low = 1
high = n-2
while low < high:
left = temp[0]
right = temp[-1]
if left < right:
temp.append(low)
temp.appendleft(high)
else:
temp.append(high)
temp.appendleft(low)
low += 1
high -= 1
if len(temp) < n:
temp.append(low)
return list(temp)
def brute_force(n):
getcomp = itemgetter(2)
return max([(list(a), comparisons(a), sum(comparisons(a))) for a in permutations(range(n))], key=getcomp)
for i in range(2, 6):
print("Algorithmic:", best_order(i), comparisons(best_order(i)), sum(comparisons(best_order(i))))
print("Brute Force:", *brute_force(i))
который дает нам:
Algorithmic: [0, 1] [1] 1
Brute Force: [0, 1] [1] 1
Algorithmic: [0, 2, 1] [2, 1] 3
Brute Force: [0, 2, 1] [2, 1] 3
Algorithmic: [2, 0, 3, 1] [2, 3, 2] 7
Brute Force: [1, 3, 0, 2] [2, 3, 2] 7
Algorithmic: [3, 0, 4, 1, 2] [3, 4, 3, 1] 11
Brute Force: [1, 3, 0, 4, 2] [2, 3, 4, 2] 11
Показано, что этот алгоритм соответствует грубой силы подход для получения наилучшего возможного результата.
Далее следует более общее решение:
from collections import deque
def comparisons(seq):
return [abs(a-b) for a, b in zip(seq, seq[1:])]
def best_order(seq):
pool = deque(sorted(seq))
temp = deque([pool.popleft(), pool.pop()])
try:
while pool:
if temp[0] < temp[-1]:
temp.append(pool.popleft())
temp.appendleft(pool.pop())
else:
temp.append(pool.pop())
temp.appendleft(pool.popleft())
except IndexError:
pass
return list(temp)
i = [0, 1, 2, 3, 4, 5, 6, 0, 0, 1, 1, 2, 2]
print("Algorithmic:", best_order(i), comparisons(best_order(i)), sum(comparisons(best_order(i))))
for n in range(2, 6):
i = list(range(n))
print("Algorithmic:", best_order(i), comparisons(best_order(i)), sum(comparisons(best_order(i))))
Что дает:
Algorithmic: [2, 1, 3, 0, 5, 0, 6, 0, 4, 1, 2, 1, 2] [1, 2, 3, 5, 5, 6, 6, 4, 3, 1, 1, 1] 38
Algorithmic: [0, 1] [1] 1
Algorithmic: [0, 2, 1] [2, 1] 3
Algorithmic: [2, 0, 3, 1] [2, 3, 2] 7
Algorithmic: [3, 0, 4, 1, 2] [3, 4, 3, 1] 11
который соответствует предыдущим результатам, где это возможно.
Я не совсем уверен, что вы собираетесь делать с индексом сравнения, не могли бы вы уточнить? Разве это не просто '' sum (comp)/len (seq) ''? –
@Lattyware, индекс, возможно, не лучший термин для описания того, что мне нужно. Знаменателем должно быть сравнение последовательности с максимальной суммой (com) во всех последовательностях с этой длиной. Например, возьмите длину 3: – msampaio
Извините, я нажал enter. Продолжение ... Принять длину 3 последовательности и их сумму (ком): [0, 1, 0] 2 [0, 1, 2] 2 [0, 2, 1] 3 [1, 0, 1] ] 2 [1, 0, 2] 3 [1, 2, 0] 3 [2, 0, 1] 3 [2, 1, 0] 2 Максимальное значение суммы (com) с длиной 3 3. Таким образом, знаменатель моего «индекса» должен быть равен 3. – msampaio