2014-10-22 1 views
0
I 라인 당 세 "랜덤"값 (10 개 라인)로 채워진 파일을 생성 할 필요

로 수 있지만, 그 값의 합이 15"슬라이스"세 난수

구조가 동일해야 "INDEX를 알파벳".

예 :

1 15 0 0 
2 0 15 0 
3 0 0 15 
4 1 14 0 
5 2 13 0 
6 3 12 0 
7 4 11 0 
8 5 10 0 
9 6 9 0 
10 7 8 0 
+3

https : //codegolf.stackexchange.com/questions/8574/generation-n-unique-random-numbers-a-specific-sum – CoryKramer

+0

"임의"로하면 실제 엔트로피가 실제로 필요합니까 (처음 세 예제는 그렇지 않다고 주장하는 것처럼 보입니다. 그러나 그것은 오도 된 것일 수 있습니다), 아니면 당신은 단지 "임의적 인, 나는 상관 없습니다"를 의미합니까? – abarnert

+0

그냥 내 문제를 해결합니다. 감사! –

답변

2

숫자가 어떤 단지 조합을 사용할 수 있습니다로하는 경우 : 당신이 만족 순열의 전체 공간을 (만들 필요하지 않도록 (또는 통해 반복)를 선택합니다

from itertools import combinations 
with open("rand.txt","w") as f: 
    combs = [x for x in combinations(range(16),3) if sum(x) == 15 ][:10] 
    for a,b,c in combs: 
     f.write("{} {} {}\n".format(a,b,c)) 
+0

나는 처음 세 행이 주어지면 거기에서'range (16)'를 원한다고 생각합니다. – abarnert

+1

또한 생성하는 조합 중 541/560을 버리는 것은 다소 비효율적이지만 문제가 될지는 의심 스럽지만이 코드의 단순함이이를 보충하는 것보다 낫다고 생각합니다. – abarnert

+0

@abarnert, 예, 16으로 변경되었습니다. 확실히 효율이 좋지 않지만 OP가 원하는 것은 괜찮을 것입니다. –

4

을 큰 경우 N이 중요 함) 순차 샘플로이 문제를 해결할 수 있습니다.

첫 번째 방법은 [0, N]에서 값을 균일하게 그려야한다는 것입니다. x이라고 부릅니다. 그런 다음 [0, N- x]에서 값을 균등하게 그려서 y로 지정한 다음 z = N - x - y을 설정합니다. 이 세 가지를 섞으면 솔루션 공간에서 합리적인 추첨을 되 찾을 수 있지만 정확하게 일치하지는 않습니다.

예를 들어, 다음을 고려하십시오. N=3. 그렇다면 (10, 0, 0)의 순열의 확률은 가능한 10 개 중 하나 일 뿐이지 만 1/4입니다. 따라서이 값은 높은 최대 값을 포함하는 권한 값입니다.

x에 대한 y에 대해 가능한 값의 수에 비례하여 첫 번째 값인 x을 샘플링하여이 효과를 완벽하게 상쇄 할 수 있습니다. xN 우연히한다면, 예를 들어, 다음 y 만 1 호환 가치가 있지만, x이 0이면, 다음, 즉 0 즉 3.

을 통해 4 개 호환 값은 Pr(X=x)이 될 수 있도록,가 i에 대한 (N-x+1)/sum_i(N-i+1)은 0에서 N까지입니다. 그런 다음 [0, N-x]에서 Pr(Y=y | X=x)을 균일하게 만듭니다.

이것은 P (X, Y) = P (X) = 1/(N-x + 1) * [N-x + 1]/sum_i 1-sum_i (N-i + 1), 이는 각 후보 트리플렛에 대해 균일하다고 보여진다.

sum(N-i+1 for i in range(0, N+1))은 3 음이 아닌 정수를 더하는 다른 방법의 수를 N으로 나타냅니다. 나는 이것에 대한 좋은 증거를 모른다. 누군가가 의견에 하나를 추가하면 행복 할 것이다!

import random 
from collections import Counter 

def discrete_sample(weights): 
    u = random.uniform(0, 1) 
    w_t = 0 
    for i, w in enumerate(weights): 
     w_t += w 
     if u <= w_t: 
      return i 
    return len(weights)-1 

def get_weights(N): 
    vals = [(N-i+1.0) for i in range(0, N+1)] 
    totl = sum(vals) 
    return [v/totl for v in vals] 

def draw_summing_triplet(N): 
    weights = get_weights(N) 
    x = discrete_sample(weights) 
    y = random.randint(0, N-x) 
    triplet = [x, y, N - x - y] 
    random.shuffle(triplet) 
    return tuple(triplet) 

많은 신용 내 원래의 대답에 의문을 제기하고 좋은 피드백을 제공하기위한 의견 @DSM 간다 :

다음은이 방법을 샘플링하는 솔루션입니다. 이 경우

, 우리는 다음과 같이 샘플러을 테스트 할 수 있습니다

foo = Counter(draw_summing_triplet(3) for i in range(10**6)) 
print foo 

Counter({(1, 2, 0): 100381, 
     (0, 2, 1): 100250, 
     (1, 1, 1): 100027, 
     (2, 1, 0): 100011, 
     (0, 3, 0): 100002, 
     (3, 0, 0): 99977, 
     (2, 0, 1): 99972, 
     (1, 0, 2): 99854, 
     (0, 0, 3): 99782, 
     (0, 1, 2): 99744}) 
+1

균일성에 대한 귀하의 주장에 동의하지 않습니다. x에 대한 분포는 균일하지만, 이는 (15, 0, 0)의 1/16 변화가 있다는 것을 의미합니다. 이는 샘플 공간의 1/136에 불과합니다. – DSM

+0

네가 맞다고 생각해. 'x'구성 요소 (터플에서 1, 2 또는 3 지점이 될 가능성이 높음)에 대한 메타 배포를 추가해야합니다. 누락 된 속성은 [교환 가능]입니다 (http://en.wikipedia.org/wiki/Exchangeable_random_variables). – ely

+0

나는 그것을 수정 (출력에'random.shuffle'을 수행하여 각 구성 요소가 값의 범위에서 "첫 번째 덩어리"를 얻을 수있는 기회가 같다고 생각하지만 다시 확인하고 주석을 달아주세요.) 감사합니다! – ely

0

이 나에게 정직 보인다 그것은 임의의 모듈을 사용합니다.

import random 

def foo(x): 
    a = random.randint(0,x) 
    b = random.randint(0,x-a) 
    c = x - (a +b) 

    return (a,b,c) 

for i in range(100): 
    print foo(15) 
+0

이것은 x-a == 0을 확인하기 위해 불필요한'if' 문을 추가하여 내 대답과 동일합니다. 'random.randint'는'random.randint (0, 0)'처럼 낮은 값과 높은 값을 가질 수 있습니다. – ely

+0

네, 맞습니다. 제로에 대한 수표는 아무 것도 추가하지 않습니다. – shrewmouse

+0

'random.randint'의 구현이'random.randint (0, 0)'의 경우에 비효율적이었고,'if' 비교를 수행하는 비용과 비교할 때, 그것은 가치가 있다고 생각합니다. 그러나'random.randint'는 하한값이 상한값과 같은지 확인하기에 충분히 똑똑합니다. – ely