랜덤 균등 분배 알고 리즘 아시는분 있나요?? > 자유게시판

자유게시판

랜덤 균등 분배 알고 리즘 아시는분 있나요?? 정보

랜덤 균등 분배 알고 리즘 아시는분 있나요??

본문

만약 100이라는 숫자가 있다면 

 

20개의 필드에 

 

각각 숫자가 랜덤하게 들어가는데 

 

나중에 총합은 100이 나와야 합니다. 

 

자바스크립트나 PHP. 혹은 이론만 말씀해 주셔도 됩니다. 

 

아....수학 공부 해야 되는데.

추천
0

댓글 11개

일단, 친숙한 규식씨 말고, 방정식씨를 한 번 써보시는 게... 차원이 좀 높아지는 건 함정이긴 한데, 생각을 방정식으로 기술한다 생각하시면 됩니다. 그걸 나중에 언어로써 옮겨놓으면 프로그래밍 거의 다 한 겁니다.
숫자 (a) = 100
필드 (b) = 20
a / b = c
각 필드에 c 대입
a % b = d
d 가 0 이상이라면 20개의 필드중 아무곳에나 넣기
<?

$range = 20;

for($i = 1; $i <= $range; $i++) {

$total = array_sum($num); //배열총합
$min= $range- $i; // 1이 들어갈때의 최소값

$num[] = rand(1, 100 - $total - $min);

}

print_r($num);
echo "배열총합 : ". array_sum($num);

?>

Array ( [0] => 32 [1] => 49 [2] => 2 [3] => 1 [4] => 1 [5] => 1 [6] => 1 [7] => 1 [8] => 1 [9] => 1 [10] => 1 [11] => 1 [12] => 1 [13] => 1 [14] => 1 [15] => 1 [16] => 1 [17] => 1 [18] => 1 [19] => 1 )
배열총합 : 100

근데 이형태의 코드는 문제가 범위에 비해서 최대값이 작으면 하나의 셀에서 큰값이 랜덤으로 나와버리면 나머지는 꽤 많은 셀에서
1이 분배되는 현상이 생기네요

이걸 원하시는건진 모르겠는데 그냥 대충 짜봤습니다.

원리는 소스보시면 이해되실듯 합니다.

하나의 셀마다 순차로 loop하되
 조건을 부여해서 남은 셀수에 최소한의 값이 1이 들어갈수 있는 범위 내에서 셀마다
랜덤의 범위를 지정하는겁니다.

이론은 맞는거 같은데 결과도 나오긴 하는데 1이 너무 많이 나오네요.
100% 은 아니지만,
원하시는 영역이 없다면  rand(4,8)) 을 mt_rand(0,100) 로 바꿔 보세요.

$field = array_fill(0, 20, 0);
for ($i=0;$i<=19; $i++) {
$field[$i] = mt_rand(4,rand(4,8));  <---  이부분을 원하시는 영역으로 조절
if( array_sum($field) > 100 ) {
$field[$i] = 0;
$field[$i] = 100-array_sum($field);
break; 
}
if($i==19 && array_sum($field)<100) $field[$i] += 100-array_sum($field); 
}


Array
(
    [0] => 4
    [1] => 5
    [2] => 5
    [3] => 8
    [4] => 4
    [5] => 5
    [6] => 4
    [7] => 4
    [8] => 7
    [9] => 6
    [10] => 4
    [11] => 4
    [12] => 4
    [13] => 5
    [14] => 7
    [15] => 4
    [16] => 4
    [17] => 6
    [18] => 5
    [19] => 5
)
100
이런 고급진 방법이 있군요~
저는 아마도 배열 탐색을 하지 않았을까... ㅡㅡ;; 머리 쓰는 건 정말 자신이 없어요.
골고루 하는 방법이 100% 은 아니지만, 좀더 가공한 재귀호출입니다...
위의 소스보다는 낳지만, 100% 가 아니니....일하러....후다다닥
전문 알고리즘 구현하시는분이 보시면 저 두들겨 맞은껄 알지만...

function func_radom($cnt) {
$vmin = 4;
$vmax = 6;
$field = array_fill(0, 20, 0);
for ($i=0;$i<=19; $i++) {
$field[$i] = mt_rand($vmin,rand($vmin+1,$vmax));
if( array_sum($field) > 100 ) {
$field[$i] = 0;
$field[$i] = 100-array_sum($field);
break; 
}
}

if($i==20) {
if( array_sum($field)<100 ) $field[19] += 100-array_sum($field);
if( $field[19]>$vmax || $field[19]<$vmin ) {
if($cnt < 30) {          <-----  30 회 제한을 준것 .... 가끔 사용하시는거라면 숫자 더 주세요
$cnt++;
return func_radom($cnt);
}
}
}

return $field;
}

$data = func_radom(0);

Array
(
    [0] => 5
    [1] => 6
    [2] => 4
    [3] => 5
    [4] => 4
    [5] => 6
    [6] => 6
    [7] => 4
    [8] => 5
    [9] => 6
    [10] => 6
    [11] => 4
    [12] => 4
    [13] => 5
    [14] => 4
    [15] => 4
    [16] => 5
    [17] => 5
    [18] => 6
    [19] => 6
)
100
음 알고리즘 이라는 부분이 나오는 결과값에 대해서 조건별로 범위 제한을 해서 되는 부분인가 싶으네요

가령 이를테면 균등 분배라고 해서 평균적으로 5가 나와야 하기 때문에 min과 max를 4 6으로 지정한다면

이미 각 필드에 각각의 숫자가 랜덤하게 들어가야 한다는 조건에서 어느정도 벗어나있지 않나 싶습니다.

최대한 랜덤하게 부여하면서 고르게 분포를 시키고자 한다면 확률에 의존하는수 밖에 없지 않나 싶습니다.

최대와 최소를 부여해서 편차를 낮춘다면 100이라는 숫자와 20개의 셀이라는값이 유동적으로 변할때

적용할 수 있는 부분에 한계가 생기게 됩니다.

<?
$loop = 100;
$range = 20;

for($i=0; $i < 100; $i++){

$key = mt_rand(1,$range);
$num[$key]++;

}

print_r($num);
?>

이렇게 간단히 처리하는 방법도 있습니다만 개별로 아무래도 범위가 커지면
rand냐 mt_rand냐의 특성도 많이 타게되는 경향도 있습니다.
전체 195,062 |RSS
자유게시판 내용 검색

회원로그인

진행중 포인트경매

  1. 참여1 회 시작24.03.28 11:15 종료24.04.04 11:15
(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT