js 배열 가중치 확률 배분 실현

9499 단어
오늘 은 js 가 페이지 의 순환 방송 을 제어 하 는 기능 을 썼 습 니 다. 만약 에 대기 열 만 사용 하면 간단 합 니 다. 그러나 모든 페이지 에 가중치 가 분배 되 는 것 이 매우 복잡 한 지 를 고려 하여 switch 와 if else 를 사용 해도 해결 할 수 없습니다. 그래서 js 배열 을 사용 하여 실현 하려 면 각 라운드 의 페이지 를 하나의 대상 으로 추상 화 하 는 것 입 니 다. 각 대상 은 수 동 으로 가중치 를 지정 해 야 합 니 다.그 다음 에 하나의 배열 을 구성 하고 아래 에 포 장 된 함 수 를 사용 하면 각 대상 의 해당 하 는 가중치 확률 에 따라 대상 을 되 돌려 줍 니 다. 코드 는 다음 과 같 습 니 다.

/**
* js          
* @param  Array  arr    js  ,    [Object,Object,Object……]
* @return  Array                ,    percent/  percent  ,    Object
* @author  shuiguang
*/
function weight_rand(arr){
  //  arr      percent  ,      
  /*
  var arr = [{
      name : '1',
      percent : 1
    }, {
      name : '2',
      percent : 2
    }, {
      name : '3',
      percent : 1
    }, {
      name : '4',
      percent : 2
    }
  ];
  */
  var total = 0;
  var i, j, percent;
  //      ,       ,         [1,2,2,3,4,4]
  var index = new Array();
  for (i = 0; i < arr.length; i++) {
    //       ,        ,        100 
    percent = 'undefined' != typeof(arr[i].percent) ? parseInt(arr[i].percent*100) : 0;
    for (j = 0; j < percent; j++) {
      index.push(i);
    }
    total += percent;
  }
  //    ,    0-5   
  var rand = Math.floor(Math.random() * total);
  return arr[index[rand]];
}

위의 방법 은 가능 하지만 이런 문제 에 부 딪 혔 다. 일반적인 복잡 한 분배 상황, 예 를 들 어 1: 1: 1 분배 (상대 치) 를 만족 시 킬 수 있 고 15%, 25%, 35% 잉여 등 정확 한 가중치 분배 (절대 치) 를 만나면 만족 시 킬 수 없다.15%: 25%: 35%: 나머지 비율 을 계산 하 는 것 이 귀 찮 기 때문에 저 는 위의 함 수 를 계속 수정 하고 백분율 모델 을 추 가 했 습 니 다. 예 를 들 어 위의 예 를 들 어 위의 명확 한 백분율 을 분배 한 후에 나머지 백분율 은 마지막 요소 에 주 고 마지막 요소 가 차지 하 는 백분율 을 계산 하지 않 아 도 되 며 각 요소 의 비율 을 계산 하지 않 아 도 됩 니 다.코드 는 다음 과 같 습 니 다:

/**
* js          ,       (  2   )      (     ,          )
* @param  Array  arr  js  ,    [Object,Object,Object……]
* @return  Array              ,    weight/  weight  ,    Object
* @author  shuiguang
*/
function weight_rand(arr){
	//  arr      weight  ,      
	//var arr=[{name:'1',weight:1.5},{name:'2',weight:2.5},{name:'3',weight:3.5}];
	//var arr=[{name:'1',weight:'15%'},{name:'2',weight:'25%'},{name:'3',weight:'35%'}];
	//              ,perMode      
	var per;
	var maxNum = 0;
	var perMode = false;
	//   Math        
	Math.gcd = function(a,b){
		var min = Math.min(a,b);
		var max = Math.max(a,b);
		var result = 1;
		if(a === 0 || b===0){
			return max;
		}
		for(var i=min; i>=1; i--){
			if(min % i === 0 && max % i === 0){
				result = i;
				break;
			}
		}
		return result;
	};
	
	//  clone             ,                
	var weight_arr = new Array();
	for (i = 0; i < arr.length; i++) {
		if('undefined' != typeof(arr[i].weight))
		{
			if(arr[i].weight.toString().indexOf('%') !== -1) {
				per = Math.floor(arr[i].weight.toString().replace('%',''));
				perMode = true;
			}else{
				per = Math.floor(arr[i].weight*100);
			}
		}else{
			per = 0;
		}
		weight_arr[i] = per;
		maxNum = Math.gcd(maxNum, per);
	}
	//     ,3:5:7,   [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2]
	//     ,        15%,25%,35%
	var index = new Array();
	var total = 0;
	var len = 0;
	if(perMode){
		for (i = 0; i < arr.length; i++) {
			//len    arr        ,                   
			len = weight_arr[i];
			for (j = 0; j < len; j++){
				//  100%  ,     
				if(total >= 100){
					break;
				}
				index.push(i);
				total++;
			}
		}
		//          100%
		while(total < 100){
			index.push(arr.length-1);
			total++;
		}
	}else{
		for (i = 0; i < arr.length; i++) {
			//len    arr        ,                   
			len = weight_arr[i]/maxNum;
			for (j = 0; j < len; j++){
				index.push(i);
			}
			total += len;
		}
	}
	//    ,   0-11   ,         
	var rand = Math.floor(Math.random()*total);
	//console.log(index);
	return arr[index[rand]];
}

var arr=[{name:'1',weight:1.5},{name:'2',weight:2.5},{name:'3',weight:3.5}];
console.log(weight_rand(arr));
var arr=[{name:'1',weight:'15%'},{name:'2',weight:'25%'},{name:'3',weight:'35%'}];
console.log(weight_rand(arr));
var prize_arr = [
	{'id':1, 'prize':'    ', 'weight':1},
	{'id':2, 'prize':'    ', 'weight':2},
	{'id':3, 'prize':'    ', 'weight':10},
	{'id':4, 'prize':'4G  ', 'weight':12},
	{'id':5, 'prize':'10Q ', 'weight':22},
	{'id':6, 'prize':'        ', 'weight':50}    
];

var times = 100000;
var prize;
var pingban = 0;
var shuma = 0;
var yinxiang = 0;
var youpan = 0;
var qb = 0;
var xc = 0;
var start = new Date().getTime();

for($i=0; $i 
 

이 코드 는 이미 최대 공약 수 를 통 해 아래 표 배열 을 최적화 시 켰 고 디지털 비 모델 을 사용 하여 최소 수치 비례 로 최적화 되 었 으 며 백분율 모델 은 성능 소 모 를 고려 하여 2 비트 소 수 를 지원 하지 않 습 니 다.
js 버 전 을 쓰 고 php 버 전 으로 쉽게 바 꾸 었 습 니 다. 10 만 번 의 순환 테스트 를 통 해 for 순환 이 foreach 보다 시간 을 절약 하 는 것 을 발 견 했 습 니 다. 인터넷 에 올 린 foreach 가 for 보다 빠 른 것 을 발 견 했 습 니 다.그러나 전체적으로 보면 js 의 집행 속 도 는 php 의 20 배 정도 이 고 php 의 집행 시간 은 약 6 초 이 며 js 의 집행 시간 은 약 0.346 초 이다.

/**
* php          ,       (  2   )      (     ,          )
* @param  array  $arr  php  ,    array(array(),array(),array()……)
* @return  array              ,    percent/  percent  ,    array()
* @author  shuiguang
*/
function weight_rand($arr)
{
  //  arr      percent  ,      
  //$arr=array(array('name'=>'1','weight'=>1.5),array('name'=>'2','weight'=>1.5),array('name'=>'3','weight'=>1.5));
  //$arr=array(array('name'=>'1','weight'=>'15%'),array('name'=>'2','weight'=>'25%'),array('name'=>'3','weight'=>'35%'));
  //              ,perMode      
  $perMode = false;
  $maxNum = 0;
  //           
  $gcd = function($a, $b)
  {
    $min = min($a, $b);
    $max = max($a, $b);
    $result = 1;
    if($a === 0 || $b === 0)
    {
      return $max;
    }
    for($i=$min; $i>=1; $i--)
    {
      if($min % $i === 0 && $max % $i === 0)
      {
        $result = $i;
        break;
      }
    }
    return $result;
  };
  //               ,                
  $weight_arr = array();
  $arr_len = count($arr);
  for($i=0; $i= 100)
        {
          break;
        }
        $index[] = $i;
        $total++;
      }
    }
    //          100%
    while($total < 100)
    {
      $index[] = $arr_len-1;
      $total++;
    }
  }else{
    for($i=0; $i'1','weight'=>1.5),array('name'=>'2','weight'=>1.5),array('name'=>'3','weight'=>1.5));
p(weight_rand($arr));
$arr=array(array('name'=>'1','weight'=>'15%'),array('name'=>'2','weight'=>'25%'),array('name'=>'3','weight'=>'35%'));
p(weight_rand($arr));

$prize_arr = array(
	'0' => array('id'=>1, 'prize'=>'    ', 'weight'=>1),
	'1' => array('id'=>2, 'prize'=>'    ', 'weight'=>5),
	'2' => array('id'=>3, 'prize'=>'    ', 'weight'=>10),
	'3' => array('id'=>4, 'prize'=>'4G  ', 'weight'=>12),
	'4' => array('id'=>5, 'prize'=>'10Q ', 'weight'=>22),
	'5' => array('id'=>6, 'prize'=>'        ', 'weight'=>50),
);

$start = time();
$result = array();
$times = 100000;
for($i=0; $i";
  if($var === false)
  {
    echo 'false';
  }else if($var === ''){
    print_r("''");
  }else{
    print_r($var);
  }
  echo "
";
}
pp 버 전 은 정수 숫자 비교 모델 만 사용 하면 숫자의 확대 와 최소 공배수 의 알고리즘 을 전혀 고려 하지 않 고 간단 한 누적 만 하면 실행 시간 을 크게 단축 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기