2016-07-19 2 views
1

와 목록을 정렬 :
무작위로 다음과 같이 내가 목록을 가지고 바이어스

i = [ 
     {'id': '1', 'P': 0.5}, 
     {'id': '2', 'P': 0.4}, 
     {'id': '3', 'P': 0.8}, 
     ... 
     {'id': 'x', 'P': P(x)} 
    ] 

다음 작업을 수행 할 때

i.sort(key=lambda x: x['P'], reverse=True) 

목록은 P에 따라 분류됩니다 경우 최대를 가진 요소 P가 앞에있다. 하지만 작은 P 값 (매우 작은 확률)을 가진 요소조차도 목록의 첫 번째 항목이 될 수 있도록 무작위 화 된 것처럼 보이게하려면 어떻게해야합니까?
sort() 함수를 사용하여 구현할 수 있습니까? 아니면 직접 작성해야합니까?

+0

(분 및 최대 값)? – ayhan

+3

무작위 인 경우 실제로는 그런 종류가 아닙니다! – jonrsharpe

+1

'i.sort (key = lambda x : random.random()/x [ 'P'])'당신이 원하는 것을 하시겠습니까? 작은'P' 값으로 넓은 범위의 무작위 키를 제공하므로 대개'P'가 큰 값보다 나중에 목록에 나타납니다. 그러나 임의의 값은 항상'random.random()'의 아주 작은 결과로 운이 좋게 될 수 있으며리스트의 맨 앞에 나타납니다. – Blckknght

답변

3

의견에서 언급했듯이 표준 정규 분포에서 바이어스 요소를 샘플링하여 임의의 바이어스 수준으로 정렬 할 수 있습니다. 그런 다음이 바이어스 (0의 대칭형)를 P 값에 추가 할 수 있습니다. 그냥 표준 라이브러리 사용하려는 경우

import numpy as np 

#Give some control over the level of rearrangement - larger equals more rearrangement 
bias_factor = 0.5 

i.sort(key=lambda x: x['P'] + np.random.randn()*bias_factor, reverse=True) 

는 또는 :

from random import gauss 

#Give some control over the level of rearrangement - larger equals more rearrangement 
sigma = 0.5 

i.sort(key=lambda x: x['P'] + gauss(0, sigma), reverse=True) 
+0

이것은 합리적인 접근 방식처럼 보입니다. –

3

내 이해에 따르면, 당신은 정렬 목록을 갖고 싶어하지만 여전히 어떤 임의성을 원한다. 리스트는 동시에 랜덤으로 정렬 될 수 없습니다. 순서뿐만 아니라 비슷한 방식으로 정렬되어 있지 정확히 임의 아님을 보장하면서 가장 가까운는

i.sort(key=lambda x: x['P']*random.triangular(0.6, 1.4), reverse=True) 

이 같은 것을 통해 달성 될 수있다.

값이 0.61.4은 원하는 편차에 따라 변경 될 수 있습니다.

2

을 여기에 내 걸릴 수 있습니다 : 유사성 유사성이 0.4 점수했다 0.3과 항목 2 득점 한 해당 항목 1을 가정 해 봅시다. 그런 다음이 두 항목 중 하나를 선택할 때 항목 1은 항목 2보다 먼저 확률이 0.3/(0.3 + 0.4)이어야합니다. 이 방법으로 높은 점수를받은 항목은 이며 일반적으로입니다. 테스트를 위해

import random 

def pick(a,b,key = None): 
    ka = key(a) if key else a 
    kb = key(b) if key else b 
    if ka+kb == 0: 
     return random.int(0,1) 
    else: 
     p = ka/(ka+kb) 
     return 0 if random.random() <= p else 1 

def randMerge(xs,ys,key = None): 
    merged = [] 
    i = j = 0 
    while i < len(xs) and j < len(ys): 
     k = pick(xs[i],ys[j],key) 
     if k == 0: 
      merged.append(xs[i]) 
      i += 1 
     else: 
      merged.append(ys[j]) 
      j += 1 
    if i == len(xs): 
     merged.extend(ys[j:]) 
    else: 
     merged.extend(xs[i:]) 
    return merged 

def randSort(items,key = None): 
    if len(items) < 2: 
     return items 
    else: 
     n = len(items)//2 
     xs = items[:n] 
     ys = items[n:] 
     return randMerge(randSort(xs,key),randSort(ys,key),key) 

: 예를 들어

i = [ 
     {'id': '1', 'P': 0.5}, 
     {'id': '2', 'P': 0.4}, 
     {'id': '3', 'P': 0.8}, 
     {'id': '4', 'P': 0.9} 
    ] 

: 다음과 같은 기능이 아이디어를 통합 병합-종류의 변형 구현 P의 범위는 무엇

>>> for j in range(5): print(randSort(i,key = lambda x: x['P'])) 

[{'P': 0.5, 'id': '1'}, {'P': 0.9, 'id': '4'}, {'P': 0.8, 'id': '3'}, {'P': 0.4, 'id': '2'}] 
[{'P': 0.8, 'id': '3'}, {'P': 0.5, 'id': '1'}, {'P': 0.9, 'id': '4'}, {'P': 0.4, 'id': '2'}] 
[{'P': 0.9, 'id': '4'}, {'P': 0.5, 'id': '1'}, {'P': 0.8, 'id': '3'}, {'P': 0.4, 'id': '2'}] 
[{'P': 0.5, 'id': '1'}, {'P': 0.8, 'id': '3'}, {'P': 0.9, 'id': '4'}, {'P': 0.4, 'id': '2'}] 
[{'P': 0.8, 'id': '3'}, {'P': 0.4, 'id': '2'}, {'P': 0.9, 'id': '4'}, {'P': 0.5, 'id': '1'}] 
관련 문제