package com.galaxy.fym.algorithm.maxsublist;
import java.math.BigDecimal;
import java.util.*;
/**
* Created by fengyiming on 2017/2/17.
*
* @author fengyiming
* 随机产生红包:金额正太分布
*
* 如果非标准正态分布X~N(μ,σ^2),那么关于X的一个一次函数 (X-μ)/σ ,就一定是服从标准正态分布N(0,1)。
* 举个具体的例子,一个量X,是非标准正态分布,期望是10,方差是5^2(即X~N(10,5^2));那么对于X的线性函数Y=(X-10)/5,Y就是服从标准正态分布的Y~N(0,1)。
*/
public class RedPacket {
private static Random random = new Random();
private static BigDecimal MIN_VALUE = new BigDecimal("0.01");
private static boolean isMin = false;
/**
* 生成红包
*
* @param amountValue 红包总金额
* @param sizeValue 红包大小
* @param maxMutValue 剩余红包限定倍数
* @param sigmaValue 标准差倍数
* @return
*/
public static List<BigDecimal> getAllHotPacket(double amountValue, double sizeValue, double maxMutValue, double sigmaValue) {
BigDecimal amount = new BigDecimal(String.valueOf(amountValue));
BigDecimal restAmount = amount;
BigDecimal size = new BigDecimal(String.valueOf(sizeValue));
BigDecimal mu = restAmount.divide(size, 2, BigDecimal.ROUND_HALF_DOWN);
BigDecimal avg = new BigDecimal(mu.toString());
BigDecimal MAX_MUT = new BigDecimal(String.valueOf(maxMutValue));
double sigma = sigmaValue <= 0 ? 1 : sigmaValue;
List<BigDecimal> hotPacketPool;
do {
hotPacketPool = new ArrayList<BigDecimal>(size.intValue());
int hotPacketSize = size.intValue() - 1;
for (int i = 0; i < hotPacketSize; i++) {
BigDecimal randomBigDecimal = getRandomHotPacketAmount(mu.doubleValue(), sigma, restAmount, size.intValue()-1);
restAmount = restAmount.subtract(randomBigDecimal);
size = size.subtract(BigDecimal.ONE);
mu = restAmount.divide(size, 2, BigDecimal.ROUND_HALF_DOWN);
hotPacketPool.add(randomBigDecimal);
}
hotPacketPool.add(restAmount);
} while (restAmount.compareTo(avg.multiply(MAX_MUT)) > 0);
Collections.shuffle(hotPacketPool);
return hotPacketPool;
}
/**
* 根据剩余红包金额均值,标准差大小,计算出随机红包的大小
*
* @param mu
* @param sigma
* @param rest 剩下的钱
* @param restSize 还剩多少红包
* @return
*/
private static BigDecimal getRandomHotPacketAmount(double mu, double sigma, BigDecimal rest, int restSize) {
if(isMin){
return MIN_VALUE;
}
BigDecimal radomNo;
BigDecimal minRest = MIN_VALUE.multiply(new BigDecimal(restSize));
do {
radomNo = getRandom(mu, mu * sigma);
}
while (rest.subtract(radomNo).subtract(minRest).compareTo(BigDecimal.ZERO) < 0);
if(rest.subtract(radomNo).subtract(minRest).compareTo(BigDecimal.ZERO) == 0){
isMin = true;
}
BigDecimal randomBigDecimal = radomNo;
randomBigDecimal = randomBigDecimal.setScale(2, BigDecimal.ROUND_HALF_DOWN);
randomBigDecimal = randomBigDecimal.compareTo(MIN_VALUE) > 0 ? randomBigDecimal : MIN_VALUE;
return randomBigDecimal;
}
/**
* 产生mu sigma的正态分布的double值
*
* @param mu
* @param sigma
* @return
*/
private static BigDecimal getRandom(double mu, double sigma) {
double randomValue = random.nextGaussian() * sigma + mu;
BigDecimal value = new BigDecimal(String.valueOf(randomValue)).abs();
return value;
}
public static void main(String[] args) {
BigDecimal all = BigDecimal.ZERO;
List<BigDecimal> allHotPacket = getAllHotPacket(10d, 10d, 3d, 1d);
int size = allHotPacket.size();
BigDecimal max = BigDecimal.ZERO;
int maxIndex = 0;
for (int i = 0; i < size; i++) {
BigDecimal amout = allHotPacket.get(i);
System.out.println("第" + (i + 1) + "随机的红包金额大小:" + amout);
if (amout.compareTo(max) > 0) {
max = amout;
maxIndex = i + 1;
}
all = all.add(amout);
}
System.out.println("所有红包金额为红包:" + all);
System.out.println("手气最佳为:第" + maxIndex + "个红包,金额为:" + max);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
第1随机的红包金额大小:0.15
第2随机的红包金额大小:1.48
第3随机的红包金额大小:0.02
第4随机的红包金额大小:2.21
第5随机的红包金额大小:1.14
所有红包金额为红包:5.00
手气最佳为:第4个红包,金额为:2.21
第1随机的红包金额大小:0.13
第2随机的红包金额大小:0.65
第3随机的红包金额大小:2.30
第4随机的红包金额大小:0.95
第5随机的红包金额大小:0.97
所有红包金额为红包:5.00
手气最佳为:第3个红包,金额为:2.30
第1随机的红包金额大小:4.74
第2随机的红包金额大小:0.88
第3随机的红包金额大小:1.07
第4随机的红包金额大小:0.20
第5随机的红包金额大小:0.43
第6随机的红包金额大小:0.41
第7随机的红包金额大小:0.22
第8随机的红包金额大小:0.20
第9随机的红包金额大小:0.65
第10随机的红包金额大小:1.20
所有红包金额为红包:10.00
手气最佳为:第1个红包,金额为:4.74
第1随机的红包金额大小:0.63
第2随机的红包金额大小:0.33
第3随机的红包金额大小:1.35
第4随机的红包金额大小:1.00
第5随机的红包金额大小:0.70
第6随机的红包金额大小:3.19
第7随机的红包金额大小:0.19
第8随机的红包金额大小:1.50
第9随机的红包金额大小:0.18
第10随机的红包金额大小:0.93
所有红包金额为红包:10.00
手气最佳为:第6个红包,金额为:3.19
第1随机的红包金额大小:1.05
第2随机的红包金额大小:0.68
第3随机的红包金额大小:0.19
第4随机的红包金额大小:1.64
第5随机的红包金额大小:1.64
第6随机的红包金额大小:0.86
第7随机的红包金额大小:0.81
第8随机的红包金额大小:1.06
第9随机的红包金额大小:0.98
第10随机的红包金额大小:1.09
所有红包金额为红包:10.00
手气最佳为:第4个红包,金额为:1.64