リストを作成する最も簡単な方法は、次のことを行うことです。
def comparisons(seq):
return [abs(a-b) for a, b in zip(seq, seq[1:])]
あなたの比較に関しては、最高値は常に最大値になり、次に最小値が繰り返されます。例:長さ4の場合:
[3, 0, 3, 0]
これにより、毎回最大の差が生じます。length-1
(長さの)比較文字列の各項目には、これらの(の)最大の差の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
これは、可能な場合は以前の結果と一致します。