文档库 最新最全的文档下载
当前位置:文档库 › 数值拆分算法

数值拆分算法

数值拆分算法

描述:
按指定策略把总数为t的整数拆分为q份,
可以指定多个数值的分配个数,
可以指定最小值,
各个值出现的位置随机, 剩下的值随机分配,
如果没有指定分配策略, 值完全随机分配.

使用场景: 可用于红包拆分


源码: BonusSpliter.java

package bonus;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Random;

/**
* 数值拆分
*
* @author xulinjian
*
*/
public class BonusSpliter {

/**
* 数值拆分
* 总额为t的数值分为q分
* 按strategies和min指定的分配策略进行拆分
* strategies中可以指定某个数值分配的数量
* min指定每个数值的最小值
* 分配策略优先级:
* 先按strategies分配, 如果总额不够, 剩余的分配为0
* 再按min分配, 如果总额不够, 剩余的分配为0
* strategies可不设置
* min可为0
*
* @param t //总值
* @param q //包数量
* @param min //最小值
* @param strategies 分配策略, 结构: 数值:数量 数量0表示忽略
*/
public static Integer[] split(int t, int q, int min, LinkedHashMap strategies) {

//拆分结果数组
Integer[] r = new Integer[q];

//产生随机包索引
HashMap> indexsetmap = new HashMap>();
if (strategies != null) {
for (Integer k : strategies.keySet()) {
Random randomindex = new Random();
HashSet indexset = new HashSet();
Integer val = k;
Integer valn = strategies.get(k);
while (indexset.size() < valn) {
int index = randomindex.nextInt() % q;
if (index < 0) {
index = -index;
}

//排除已经存在的索引
boolean iscontinue = false;
for (Integer mk : indexsetmap.keySet()) {
HashSet map = indexsetmap.get(mk);
if (map != null && map.contains(index)) {
iscontinue = true;
}
}
if (iscontinue) {
continue;
}
//

indexset.add(index);
}

//for (Integer e : indexset) {
// System.out.println(k+":idx:"+e);
//}

//分配包金额
for (Integer e : indexset) {
if (t > 0) {
if (t<=val) {
r[e] = t;
t = 0;
} else {
r[e] = val;
t -= val;
}
} else {
r[e] = 0;
}
}

indexsetmap.put(k, indexset);
}
}

//初始化随机包金额
if (min < 0) {
min = 0;
}
for (int i=0; i//排除已经存在的索引
boolean iscontinue = false;
for (Integer mk : indexsetmap.keySet()) {
HashSet map = indexsetmap.get(mk);
if (map != null && map.contains(i)) {
iscontinue = true;
}
}
if (iscontinue) {
continue;
}
//

if (t > 0) {
if (t<=min) {
r

[i] = t;
t = 0;
} else {
r[i] = min;
t -= min;
}
} else {
r[i] = 0;
}
}

int randscope = t/q;
if (randscope == 0) {
randscope = 10;
}

//除去指定包随机累加1~randscope
Random random = new Random();
while (t>0) {
for (int i=0; i//排除已经存在的索引
boolean iscontinue = false;
for (Integer mk : indexsetmap.keySet()) {
HashSet map = indexsetmap.get(mk);
if (map != null && map.contains(i)) {
iscontinue = true;
}
}
if (iscontinue) {
continue;
}
//

int rand = 1+random.nextInt() % randscope;
if (rand < 0) {
rand = -rand;
}
if (t < rand) {
rand = t;
}
r[i] += rand;
t -= rand;
if (t<=0) {
break;
}
}
}

return r;

}

/**
* 测试
* @param args
*/
public static void main(String[] args) {

long s1 = System.currentTimeMillis();

int t = 500000; //总金额
int q = 500; //分包数量
int min = 100; //最小值

//int t = 50000; //总金额
//int q = 200; //分包数量
//int min = 100; //最小值
/*
* 分配策略
* 结构: 数值:数量
*/
LinkedHashMap strategies = new LinkedHashMap();
/*
strategies.put(16800, 1);
strategies.put(1680, 10);
strategies.put(997, 20);
strategies.put(888, 30);
strategies.put(666, 40);
*/
/*
strategies.put(33300, 1);
strategies.put(3333, 9);
strategies.put(2016, 20);
strategies.put(1680, 30);
strategies.put(997, 40);
*/
strategies.put(99700, 1);
strategies.put(16800, 3);
strategies.put(8888, 6);
strategies.put(6666, 20);
strategies.put(997, 30);
strategies.put(888, 40);

Integer[] r = split(t, q, min, strategies);
//Integer[] r = split(t, q, -1, null);

long s2 = System.currentTimeMillis();

System.out.println("分包耗时(ms):"+(s2-s1));

//打印结果
for (int i=0; iSystem.out.println(r[i]);
}
}

}

相关文档
相关文档 最新文档