• 金额随机分配算法


    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Random;
    
    import javax.swing.JOptionPane;
    
    /**
     * 金额随机分配算法
     * @author kwf
     * @since 2018-2-9 11:03:59
     */
    public class Main {
        //需要设置的参数
        private static final double MIN_MONEY = 0.1; //用户获得的最小金额
        private static final double MAX_MONEY = 10; //用户获得的最大金额(可能存在误差。主要用于计算倍数,值为0则使用默认倍数)
        private static final double TOTAL_MONEY = 100;//总金额
        private static final int TOTAL_COUNT = 50;//总份数
        private static final boolean IS_UPSET = true;//结果是否需要打乱
        private static double times = 2;//倍数(用户获得的最大金额=当前平均值*倍数,当前平均值=剩余金额/剩余份数)(若最大金额不为0则会被重新赋值)
        
        private static double leftMoney = TOTAL_MONEY; //剩余金额
        private static int leftCount = TOTAL_COUNT;//剩余份数
        
        private static int runCount = 0;//运行次数
        private static int minCount = 0;//算法中获得的最小金额的个数
        private static double maxValue, minValue; //算法中获得的最大值和最小值
        
        public static void main(String[] args) {
            System.out.println("倍数为" + setTimes());
            if(!isRight(TOTAL_MONEY, TOTAL_COUNT)) { //如果设置金额和份数不合法则报错
                JOptionPane.showMessageDialog(null, "平均值为小于最小金额", "出错啦", JOptionPane.ERROR_MESSAGE);
                return;
            }
            
            List<Double> list = new ArrayList<>(); //用于存储金额列表
            double total = 0;//用于存储金额列表的总值
            int size = TOTAL_COUNT;
            for(int i = 0; i < size; size--) {
                double money = getRandomMoney();
                list.add(money);
                total += money;
                if(Double.doubleToLongBits(money) == Double.doubleToLongBits(MIN_MONEY)) minCount ++;
            }
            if(IS_UPSET) {
                System.out.println("打乱前:" + list); //打印打乱前的金额列表
                Collections.shuffle(list);//打乱列表
                System.out.println("打乱后:" + list); //打印打乱后的金额列表
            } else{
                System.out.println(list); //打印金额列表
            }
            System.out.println("数组总额为" + Math.round(total) + "=>" + (Math.round(total) == Math.round(TOTAL_MONEY) ? "合法" : "不合法"));
            System.out.println("随机算法运行了" + runCount + "次"); //打印金额列表
            
            
            maxValue = minValue = list.get(0);
            for(double value:list) {
                maxValue = value > maxValue ? value : maxValue;
                minValue = value < minValue ? value : minValue;
            }
            System.out.println("最大值为" + maxValue + ",最小值为" + minValue);
            System.out.println("最小金额的个数为" + minCount);
        }
        
        /**
         * 随机算法
         * @return 随机金额
         */
        public static double getRandomMoney() {
            runCount ++;
            if (leftCount == 1) {
                return (double) Math.round(leftMoney * 100) /100;
            }
            Random r = new Random();
            double max = leftMoney / leftCount * times;
            double money = r.nextDouble() * max;
            money = money <= MIN_MONEY ? MIN_MONEY : money;
            money = Math.floor(money * 100) / 100;
            if(isRight(leftMoney - money, leftCount - 1)) {
                leftMoney -= money;
                leftCount--;
                return money;
            } else {//如果不合法则递归调用随机算法,直到合法
                return getRandomMoney();
            }
        }
        
        /**
         * 判断金额和份数是否合法,平均值小于最小金额则视为不合法
         * @param money 金额
         * @param count 份数
         * @return 合法性
         */
        private static boolean isRight(double money, int count) {
            return money / count >= MIN_MONEY;
        }
        
        /**
         * 设置倍数(仅当设置了最大金额才有效,否则为默认倍数)
         * @return 倍数
         */
        private static double setTimes() {
            if(MAX_MONEY != 0) {
                times = MAX_MONEY / (TOTAL_MONEY / TOTAL_COUNT);
            }
            return times;
        }
    }

    10次运行结果如下

    第1次运行结果
    倍数为2.5
    打乱前:[1.54, 4.59, 3.19, 1.8, 2.67, 0.66, 0.1, 2.07, 4.05, 3.59, 4.31, 4.03, 3.27, 1.06, 0.28, 2.13, 1.08, 4.46, 2.4, 2.5, 3.39, 3.49, 0.23, 3.34, 1.06, 1.97, 3.49, 3.15, 3.26, 1.87, 2.71, 2.82, 0.99, 1.35, 0.83, 0.97, 1.68, 0.8, 1.61, 1.56, 2.05, 0.33, 0.38, 1.54, 1.71, 1.3, 0.32, 0.91, 0.8, 0.31]
    打乱后:[1.97, 0.97, 0.23, 3.39, 0.83, 3.49, 3.49, 3.19, 0.91, 4.46, 0.31, 1.8, 1.68, 1.71, 1.3, 2.82, 4.59, 0.33, 1.35, 3.34, 0.66, 1.61, 2.05, 4.05, 1.54, 2.07, 1.06, 0.32, 3.59, 3.27, 4.31, 3.26, 1.56, 1.87, 2.71, 0.38, 0.99, 0.8, 2.13, 2.4, 1.08, 4.03, 0.8, 3.15, 2.5, 1.54, 2.67, 0.1, 1.06, 0.28]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.59,最小值为0.1
    最小金额的个数为1
    
    
    第2次运行结果
    倍数为2.5
    打乱前:[3.67, 3.61, 2.48, 1.64, 1.4, 0.1, 4.03, 0.46, 2.25, 2.9, 4.03, 4.59, 2.27, 0.69, 2.14, 2.0, 4.33, 2.28, 0.3, 1.03, 2.14, 0.86, 1.29, 2.5, 0.84, 1.26, 0.71, 3.84, 3.47, 3.17, 2.94, 0.79, 0.54, 4.03, 0.16, 2.97, 3.36, 0.63, 1.49, 3.0, 1.07, 1.4, 0.75, 0.85, 2.35, 0.43, 0.1, 4.33, 1.59, 0.94]
    打乱后:[1.4, 4.03, 4.33, 0.85, 2.27, 2.97, 2.0, 1.03, 0.86, 0.16, 0.69, 2.48, 3.61, 4.03, 2.5, 2.14, 1.29, 3.0, 3.67, 4.33, 0.1, 0.71, 0.75, 3.36, 0.94, 0.1, 0.79, 0.63, 1.49, 0.84, 2.35, 0.46, 3.17, 3.47, 4.03, 2.14, 2.25, 1.64, 2.94, 1.59, 4.59, 0.43, 2.9, 0.3, 3.84, 1.07, 1.26, 0.54, 2.28, 1.4]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.59,最小值为0.1
    最小金额的个数为2
    
    
    第3次运行结果
    倍数为2.5
    打乱前:[0.85, 4.47, 0.52, 1.31, 0.39, 4.98, 4.01, 2.14, 1.21, 4.37, 0.51, 4.14, 1.53, 4.14, 0.28, 0.22, 3.46, 0.26, 3.75, 0.39, 4.67, 0.88, 4.26, 4.0, 1.83, 2.47, 2.95, 2.48, 3.5, 2.73, 1.42, 1.94, 1.43, 2.28, 0.8, 1.09, 1.04, 0.41, 3.1, 0.82, 0.1, 1.0, 3.34, 0.89, 2.77, 1.67, 1.12, 1.47, 0.31, 0.3]
    打乱后:[1.67, 0.52, 0.89, 3.34, 2.28, 0.85, 2.14, 1.42, 3.1, 1.04, 0.82, 0.51, 4.0, 2.47, 0.39, 2.95, 1.47, 4.37, 1.09, 2.73, 0.31, 4.26, 0.22, 0.8, 3.5, 0.39, 1.43, 4.14, 4.14, 3.46, 1.0, 1.12, 2.77, 4.47, 0.26, 4.67, 1.83, 0.88, 1.94, 1.53, 4.98, 0.41, 1.31, 3.75, 0.1, 4.01, 2.48, 1.21, 0.28, 0.3]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.98,最小值为0.1
    最小金额的个数为1
    
    
    第4次运行结果
    倍数为2.5
    打乱前:[1.37, 3.39, 0.87, 2.99, 3.41, 1.45, 3.86, 2.3, 0.27, 1.5, 1.58, 0.67, 2.38, 3.88, 0.14, 0.28, 1.91, 2.85, 0.25, 0.93, 3.38, 2.72, 2.8, 1.99, 5.0, 3.7, 3.25, 2.64, 1.69, 2.94, 0.54, 0.98, 0.71, 0.85, 3.71, 0.21, 3.78, 0.9, 0.1, 4.67, 0.57, 1.14, 3.87, 1.63, 0.99, 2.01, 1.36, 3.59, 0.39, 1.61]
    打乱后:[2.64, 1.69, 1.37, 2.72, 1.91, 0.98, 0.71, 0.28, 0.87, 3.88, 1.63, 2.8, 3.38, 1.36, 0.54, 2.38, 0.25, 0.57, 4.67, 0.27, 2.01, 2.3, 2.94, 3.59, 2.99, 3.78, 3.87, 5.0, 0.14, 0.67, 0.9, 3.86, 0.93, 3.39, 3.41, 0.99, 0.21, 1.99, 2.85, 0.1, 1.61, 1.45, 0.85, 1.5, 3.71, 1.58, 0.39, 1.14, 3.7, 3.25]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为5.0,最小值为0.1
    最小金额的个数为1
    
    
    第5次运行结果
    倍数为2.5
    打乱前:[3.35, 3.28, 3.99, 1.31, 0.68, 4.56, 4.28, 1.03, 3.09, 1.37, 0.88, 3.65, 3.11, 2.11, 1.23, 0.99, 4.05, 3.44, 2.11, 3.77, 2.37, 0.74, 0.82, 1.71, 0.4, 3.38, 1.8, 3.4, 0.1, 0.86, 1.15, 1.77, 0.35, 1.85, 3.53, 3.29, 3.1, 2.69, 1.94, 2.16, 0.57, 1.29, 0.8, 1.56, 1.45, 1.61, 1.77, 0.98, 0.1, 0.18]
    打乱后:[4.28, 1.37, 1.77, 2.16, 1.45, 2.11, 0.74, 1.56, 1.85, 3.44, 1.29, 0.88, 1.15, 3.65, 1.31, 0.82, 3.38, 1.71, 3.11, 1.23, 0.68, 1.77, 2.37, 0.86, 0.18, 0.1, 1.61, 3.09, 0.98, 3.77, 3.4, 1.94, 3.99, 1.03, 0.99, 0.8, 0.1, 3.53, 2.69, 2.11, 0.35, 3.35, 3.1, 3.29, 0.57, 4.05, 0.4, 4.56, 1.8, 3.28]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.56,最小值为0.1
    最小金额的个数为2
    
    
    第6次运行结果
    倍数为2.5
    打乱前:[2.1, 4.6, 3.04, 3.49, 0.1, 1.77, 3.29, 2.83, 4.3, 2.76, 3.86, 2.22, 1.83, 2.33, 1.87, 2.04, 3.81, 1.57, 2.01, 0.1, 3.76, 0.68, 0.66, 1.94, 0.12, 3.32, 1.05, 0.1, 1.01, 2.36, 1.46, 4.05, 0.93, 1.14, 4.02, 1.74, 1.77, 2.12, 2.6, 0.1, 0.81, 2.46, 1.62, 0.1, 0.44, 0.11, 1.1, 3.72, 2.21, 2.58]
    打乱后:[0.12, 3.86, 1.62, 4.05, 3.32, 0.93, 1.74, 0.1, 3.04, 1.57, 2.12, 1.01, 2.83, 2.46, 0.66, 4.6, 3.29, 4.3, 2.22, 1.05, 2.21, 2.1, 1.77, 1.94, 2.01, 0.81, 3.76, 1.77, 0.1, 4.02, 0.1, 2.36, 2.04, 2.6, 1.46, 1.87, 2.33, 0.1, 3.49, 2.58, 3.72, 2.76, 0.44, 0.1, 3.81, 1.1, 0.68, 1.14, 1.83, 0.11]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.6,最小值为0.1
    最小金额的个数为5
    
    
    第7次运行结果
    倍数为2.5
    打乱前:[2.45, 4.0, 0.15, 2.04, 4.42, 4.79, 0.45, 2.97, 4.6, 1.09, 0.31, 4.31, 0.54, 1.95, 4.37, 2.18, 3.59, 2.2, 3.28, 2.35, 3.0, 1.78, 2.0, 0.29, 2.41, 1.34, 3.69, 0.25, 3.68, 2.5, 2.17, 3.15, 2.94, 1.71, 1.67, 1.23, 1.91, 0.63, 0.77, 2.43, 2.06, 1.36, 1.12, 0.83, 0.14, 1.4, 0.25, 0.37, 0.69, 0.19]
    打乱后:[2.2, 0.29, 3.15, 1.91, 0.63, 4.42, 4.31, 0.69, 2.41, 3.0, 2.35, 1.23, 1.4, 0.37, 2.17, 0.25, 2.0, 2.5, 4.6, 2.06, 1.67, 1.95, 0.77, 1.09, 1.78, 3.69, 3.59, 3.68, 4.79, 0.19, 0.31, 0.15, 2.04, 1.12, 1.34, 4.37, 0.54, 2.43, 2.97, 4.0, 3.28, 1.71, 2.45, 0.45, 0.83, 0.14, 2.18, 1.36, 2.94, 0.25]
    数组总额为100=>合法
    随机算法运行了51次
    最大值为4.79,最小值为0.14
    最小金额的个数为0
    
    
    第8次运行结果
    倍数为2.5
    打乱前:[2.52, 2.46, 3.39, 3.8, 1.32, 1.15, 0.26, 2.77, 3.88, 0.73, 4.16, 3.47, 4.14, 4.32, 2.98, 3.61, 1.81, 0.37, 0.67, 3.96, 1.42, 2.84, 1.02, 1.59, 2.64, 3.31, 1.68, 2.18, 1.28, 0.68, 3.1, 1.35, 0.8, 1.72, 1.01, 0.27, 2.61, 1.69, 1.0, 2.79, 0.58, 0.18, 0.92, 0.45, 0.26, 0.81, 0.16, 0.32, 6.73, 2.84]
    打乱后:[1.28, 2.84, 0.92, 0.16, 0.37, 0.45, 3.1, 4.32, 2.84, 6.73, 0.58, 2.77, 0.8, 2.61, 4.14, 0.27, 1.0, 0.18, 1.69, 2.98, 3.39, 1.01, 3.47, 0.32, 1.42, 3.88, 1.72, 3.31, 0.67, 2.52, 4.16, 2.18, 2.64, 1.59, 3.61, 0.26, 0.68, 0.73, 1.02, 1.32, 1.35, 3.96, 1.15, 0.26, 2.46, 0.81, 1.68, 2.79, 3.8, 1.81]
    数组总额为100=>合法
    随机算法运行了51次
    最大值为6.73,最小值为0.16
    最小金额的个数为0
    
    
    第9次运行结果
    倍数为2.5
    打乱前:[0.62, 4.47, 0.95, 3.23, 1.56, 3.99, 2.17, 4.82, 4.07, 1.69, 1.66, 1.24, 2.56, 2.63, 3.87, 1.93, 0.11, 3.33, 2.35, 2.47, 2.68, 3.61, 2.19, 3.59, 1.27, 0.18, 1.81, 0.82, 2.94, 2.95, 0.77, 2.35, 2.59, 1.41, 1.01, 2.0, 2.51, 0.29, 0.24, 2.69, 1.95, 1.98, 1.12, 0.68, 0.75, 1.72, 1.11, 1.06, 1.82, 0.19]
    打乱后:[1.69, 2.69, 3.33, 1.24, 1.66, 1.95, 1.98, 0.95, 1.12, 2.35, 4.82, 3.87, 1.72, 1.27, 3.99, 3.23, 3.59, 4.07, 2.95, 2.17, 0.24, 4.47, 0.75, 3.61, 1.56, 1.11, 0.18, 1.93, 2.56, 1.82, 0.77, 1.81, 0.19, 2.47, 0.29, 1.01, 2.19, 0.68, 2.94, 1.06, 0.11, 2.59, 1.41, 2.68, 0.82, 0.62, 2.63, 2.0, 2.35, 2.51]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.82,最小值为0.11
    最小金额的个数为0
    
    
    第10次运行结果
    倍数为2.5
    打乱前:[3.07, 4.15, 4.28, 2.07, 1.97, 2.1, 0.47, 4.07, 1.13, 0.1, 0.89, 3.54, 3.35, 4.09, 0.92, 0.93, 2.03, 3.87, 0.1, 2.7, 0.1, 0.4, 2.14, 0.76, 3.33, 4.07, 2.64, 1.41, 0.13, 2.01, 3.26, 2.95, 0.88, 2.7, 0.72, 2.18, 0.88, 4.52, 3.09, 0.1, 2.63, 3.05, 3.13, 2.25, 0.78, 0.29, 1.67, 1.48, 0.13, 0.49]
    打乱后:[0.1, 2.7, 0.49, 3.09, 2.18, 2.1, 0.29, 2.95, 3.87, 4.09, 0.78, 0.13, 3.54, 3.07, 0.4, 2.25, 3.05, 4.07, 0.47, 4.52, 0.13, 0.1, 1.67, 1.13, 0.76, 2.01, 2.03, 3.26, 4.07, 1.48, 0.1, 0.88, 0.89, 0.88, 1.97, 2.64, 3.33, 3.13, 0.72, 1.41, 0.93, 4.15, 0.1, 2.07, 2.63, 4.28, 3.35, 2.14, 2.7, 0.92]
    数组总额为100=>合法
    随机算法运行了50次
    最大值为4.52,最小值为0.1
    最小金额的个数为4
  • 相关阅读:
    nyoj--325--zb的生日(简单dp)
    nyoj--124--中位数(水题)
    nyoj--90--整数划分(母函数)
    nyoj--18--The Triangle(dp水题)
    CodeForces ---596B--Wilbur and Array(贪心模拟)
    nyoj--1023--还是回文(动态规划)
    poj--3984--迷宫问题(bfs+路径记录)
    Netty(4)Stream by codec(粘包与拆包)
    Netty(1-1)Discard
    Netty:option和childOption参数设置说明
  • 原文地址:https://www.cnblogs.com/kangweifeng/p/8432774.html
Copyright © 2020-2023  润新知