자바 보너스 쟁탈 알고리즘 실현(공정 판 과 수 속 판)

우리 가 단체 에서 보 너 스 를 뺏 을 때 정말 손 속도 가 빨 라 질 수록 보 너 스 는 금액 이 큽 니까?
답 은 당연히 그렇지 않 습 니 다.모두 운 을 겨 루 는 것 이 라 고 말 했 는데 어찌 손 을 빨리 겨 룰 수 있 겠 습 니까?
하지만 손 을 맞 추 는 방법 도 있 습 니 다.
뇌물 을 빼앗다
  • 2 배 평균치 법(공정 판)
  • 선분 절단 법(수 속 판)
  • 2 배 평균치 법(공정 판)
    이것 은 매우 합 리 적 이 고 공평 한 보 너 스 를 빼 앗 는 알고리즘 이다.절대로 너 로 하여 금 속 도 를 내 게 하지 않 을 것 이 니 순진 하지 마라.
    여기 서 우 리 는 가정 한다.
    보너스 남 은 금액 은 M
    보너스 남 은 수량 은 N
    이런 알고리즘 은 매번 구간[0,M/N 에 있다.×2]무 작위 로 숫자 를 뽑는다
    100 위안 의 보 너 스 를 10 명 에 게 준다 고 가정 하면 합 리 적 인 방법 은 한 사람 이 10 위안 을 받 을 확률 이 같 아야 한다.
    1 인 무 작위 금액 의 범 위 는[0,100/10 이다.×2],즉[0,20]으로 평균 10 원 을 받 을 수 있 는데 이때 남 은 금액 은 100-10=90 이다.
    두 번 째 사람의 무 작위 금액 범 위 는[0,90/9 이다.×2],즉[0,20]입 니 다.이렇게 하면 평균 10 위안 을 받 을 수 있 습 니 다.이때 나머지 금액 은 90-10=80 입 니 다.
    세 번 째 사람의 무 작위 금액 범 위 는[0,80/8 이다.×2],즉[0,20]입 니 다.이렇게 하면 평균 10 원 을 받 을 수 있 습 니 다.
    이렇게 유도 해 나 가면 모든 사람 이 같은 금액 을 받 을 확률 은 같 을 것 이다.
    코드:
    
    public static List<Double> doubleMeanMethod(double money,int number){
     List<Double> result = new ArrayList<Double>();
     if(money<0&&number<1)
     return null;
     double amount,sum=0;
     int remainingNumber=number;
     int i=1;
     while(remainingNumber>1){
     amount= nextDouble(0.01,2*(money/remainingNumber));
     sum+=amount;
     System.out.println(" "+i+"          :"+format(amount));
     money -= amount;
     remainingNumber--;
     result.add(amount);
     i++;
     }
     result.add(money);
     System.out.println(" "+i+"          :"+format(money));
     sum+=money;
     System.out.println("           :"+format(sum));
     
     return result;
     
     
     }
    실행 결과:

    선분 절단 법(수 속 판)
    이것 이 바로 손 을 맞 추 는 속도 이 니 손 속 도 를 보 여줄 때 가 되 었 다.
    이 알고리즘 은 총 금액 을 하나의 라인 으로 상상 할 수 있 고 모든 사람 이 칼 을 자 를 기회 가 있 으 며 앞 사람 이 자 른 뒤에 있 는 사람 이 이어서 자 르 면 앞 사람 이 자 른 길이(받 은 보너스 금액 으로 이해)일수 록 확률 이 높다.
    코드:
    
    public static void lineSegmentCutting(double money,int number){
     if(money<0&&number<1)
     System.out.println("    !");
     double begin=0,end=money;
     double y=0;
     for(int i=0;i<number-1;i++){
     double nn=0;
     double amount=nextDouble(begin,end);
     
     nn=amount-begin;
     System.out.println(" "+(i+1)+"          :"+format(nn));
     y+=nn;
     begin=amount;
     
     }
     System.out.println(" "+number+"          :"+format(end-begin));
     y+=(end-begin);
     System.out.println("           :"+format(y));
     
    }
    실행 결과:

    전체 코드:
    
    package com.zhl.blogTest;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.Scanner;
    
    public class redEnvelope {
     
     /*Random          [min , max]   
     randNumber         MIN   MAX        
     int randNumber =rand.nextInt(MAX - MIN + 1) + MIN; */
     
     
    
     /**
     *   min max      
     **/
     public static double nextDouble(final double min, final double max) {
     return min + ((max - min) * new Random().nextDouble());
     }
     
     public static String format(double value) {
     
     return new java.text.DecimalFormat("0.00").format(value); //       
     }
     
    
     //     
     public static List<Double> doubleMeanMethod(double money,int number){
     List<Double> result = new ArrayList<Double>();
     if(money<0&&number<1)
     return null;
     double amount,sum=0;
     int remainingNumber=number;
     int i=1;
     while(remainingNumber>1){
     amount= nextDouble(0.01,2*(money/remainingNumber));
     sum+=amount;
     System.out.println(" "+i+"          :"+format(amount));
     money -= amount;
     remainingNumber--;
     result.add(amount);
     i++;
     }
     result.add(money);
     System.out.println(" "+i+"          :"+format(money));
     sum+=money;
     System.out.println("           :"+format(sum));
     
     return result;
     
     
     }
     
     //     
     public static void lineSegmentCutting(double money,int number){
     if(money<0&&number<1)
     System.out.println("    !");
     double begin=0,end=money;
     double y=0;
     for(int i=0;i<number-1;i++){
     double nn=0;
     double amount=nextDouble(begin,end);
     
     nn=amount-begin;
     System.out.println(" "+(i+1)+"          :"+format(nn));
     y+=nn;
     begin=amount;
     
     }
     System.out.println(" "+number+"          :"+format(end-begin));
     y+=(end-begin);
     System.out.println("           :"+format(y));
     
     }
     
     public static void main(String[] args) {
     Scanner sc = new Scanner(System.in);
     System.out.println("            。");
     
     int number;
     double money;
     System.out.print("        :");
     money = sc.nextDouble();
     System.out.print("       :");
     number = sc.nextInt();
     //System.out.println(money + " " + number);
     
     //     
     doubleMeanMethod(money,number);
     //System.out.println(doubleMeanMethod(money,number).toString());
     //        list ,      ,         ,  list               
     System.out.println();
     
     //     
     lineSegmentCutting(money,number);
     
    
     }
    
    }
    여기까지 읽 었 으 니 너 는 정말 귀 요 미 구나.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기