营销奖励金额算法

        业务场景是用户买充值卡,如果买100元充值卡,就给账户充100加上奖励的金额,要求平均给用户充值本金+本金*3%的金额,最少给用户充本金+本金*1%,最多给用户充本金+本金*50%,如何去保证必须有一部分用户充到最大值并且有平均值在3%上下浮动呢?

        提供两个方法,以本金100元举例;

        一.创建一个队列,随机一千个数放入队列里,这一千个数的平均值是3元,最小值是1元,最大值是50,一个用户买产品的时候就从这个队列里面拿一个,如果大于一千人买就在取一遍队列里的值。

        二.两次随机数,第一次随机落到大奖金区间里面还是落到小奖金区间里面,概率是可以配置的,为了保证均值在3元上下浮动,小奖金区间是(最小值,2*平均值-最小值),最大值的区间是(最小值-最大值)。具体代码如下。


public class RandomUtils {
    private static Random random = new Random();
    private static final Logger logger = LoggerFactory.getLogger(RandomUtils.class);

   /**
    * 给定范围
    * 生成随机金额
    */
   public static Integer randomInt( int left , int right , int avg ){
      
      if( left - right > 0 ){
         
         throw new IllegalArgumentException("最小金额不应大于最大金额");
      }
      
      if( left == right ){
         
         return left ;
      }
      
      if( avg < left ) {
         
         return avg;
      }
      
      if( avg > right ){
         return  randomIntByDifference(left, avg);
      }
      
      int winProbability =5;// Integer.parseInt( JXJConfigInit.getMerchantConfig( Constants.SWELL_PROBABILITY ) + "" );
      int winRate =1000;// Integer.parseInt( JXJConfigInit.getMerchantConfig( Constants.SWELL_RATE ) + "" );
      logger.info( "RandomUtils.randomInt winProbability:{} winRate:{}", winProbability, winRate );
      int bonus = 0;
      if( winProbability > randomInt(0, winRate) ){
         /**
          * 
          * 大奖金
          */
         
         bonus = randomIntByDifference(left, right );
         if( ( bonus + left ) > right ){
            
            bonus = left ;
         }
         logger.info( "RandomUtils.randomInt largeAmount bonus:{}", bonus );

      }else{
         
         /**
          * 小奖金
          */
         
         bonus = randomIntByDifference(left, (avg * 2 - left));
         if( ( bonus + left ) > right ){

            bonus = left ;
         }

         logger.info( "RandomUtils.randomInt smallAmount bonus:{}", bonus );

      }
      
      if( bonus > right ){
         
         /**
          * 
          * 不允许超过最大金额
          */
         
         bonus = right;
      }
      return bonus;
   }
   
   public static Integer randomIntByDifference( int left , int right ){
      
      logger.info( "RandomUtils.randomIntByDifference left:{} right:{}", left, right );
      if( left - right > 0 ){
         
         throw new IllegalArgumentException("最小金额不应大于最大金额");
      }
      
      if( left == right ){
         
         return left ;
      }
      
      int dif = right - left + 1 ;
      Random rand = new Random();
      int bonus = rand.nextInt( dif ) + left;
      return bonus;
      
//    
//    int digit = right - left;
//    String digitStr = digit + "";
//    int digitLength = digitStr.length();
//    StringBuffer sb = new StringBuffer();
//    char [] ca = digitStr.toCharArray();
//    for (int i = 0; i < digitLength; i++) {
//       
//       char c = ca[ i ];
//       if( '0' == c  ){
//          
//          /**
//           * 
//           * 所有0置换为9
//           */
//          sb.append( randomInt( 0, 9 ) );
//          
//       }else{
//          
//          sb.append( randomInt( 0, Integer.parseInt( String.valueOf( c ) ) ) );
//          
//       }
//    }
//    
//    logger.info( "RandomUtils.randomIntByDifference randomNo:{}", sb.toString() );
//    return Integer.parseInt( sb.toString() );
   }
   private static Random r = new Random();
   public static Integer randomInt( int left , int right ){
      
      logger.info( "RandomUtils.randomInt left:{} right:{}", left, right );

      if( left - right > 0 ){
         
         throw new IllegalArgumentException("最小金额不应大于最大金额");
      }
      
      if( left == right ){
         
         return left ;
      }
      
      int seqs = right - left;
      int [] indexs = new int[ seqs + 1 ];
      
      for (int i = 0; i < indexs.length; i++) {
         
         indexs [ i ] = left++;  
         
      }
      
      int index = r.nextInt( seqs + 1 );
      logger.info( "RandomUtils.randomInt indexs [ index ]:{}", indexs [ index ] );
      return indexs [ index ] ; 
   }
   
   
   
   public static void main(String[] args) {
      
      int countmax=0,countmin=0,count=0 ,summax=0,summin=0;
      for (int i = 0; i < 10000; i++) {
         int r = randomInt(10, 500,50);
         if( r > 90 ){
            
            countmax+=r;
            summax++;
         }else{
            
            countmin+=r;
            summin++;
         }
         count+=r;

         
      }
      System.out.println((count)/10000);
      System.out.println(countmax/summax);
      System.out.println(countmin/summin);
      System.out.println((summax * 1.0d)/10000d);
      System.out.println(countmax/(count*1.0d));
   }
   

    /**
     * 示例:String reqNo = buildReqNo("CUC");
     * String reqNo = buildReqNo("JDP");
     * 
     */
    public static String buildReqNo(String requestModule)
    {
        if(requestModule != null && requestModule.length() == 3){
            StringBuffer sb = new StringBuffer();
            sb.append(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
            sb.append(requestModule.toUpperCase());
            sb.append(getRegularRandomStr());
            return sb.toString();
        }else{
            throw new RuntimeException("Invalid requestModule");
        }
    }
    
    private static String getRegularRandomStr()
    {
        return lpad(5, (random.nextInt(100000)));
    }
    
    /**
     * 左补函数
     * 
     * @param length 长度
     * @param number 数字
     * @return
     */
    private static String lpad(int length, int number)
    {
        String f = "%0" + length + "d";
        return String.format(f, number);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抽奖之星是一款简单好用的随机抽奖软件。软件可用于各种活动和晚会、年会抽奖,支持文字抽奖、图片抽奖等多种模式,还内置作弊内定、黑白名单、名单分组等诸多功能。软件界面美观简洁、使用方便,速度快,质量高,对于用户来说是一款很不错的软件,小编这里推荐大家使用这款软件! 抽奖之星基本简介 抽奖模式:含文字抽奖、照片抽奖两种模式。 重复中奖:采用禁止重复中奖算法,自动滤除已经中奖的参选者。 随机抽取:随机滚动显示参选者(姓名、号码、照片等)。 按键方便:按回车开始滚动,按空格停止滚动,按Tab键播放颁奖音乐。 名单导入:导入文本文件,或导入图片文件夹,最多可导入高达2万条。 抽奖结果:自动保存抽奖结果,不惧死机断电,支持缺席等的作废处理。 灵活易用:无需预先固定中奖数量,手动切换当前奖项,设置每次抽取个数(1-50)。 背景音乐:支持滚动音乐、中奖音乐、颁奖音乐,并附带了相关音乐资源。 辅助工具:附带了图片批量缩小、号码座位号批量生成、强大的纯文本编辑、多列表格数据导入导出、格式转换等免费工具。 抽奖之星的安装 把下载好的安装包解压到当前文件夹,之后双击【cjzx.exe】运行文件进行安装,打开的时候会出现安装框,依次开始安装,依照步骤点击下一步,并选择同意协议和软件安装位置即可。 抽奖之星的使用   安装完成后,点击【抽奖之星】快捷方式即可进入抽奖之星软件。如图所示,这是软件的主界面。     如图所示,这是软件的界面布局介绍。用户可以点击界面的各种按钮实现自己所需要的各种功能。     如图所示,这是软件的文字中奖名单模式。     如图所示,这是软件的文字图片名单模式。     如图所示,这是软件的播放总名单模式显示。软件的功能就大致介绍到这里了,软件其余的具体功能就有小伙伴们自己去发掘吧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值