algorithm 取 n 個亂數,總和為 100

取n個亂數和為100的方法

水桶法

n = 需要幾個變數,scale為刻度,執行次數為100/scale

假設需取 n = 5的變數總和為100,設5個桶子則取1-5亂數,刻度為10,執行 =100/10次指定到的桶子劃記ㄧ次,

執行完則可能結果為1,1,1,4,3==>乘以scale 10==>10,10,10,40,30

缺點:

  • n太小且scale太大時可能會有沒被分到的情形,此時scale設小一點即可
public static void main(String[] args) throws InterruptedException {
	bucket(5,1);
}
public static void bucket(int n ,int scale) {
	if(100 % scale !=0) {
		System.out.println("scale無法整除100");
		return;
	}
	
	int [] bucket = new int [n];
	int t = 100/scale;
	
	for(int i = 1 ;i<=t;i++) {
		int ran = (int)(Math.random()*n);
		bucket[ran]+=1;
	}
	List<Integer> list = Arrays.asList(ArrayUtils.toObject(bucket));
	list.sort(Integer::compareTo);
	String output =list.stream().map(s->s*scale+"").collect(Collectors.joining(","));
	System.out.println(output);
}

數字加總後轉換為百分比

抽n個亂數,加總算總合後,個別亂數除以總合

public static void main(String[] args) throws InterruptedException {
	sumMethod(5);
}
public static void sumMethod(int n ) {
	int [] arr = new int [n];
	int sum =0;
	for(int i = 0 ; i<n;i++) {
		int random = (int)(Math.random()*100)+1;//1-100 ,注意有可能取到1會造成比例為零,可以加ㄧ個更大的數
		arr[i] = random;
		sum+=random;
	}
	//System.out.println("sum:"+sum);
	arr[n-1] = 100;
	for(int i =0;i<n-1;i++) {
		//System.out.println(arr[i]);
		arr[i] = arr[i]*100/sum;
		arr[n-1] -=arr[i];
	}
	List<Integer> list = Arrays.asList(ArrayUtils.toObject(arr));
	list.sort(Integer::compareTo);
	list.stream().map(s->s+"").collect(Collectors.joining(","));
	System.out.println(list);
	
}

計算數線上的距離

利用數線來取得,若要取得5個變數總合為100,只需取得4個不相等的隨機數字,排序後計算差值

ex. 15 , 30 , 66 ,82

=>15 , 15(30-15),33(66-30),16(82-66),18(100-82)

public static void main(String[] args) throws InterruptedException {
	lineMethod(5);
}
public static void lineMethod(int n) {
	n = n-1; //產生n個數只需要產生n-1個亂數即可
	List<Integer> list = new ArrayList<>();
	for(int i =1;i<=n;i++) {
		int random = (int)(Math.random()*99)+1;//generate 1-99
		//System.out.println(random);
		list.add(random);
	}
	list.add(100);
	list.sort(Integer::compareTo);
	for(int i = list.size()-1;i>0;i--) {
		list.set(i, list.get(i)-list.get(i-1));
	}
	
	list.sort(Integer::compareTo);
	System.out.println(list);
}

Reference: