주어진 사건의 모든 조합의 가능성


18

확률이 0.0에서 1.0 사이 인 일련의 이벤트가 주어지면 각 조합이 발생할 확률을 생성하고 도출하십시오. 선택한 언어가 제공하는 구성에 따라 일련의 숫자가 제공 될 수 있습니다.

다음은 예입니다. 시퀀스 조합의 길이가 메모리에 맞는 것으로 가정 할 수 있습니다.

{ 0.55, 0.67, 0.13 }

프로그램은 각 조합과 해당 서열의 발생 확률을 인쇄해야합니다. 1은 입력 시퀀스의 해당 인덱스에서 이벤트가 발생했음을 나타내고 0은 해당 이벤트가 발생하지 않았 음을 나타냅니다. 원하는 출력은 다음과 같습니다 (저는 작업의 인쇄에 신경 쓰지 않습니다. 알고리즘의 정보 제공 목적입니다).

[0,0,0] = (1 - 0.55) * (1-0.67) * (1-0.13) = 0.129195
[0,0,1] = (1 - 0.55) * (1-0.67) * (0.13)   = 0.019305
[0,1,0] = (1 - 0.55) * (0.67)   * (1-0.13) = 0.262305
[0,1,1] = (1 - 0.55) * (0.67)   * (0.13)   = 0.039195
[1,0,0] = (0.55)     * (1-0.67) * (1-0.13) = 0.157905
[1,0,1] = (0.55)     * (1-0.67) * (0.13)   = 0.023595
[1,1,0] = (0.55)     * (0.67)   * (1-0.13) = 0.320595
[1,1,1] = (0.55)     * (0.67)   * (0.13)   = 0.047905

이 문제는 "Cartesian product"계산과 관련이 있습니다.

이것은 코드 골프이므로 바이트 수가 가장 적은 코드가 이깁니다.


3
Programming Puzzles & Code Golf에 오신 것을 환영합니다.
Doorknob

겠습니까 [0.129195, 0.019305, 0.262305, ..., 0.047905]출력으로 충분 또는은 [0,0,0], [0,0,1], ...필요?
Laikoni

@Laikoni 출력이 양호합니다. 출력 부분은 문제의 고기가 아닙니다.
Mark Johnson

출력을 역순으로 할 수 있습니까?
Luis Mendo

@LuisMendo 물론입니다.
마크 존슨

답변:


8

하스켈, 86 바이트

unlines.map(\p->show(fst<$>p)++" = "++show(product$snd<$>p)).mapM(\x->[(0,1-x),(1,x)])

사용 예 :

Prelude> putStrLn $ unlines.map(\p->show(fst<$>p)++" = "++show(product$snd<$>p)).mapM(\x->[(0,1-x),(1,x)]) $ [0.55, 0.67, 0.13]
[0,0,0] = 0.12919499999999998
[0,0,1] = 1.9304999999999996e-2
[0,1,0] = 0.262305
[0,1,1] = 3.9195e-2
[1,0,0] = 0.157905
[1,0,1] = 2.3595e-2
[1,1,0] = 0.320595
[1,1,1] = 4.790500000000001e-2

대부분의 바이트는 출력 형식화에 사용됩니다. 확률 벡터에만 관심이 있다면 29 바이트에 불과합니다.

map product.mapM(\x->[1-x,x])

작동 방식 :

                    mapM(\x->[(0,1-x),(1,x)])   -- for each number x in the input
                                                -- list make either the pair (0,1-x)
                                                -- or (1,x). Build a list with
                                                -- all combinations

    map(\p->                    )               -- for each such combination p
          show(fst<$>p)                         -- print the first elements
          ++" = "++                             -- then the string " = "
          show(product$snd<$>p)                 -- then the product of the second
                                                -- elements

unlines                                         -- joins with newlines

깔끔하다. 이 작업을 수행하는 데 실제로 짧은 기능적 방법이 있는지 궁금합니다. C # 또는 F #을 알고 있습니까? Haskell 구문에 완전히 익숙하지 않기 때문에 해당 언어에서 동일한 알고리즘이 어떻게 보이는지 궁금합니다.
Mark Johnson

@ MarkJohnson : 아니요, 죄송합니다. C #도 F #도 모릅니다.
nimi

5

매스 매 티카, 46 45 바이트

(s=#;1##&@@Abs[#-s]&/@{1,0}~Tuples~Length@s)&

목록을 가져옵니다. {}출력이 있는 빈 목록에서도 작동합니다 {1}.

테스트 사례 :

%[{0.55, 0.67, 0.13}]
{0.129195, 0.019305, 0.262305, 0.039195, 0.157905, 0.023595, 0.320595, 0.047905}

설명

확률 s목록 b0"발생하지 않음"및 1" 발생 했음" 을 나타내는 비트 목록이 주어지면 곱할 확률 목록은 다음과 같이 주어집니다.

1 - b - s

서명합니다. 대신에 0"발생 했음"및 1"발생하지 않음"을 나타내면 다음과 같이 단순화됩니다.

b - s

그래서 우리는 :

                      {1,0}~Tuples~Length@s   (* Generate all possible bit combinations *)
              (#-s)&/@{1,0}~Tuples~Length@s   (* Generate probabilities to be multiplied
                                                  up to sign *)
     1##&@@Abs[#-s]&/@{1,0}~Tuples~Length@s   (* Correct sign and multiply;
                                                 1##& is short for Times *)
(s=#;1##&@@Abs[#-s]&/@{1,0}~Tuples~Length@s)& (* Assign s to first argument of function,
                                                 done separately to avoid clash
                                                 with inner function *)

4

펄, 42 40 바이트

에 +1 포함 -a

STDIN에 숫자를 적으십시오 :

perl -M5.010 combi.pl <<< "0.55 0.67 0.13"

출력

0.129195
0.019305
0.262305
0.039195
0.157905
0.023595
0.320595
0.047905

combi.pl:

#!/usr/bin/perl -a
$"=")\\*({1-,}";say eval for<({1-,}@F)>

4

MATL , 12 11 바이트

TF-|Z}&Z*!p

입력 값은 형식이있는 열 벡터입니다. [0.55; 0.67; 0.13]

온라인으로 사용해보십시오!

TF    % Push [1, 0]
-     % Subtract from implicit input (column array), with broadcast. Gives a 2-col
      % matrix where the first column is the input minus 1 and the second is the input
|     % Absolute value
Z}    % Split the matrix into its rows
&Z*   % Cartesian product of all resulting. This gives a matrix as result, with each
      % "combination" on a different row
!p    % Product of each row. Implicitly display

3

펄, 116 바이트

for(glob"{0,1}"x(@a=split/ /,<>)){@c=split//;$d=1;$d*=@c[$_]?$a[$_]:1-$a[$_]for 0..$#a;say"[".join(",",@c)."] = $d"}

읽을 수있는 :

for(glob"{0,1}"x(@a=split/ /,<>)){
    @c=split//;
    $d=1;$d*=@c[$_]?$a[$_]:1-$a[$_]for 0..$#a;
    say"[".join(",",@c)."] = $d"
}

입력 매개 변수의 수와 동일한 길이 (0과 1)의 가능한 모든 조합의 목록을 작성하고 (예를 들어 위의 예에서는 길이가 3 임) 각 확률을 계산합니다.

나를 보여주는 @Dada에 감사는 어떤 glob기능을 할 수 있는지 이해가 나는 100 % 아니에요에도 불구하고, 수행 방법 은 그 않습니다.

샘플 출력 :

[0,0,0] = 0.129195
[0,0,1] = 0.019305
[0,1,0] = 0.262305
[0,1,1] = 0.039195
[1,0,0] = 0.157905
[1,0,1] = 0.023595
[1,1,0] = 0.320595
[1,1,1] = 0.047905

1
-a대신 (@a=split/ /,<>)...
다다

3

72 화 69 바이트

stdin에서 입력을 받아서 확률의 R- 벡터를 반환합니다.

apply(abs(t(expand.grid(rep(list(1:0),length(x<-scan())))-x)),1,prod)

편집 : 하나의 불필요한 전치가 제거되고 순열 행렬은 이제 아래의 전치 버전이며 확률은 행 단위가 아닌 열 단위 곱으로 계산됩니다. 출력 예 :

[1] 0.129195 0.157905 0.262305 0.320595 0.019305 0.023595 0.039195 0.047905

확률 행렬 expand.grid은 다음에 의해 생성되는 순열 행렬로 인해 다른 순서로 진행됩니다 (이 행렬의 생성은 외부 패키지를 사용하여 골프를 칠 수 있음).

1    1    1    1
2    0    1    1
3    1    0    1
4    0    0    1
5    1    1    0
6    0    1    0
7    1    0    0
8    0    0    0

첫 번째 확률은 위의 행렬에서 첫 번째 행의 반전 된 결과에 해당하고 두 번째 행은 거꾸로 된 두 번째 행 등에 해당합니다. 출력을 형식화하면 프로그램을 더욱 명확하게 볼 수 있습니다 (164 바이트).

m=expand.grid(rep(list(1:0),length(x<-scan())))
cat(paste0("[",apply(abs(m-1),1,function(x)paste0(x,collapse=",")),"] = ",apply(abs(t(t(m)-x)),1,prod),"\n"),sep="")

대신에 다음을 생성합니다.

[0,0,0] = 0.129195
[1,0,0] = 0.157905
[0,1,0] = 0.262305
[1,1,0] = 0.320595
[0,0,1] = 0.019305
[1,0,1] = 0.023595
[0,1,1] = 0.039195
[1,1,1] = 0.047905

나는 이것에 대한 내 자신의 대답을 연구하고 있었지만 깔끔한 해결책을 찾지 못했습니다. 의 큰 사용 expand.grid! 나는이 생각하는 apply코드가없이 작동하므로, 데이터 프레임뿐만 아니라 행렬에서 작동 할 수 있습니다 t(t(...))당신에게 6 바이트를 저장 것이다.
rturnbull

@rturnbull t어떤 데이터 프레임과도 관련이 없지만 치환 행렬에서 확률 벡터를 빼는 것이 가능 하다는 점에 유의하십시오 (차원이 다름). R이 벡터화 된 작업을 처리하는 방식으로 인해 적어도 하나가 필요하지만 외부 전치를 제거하고 대신 열에 제품을 적용 할 수 있습니다. 내일 업데이트
Billywob


2

J, 14 바이트

-.([:,*/)/@,.]

용법

   f =: -.([:,*/)/@,.]
   f 0.55 0.67 0.13
0.129195 0.019305 0.262305 0.039195 0.157905 0.023595 0.320595 0.047905

설명

-.([:,*/)/@,.]  Input: array P
-.              Complement (1-x) for each x in P
             ]  Identity, get P
           ,.   Interleave to make pairs [(1-x), x]
  (     )/@     Reduce from right-to-left by
      */          Forming the multiplication table
   [:,            Flattening the result

|*//0.55 0.67 0.13-/0 1기차로 갈 수 있습니까 ?
Adám

2

Pyth, 10 바이트

*MaVLQ^U2l

온라인으로 사용해보십시오 : 데모

설명:

*MaVLQ^U2lQ   implicit Q at the end (Q = input list)
      ^U2lQ   repeated Cartesian product of [0, 1] with itself length(Q)-times
              this gives all combinations of 0s and 1s
  aVLQ        absolute difference between these 0-1-vectors with Q
*M            fold the vectors by multiplication

1

C, 110 바이트

i,k;f(float* a,int n){for(k=0;k<1<<n;++k){float p=1;for(i=0;i<n;++i)p*=k&(1<<i)?a[i]:1-a[i];printf("%f,",p);}}

언 골프 드 :

i,k;f(float* a,int n){ 
 for(k=0; k<1<<n; ++k){
  float p=1;
  for (i=0; i<n; ++i)
   p*=k&(1<<i)?a[i]:1-a[i];
  printf("%f,",p);
 }
}

최대 32 개 항목, 64 개 항목에 + 5 + 1 바이트를 사용할 수 있습니다 (선언 long k;하고 L첫 번째 루프에 추가 하여 k<1L<<N).


1
32 개가 넘는 항목의 경우 C에 "L"리터럴이 필요 *1*<<n합니까? 아니면 C ++에만 해당됩니까?
마크 존슨

@ MarkJohnson 네, 필요할 것 같습니다.
Karl Napf

1

05AB1E , 8 바이트

<Äæ¹æR+P

온라인으로 사용해보십시오!

 <Äæ¹æR+P  # Main link (Input is [.1,.2])
 ###########
 <Ä        # Invert input, take the abs value.
           # Stack is [.9,.8]
   æ¹æ     # Powerset of both inverted and original arrays.
           # Stack is [[],[.1],[.2],[.1,.2]],[[],[.9],[.8],[.9,.8]]
      R+   # Reverse original array, add arrays together.
           # Stack is [.9,.8],[.1,.8],[.2,.9],[.1,.2]
        P  # For each sub array, push product.
           # Final Result: [0.02, 0.18, 0.08, 0.72]
           # E.G.          [  11,   10,   01,   00]

1

자바 스크립트 (Firefox 30-57), 57 바이트

f=([p,...a])=>1/p?[for(q of[1-p,p])for(b of f(a))q*b]:[1]

모든 확률의 배열을 반환합니다. 이벤트 배열도 원하는 경우 86 바이트 :

f=([p,...a])=>1/p?[for(e of'01')for(b of f(a))[[+e,...b[0]],(+e?p:1-p)*b[1]]]:[[[],1]]

이벤트를 문자열로 허용하면 80 바이트입니다.

f=([p,...a])=>1/p?[for(e of'01')for(b of f(a))[e+b[0],(+e?p:1-p)*b[1]]]:[['',1]]

1/확률이 0이되지 않을 경우 각 솔루션에 대해 2 바이트를 빼십시오 .


이것을 어떻게 <script></script>블록 에서 실행 하시겠습니까? 첫 번째 "for"에 예기치 않은 문제가 발생합니까?
마크 존슨

@MarkJohnson Firefox 30 이상을 사용하는 한 작동합니다.
Neil

0

Perl 6, 24 19 바이트의 Latin-1

{[*] 1 «-»@_ «|»@_}

이전 코드 :

{[*] map {1-$^a|$^a},@_}

이것은 기능입니다. 다음과 같이 사용하십시오.

{[*] 1 «-»@_ «|»@_}(0.55, 0.67, 0.13)

얻을 :

any(any(any(0.129195, 0.019305), any(0.262305, 0.039195)), any(any(0.157905, 0.023595), any(0.320595, 0.047905)))

이전 코드에 대한 설명 :

[*]          multiply together all array elements
map          but first transform each element via
{1-$^a|$^a}  considering both 1 minus the value and the value
,@_          of the function input

최신 코드는 기본적으로 동일한 구문을 사용하여 동일합니다.

[*]          multiply together all array elements
1 «-»@_      of the array formed by subtracting the argument from 1
«|»@_        pointwise considering both that and the original array

맵은 any구성으로 가득 찬 배열을 생성하여 더 큰 any구성 으로 곱하여 루프가 없어도 문제를 깔끔하게 해결합니다.

프로그램의 가장 짧은 언어는 아니지만 문제를 직접 번역 한 것입니다.


0

Dyalog APL , 10 바이트

새로운 솔루션

인덱스 원점에 독립적. 익명의 기능. 확률 목록을 인수로 사용합니다.

∘.×/⊢,¨1-⊢

∘.×/ 데카르트 곱 감소

인수 값

각각은

1-⊢ 보수 인수 값 (1에서 인수 값을 뺀 값)

TryAPL 온라인!


오래된 솔루션

⎕IO←0많은 시스템에서 기본값이 필요합니다 . 확률 목록을 묻습니다.

|⎕∘.×.-⊂⍳2

설명

| 절대 값

입력, ɑ = [ ɑ ₁  ɑ ₂  ɑ ₃]

∘.×.-수정 된 내부 텐서에 ( ɑ ₁ – b ₁) ⊗ ( ɑ ₂ – b ₂) ⊗ ( ɑ ₃ – b ₃)을 곱한 값

⊂⍳2동봉 된 목록 b = [[0 1]]

수학적 정의

마찬가지로 B는 밀폐되어 그 스칼라이므로, 길이 연장 ɑ 전체 표현식이되도록, 즉 3= │ ( ɑ ₁ - B ) ⊗ ( ɑ ₂ - B ) ⊗ ( ɑ ₃ - B ) │ =  │ ( ɑ ₁ – [0,1]) ⊗ ( ɑ ɑ ₃-1)  ⎤ ⎤ ⎥ ⎢ ⎢ ⎣  ɑ ₁ ( ɑ ₂-1) ɑ ₃ ⎦ ⎣  ɑ ₁ ( ɑ ₁-1) ɑ



₂ – [0,1]) ⊗ ( ɑ ₃ – [0,1]) │ =

 │ [ ɑ ₁, ɑ ₁ – 1] ⊗ [ ɑ ₂ , ɑ ₂ – 1] ⊗ [ ɑ ₃, ɑ ₃ – 1] │ =

 ⎢ ⎡ ⎡   ɑɑ ɑ₃ ⎤ ⎡  ɑ ɑ ₂ ( ɑ ₂-1) ( ɑ ₃-1) ⎦  ⎥ ⎥ ⎢ ⎢ ⎡ ( ɑ ₃ ⎤ ⎡ ( ɑ ₁-1) ɑ ₂ ( ɑ ₃-1)  ⎤ ⎥ ⎥ ⎢ ⎣ ⎣ ( ɑ ₁-1) ( ɑ ₂-1) ɑ ₃⎦ ⎣ ( ɑ ₁- 1) ( ɑ ₂-1) ( ɑ ₃-1) ⎦ ⎦ ⎥



TryAPL 온라인!

참고 사항 (이전 및 새 솔루션 모두에 적용)

프로그램과 수식은 여러 변수 ( n )에 대해 작동하며 모든 차원에서 길이 2 의 n 차원 배열을 반환 합니다. 세 가지 변수를 사용하면 특정 결과
P ( p , q , r ) = A p , q , r 의 확률은 다음
과 같이 (⊃A)[p;q;r]추출 하여 배열에서 편리하게 선택할 수 있습니다p q r⌷⊃A

1 1 0⌷⊃|0.55 0.67 0.13∘.×.-⊂⍳2를 들어 P (55 %, 67 %, ¬13 %) = 1.9305 %


0

PHP, 105 97 94 93 87 바이트

for(;$i<2**$c=count($a=$argv)-$p=1;$i+=print-abs($p))for(;$c;)$p*=$a[$c--]-!($i>>$c&1);

다음과 같이 실행하십시오.

php -r 'for(;$i<2**$c=count($a=$argv)-$p=1;$i+=print-abs($p))for(;$c;)$p*=$a[$c--]-!($i>>$c&1);' -- .55 .67 .13 2>/dev/null;echo
> -0.129195-0.157905-0.262305-0.320595-0.019305-0.023595-0.039195-0.047905

출력은 리틀 엔디안입니다.

[0,0,0]
[1,0,0]
[0,1,0]
[1,1,0]
[0,0,1]
[1,0,1]
[0,1,1]
[1,1,1]

설명

for(
  ;
  $i<2**$c=                 # Iterate over possible combinations: 2^c,
    count($a=$argv)-$p=1;   #   where c is input length -p (set p to 1)
  $i+=print-abs($p)         # Increment i and print product after each
)                           #   iteration, dash separated
  for(
     ;
     $c;                    # Iterate over input ($c..0)
  )
    $p*=                    # Multiply the product by difference between:
      $a[$c--]-             # - The $c-th item of the input.
      !($i>>$c&1);          # - The $c-th bit of `$i`, negated (1 or 0)

조정

  • 이진 논리를 사용하여 문자열로 변환하는 대신 비트를 가져와 8 바이트 저장
  • 의 재설정과 $p1의 계산을 결합하여 바이트를 절약했습니다.$c
  • 인쇄 결과를 다음에 추가하여 바이트를 저장했습니다 (1). $i 를 증분 대신
  • 밑줄을 출력 구분자로 사용하여 바이트를 저장했습니다.
  • 빼기 기호로 빼기 기호를 사용하여 바이트를 저장했습니다 (음수 확률은 없음).
  • $c대신에 6 바이트를 절약했습니다.$$i

0

C ++ 17 137 131 129 바이트

선언하여 6 바이트 저장 #define A auto짧은 매크로가 무엇이든 저장하면 처음으로 절약 할 수 있습니다. #import공백 을 사용 하고 삭제하기 위한 -2 바이트<

#import<iostream>
#define A auto
A g(A r){std::cout<<r<<",";}A g(A r,A x,A...p){g(x*r,p...);g(r-x*r,p...);}A f(A...p){g(1,p...);}

가능한 모든 조합을 생성합니다.

언 골프 드 :

//base case to print the result
int g(auto r){std::cout << r << ",";}

//extract item from parameter pack
int g(auto r, auto x, auto... p) {
 g(x*r,p...);    //multiply with temp result and call with tail
 g(r-x*r,p...);  //same as above for (1-x)
}

//start of recursion, setting temp result to 1
int f(auto...p){g(1,p...);}

용법:

f(0.55, 0.67, 0.13);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.