development

목록이 얼마나 정렬되어 있는지 측정하는 방법이 있습니까?

big-blog 2020. 6. 3. 08:04
반응형

목록이 얼마나 정렬되어 있는지 측정하는 방법이 있습니까?


목록이 얼마나 정렬되어 있는지 측정하는 방법이 있습니까?

리스트가 정렬되어 있는지 아닌지 (부울) 아는 것이 아니라 통계의 상관 계수와 같은 "정렬"의 비율과 같은 것입니다.

예를 들어

  • 목록의 항목이 오름차순이면 해당 비율은 1.0입니다.

  • 목록이 내림차순으로 정렬되면 비율은 -1.0입니다.

  • 목록이 거의 오름차순으로 정렬되면 비율은 0.9 또는 1에 가까운 값입니다.

  • 목록이 전혀 정렬되지 않은 경우 (임의의 경우) 비율은 0에 가깝습니다.

실습을 위해 스칼라에 작은 도서관을 쓰고 있습니다. 정렬 속도가 도움이 될 것이라고 생각하지만 그와 같은 정보는 찾지 못했습니다. 어쩌면 나는 그 개념에 대한 적절한 용어를 모른다.


목록에서 반전 수를 간단히 계산할 수 있습니다.

전도

유형의 요소 시퀀스에서 반전 T은의 세트에서 일부 순서 <따라 순서가 다르게 나타나는 한 쌍의 시퀀스 요소입니다 T.

에서 위키 백과 :

공식적으로 A(1), A(2), ..., A(n)일련의 n숫자를 보자 .
경우 i < jA(i) > A(j), 그 쌍은 (i,j)이라고 반전 의를 A.

시퀀스 반전 번호 는 정렬의 일반적인 측정 방법 중 하나입니다.
공식적으로, 반전 번호는 반전 횟수, 즉,

정의

이러한 정의를보다 명확하게하려면 sequence 예제를 고려하십시오 9, 5, 7, 6. 이 순서에는 반전 (0,1), (0,2), (0,3), (2,3)반전 번호가 4 있습니다.

0사이의 값을 원하면 1반전 숫자를로 나눌 수 있습니다 N choose 2.

목록 정렬 방식에 대해이 점수를 계산하는 알고리즘을 실제로 만들려면 다음 두 가지 방법이 있습니다.

접근법 1 (결정 론적)

자주 사용하는 정렬 알고리즘을 수정하여 실행시 수정되는 반전 수를 추적하십시오. 이것은 사소하지 않으며 선택한 정렬 알고리즘에 따라 다양한 구현이 있지만, 시작한 정렬 알고리즘보다 비싸지 않은 (복잡성 측면에서) 알고리즘으로 끝납니다.

이 경로를 사용하는 경우 "스왑"을 계산하는 것만 큼 간단하지는 않습니다. 예를 들어 Mergesort는 최악의 경우 O(N log N)이지만 내림차순으로 정렬 된 목록에서 실행하면 모든 N choose 2반전 이 수정됩니다 . 그것은 작업 O(N^2)에서 수정 된 반전 O(N log N)입니다. 따라서 일부 작업은 불가피하게 한 번에 두 개 이상의 반전을 수정해야합니다. 구현에주의를 기울여야합니다. 참고 : O(N log N)복잡 하게이 작업을 수행 할 수 있습니다 .

관련 : 순열에서 "반전"수 계산

접근법 2 (확률 론적)

  • 무작위로 샘플 쌍 (i,j),i != j
  • 각 쌍에 대해 list[min(i,j)] < list[max(i,j)](0 또는 1)
  • 이러한 비교의 평균을 계산 한 다음 N choose 2

정확성이 요구되지 않는 한 개인적으로 확률 적 접근 방식을 사용합니다. 구현하기가 쉽기 때문입니다.


당신이 정말로 원하는 것은 값 (경우 z'사이) -1에 (정렬 내림차순) 1(정렬 오름차순)는, 당신은 단순히 위의 값 (매핑 할 수 있습니다 z사이에), 0(정렬 오름차순) 및 1공식을 사용하여이 범위 (정렬 내림차순) :

z' = -2 * z + 1

목록 (또는 다른 순차적 구조)을 정렬하는 방법에 대한 전통적인 측정 방법은 반전의 수입니다.

반전 수는 a <b AND b a의 쌍 (a, b) st 인덱스 수입니다 <<. 이러한 목적 <<을 위해 특정 정렬에 대해 선택한 주문 관계를 나타냅니다.

완전히 정렬 된 목록에는 반전이없고 완전히 반대의 목록에는 최대 반전 수가 있습니다.


실제 상관 관계를 사용할 수 있습니다.

정렬 된 목록의 각 항목에 0부터 시작하는 정수 순위를 지정한다고 가정하십시오. 요소 위치 인덱스 대 순위의 그래프는 직선의 점처럼 보입니다 (위치와 순위 사이의 상관 관계는 1.0).

이 데이터에 대한 상관 관계를 계산할 수 있습니다. 역 정렬의 경우 -1 등이 표시됩니다.


큰 답이 있었고, 완성도를 위해 수학적 측면을 추가하고 싶습니다.

  • 정렬 된 목록과 얼마나 관련되어 있는지 측정하여 목록이 정렬 된 정도를 측정 할 수 있습니다. 그렇게하려면 순위 상관 관계 (가장 알려진 Spearman 's )를 사용하면 일반적인 상관 관계와 정확히 동일하지만 항목의 아날로그 값 대신 목록에서 요소의 순위를 사용합니다.

  • 상관 계수 (정확한 정렬의 경우 +1, 정확한 반전의 경우 -1) 와 같은 많은 확장이 존재합니다.

  • 이를 통해 순열 중심 한계 정리와 같이이 측정에 대한 통계적 속성을 가질 수 있으며,이를 통해 임의의 목록에 대한이 측정의 분포를 알 수 있습니다.


숫자 목록의 경우 반전 수를 제외하고 정렬 된 상태에서 평균 제곱 거리를 상상할 수 있습니다.

#! ruby
d = -> a { a.zip( a.sort ).map { |u, v| ( u - v ) ** 2 }.reduce( :+ ) ** 0.5 }

a = 8, 7, 3, 4, 10, 9, 6, 2, 5, 1
d.( a ) #=> 15.556
d.( a.sort ) #=> 0.0
d.( a.sort.reverse ) # => 18.166 is the worrst case

I am not sure of the "best" method, but a simple one would be to compare every element with the one after it, incrementing a counter if element2 > element 1 (or whatever you want to test) and then divide by the total number of elements. It should give you a percentage.


I would count comparisons and divide it to the total number of comparisons. Here is a simple Python example.

my_list = [1,4,5,6,9,-1,5,3,55,11,12,13,14]

right_comparison_count = 0

for i in range(len(my_list)-1):
    if my_list[i] < my_list[i+1]: # Assume you want to it ascending order
        right_comparison_count += 1

if right_comparison_count == 0:
    result = -1
else:
    result = float(right_comparison_count) / float((len(my_list) - 1))

print result

How about something like this?

#!/usr/bin/python3

def sign(x, y):
   if x < y:
      return 1
   elif x > y:
      return -1
   else:
      return 0

def mean(list_):
   return float(sum(list_)) / float(len(list_))

def main():
   list_ = [ 1, 2, 3, 4, 6, 5, 7, 8 ]
   signs = []
   # this zip is pairing up element 0, 1, then 1, 2, then 2, 3, etc...
   for elem1, elem2 in zip(list_[:-1], list_[1:]):
      signs.append(sign(elem1, elem2))

   # This should print 1 for a sorted list, -1 for a list that is in reverse order
   # and 0 for a run of the same numbers, like all 4's
   print(mean(signs))

main()

If you take your list, calculate the ranks of the values in that list and call the list of ranks Y and another list, X that contains the integers from 1 to length(Y), you can obtain exactly the measure of sortedness that you are looking for by calculating the correlation coefficient, r, between the two lists.

r = \frac{\sum ^n _{i=1}(X_i - \bar{X})(Y_i - \bar{Y})}{\sqrt{\sum ^n _{i=1}(X_i - \bar{X})^2} \sqrt{\sum ^n _{i=1}(Y_i - \bar{Y})^2}} 

완전 정렬 된 목록의 경우 r = 1.0, 역방향 정렬 된 목록의 경우 r=-1.0, r다양한 정렬 수준에 대한 이러한 한계 사이 차이가 있습니다.

응용 프로그램에 따라이 방법의 가능한 문제점은 목록에서 각 항목의 순위를 계산하는 것이 정렬하는 것과 동일하므로 O (n log n) 연산입니다.

참고 URL : https://stackoverflow.com/questions/16994668/is-there-a-way-to-measure-how-sorted-a-list-is

반응형