簡體   English   中英

序列中相鄰元素的比較

[英]Comparison between adjacent elements in sequences

我需要一個序列中元素之間的比較索引。 該索引是序列中相鄰元素之間所有絕對比較的總和與具有其長度的序列可具有的最高值之​​間的商。

例如,序列s1 = [0, 1, 2]s2 = [0, 2, 1]具有絕對比較[1, 1][2, 1] 沒有長度為3的序列的其他組合,絕對比較和的值高於3.因此,對於s1和s2,比較指數應為2/3和3/3。

這些序列總是具有從0length - 1整數,並且可以具有非相鄰的重復元素,例如[0, 1, 0, 1, 0] 這些序列在其較低和最高元素值之間具有所有整數。

我需要一個函數來計算絕對比較的最高值和給定長度的序列可以有的。 我寫的函數(最高)返回錯誤的結果。 我寫了這段代碼:

    def aux_pairs(seq):
        n = 2
        return [seq[i:i + n] for i in range(len(seq) - (n - 1))]

    def comparisons_sum(seq):
        return sum([abs(el[-1] - el[0]) for el in aux_pairs(seq)])

    def highest(seq):
        card = len(seq)
        pair = [0, card - 1]
        r = (pair * (card / 2))
        if card & 1 == 1:
            r.append(0)
        return comparisons_sum(r)

    def comparison_index(seq):
        return comparisons_sum(seq) / float(highest(seq))

生成列表的最簡單方法是:

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 )?

您提到必須包含從0length-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

這與之前的結果相符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM