首页 新闻 会员 周边 捐助

js将 50000元,按照一定的规则随机分配

0
悬赏园豆:200 [待解决问题]

将 50000元随机分给10个人,其中3个人必须分到百位数,4个人分到千位数,3个人分到万位数,每个人所得金额保留两位小数

好来污影后的主页 好来污影后 | 菜鸟二级 | 园豆:287
提问于:2018-07-02 17:01

是类似红包分配的算法吗?其中什么是变参?什么是固参?

Ben_Mario 6年前
< >
分享
所有回答(7)
0

暴力吧,暴力出奇迹

老哈球 | 园豆:202 (菜鸟二级) | 2018-07-02 17:10
0

思路可以这样,只随机尾数:

var sum=50000;
var tempsum=sum;
//可以分组循环,一万的循环三次;上千的循环四次;上百的循环三次
var num1 = Math.random()*100 + 10000;
num1=num1.toFixed(2);

var num2 = Math.random()*100 + 10000;
num2=num2.toFixed(2);

var num3 = Math.random()*100 + 10000;
num3=num3.toFixed(2);

tempsum-=(parseFloat(num1)+parseFloat(num2)+parseFloat(num3));

一万的,先从一万开始,随机尾数;如果不想彻底重复,就用数组存起来,每次随机完值,就去数组中检查,有重复就重新随机生成数字;

以前的从三千开始,随机尾数;

总数减除前面的,后面的留给百位随机;

百位最后一个有总数减除上面所有随机的数字;

这方法虽然有点笨,但是合理分配值,是可以用的,后面再慢慢优化

悟行 | 园豆:12559 (专家六级) | 2018-07-02 18:24

你好,Math.random()*100 是什么原因呢 ?

支持(0) 反对(0) 好来污影后 | 园豆:287 (菜鸟二级) | 2018-07-02 19:10

@好来污影后: 尾数随机数,你在控制台打印就知道了

支持(0) 反对(0) 悟行 | 园豆:12559 (专家六级) | 2018-07-03 08:35

存在一定范围的错误

支持(0) 反对(0) Mario0315 | 园豆:340 (菜鸟二级) | 2018-07-13 17:20
0

原谅我,连你的问题都没理解到。

幻天芒 | 园豆:37207 (高人七级) | 2018-07-02 21:23
0

——理解同上。

 

如果是取10个不为0,只需要逐个random就行了,下一个就是剩余值内random。

花飘水流兮 | 园豆:13617 (专家六级) | 2018-07-03 00:35
0

嘛意思,还能描述的再差一点么

小光 | 园豆:1766 (小虾三级) | 2018-07-03 09:12
0

你的意思是保留两位之后,要总和为50000吗? 还是你写的这个就是你想要的答案?

没有表达清楚呀。。

铁柱成针 | 园豆:614 (小虾三级) | 2018-07-09 14:07
0
/**
 * 函数将返回分割后的数据 格式为2维数组
 * @param {*} rules
 * @param {*} total
 * @param {number} [fraction=1]
 * @returns
 */
let go = (rules, total, fraction = 1) => {

  if(fraction % 10 == 0 || fraction == 1) {
    total *= fraction;
    for(let i = 0; i < rules.length; i++) {
      rules[i].min *= fraction;
    }
  }else {
    throw Error('放大倍数填写错误!');
  }

  let rd = (n, m) => { // 生成整数随机数
    var c = m - n + 1;
    return Math.floor(Math.random() * c + n);
  }

  // 排序原始规则
  rules = [...rules.sort((a, b) => {
    if (a.min > b.min) {
      return 1;
    }
  })]
  for(let i = 0; i < rules.length - 1; i++) {
    rules[i].max = '';
    for(let k = 0; k < rules[i].min.toString().length; k++) {
      rules[i].max += '9'; 
      rules[i].max = parseInt(rules[i].max);
    }
  }
  console.log(rules)

  let surplus = 0; // 剩余未分配的量
  let count = 0; // 计数器
  let result = []; // 用于保存最终的结果
  let lastLen = rules[rules.length - 1].length; // 原始规则中 最后一个条规则的 length
  createRes = () => {
    let temp = [];
    for(let i = 0; i < rules[count].length; i++) {
      temp.push(rd(rules[count].min, rules[count].max));
    }
    if(count == rules.length - 1) {
      console.log('count = '+ count +' 的时候,结果为:');
      console.log('剩余未分配的量:' + surplus);
      console.log(temp)
      let tempSum = temp.reduce((a, b) => (a + b), 0)
      let t = surplus - tempSum;
      console.log('最后一位的值为:' + t)
      if(t >= rules[count].min) {
        count++;
        temp.push(t);
        result.push(temp);
        console.log('条件符合');
      }else {
        console.log('剩余分配的量不符合,继续随机');
      }
    }
    if(count < rules.length - 1) {
      let tempSum = temp.reduce((a, b) => (a + b), 0)
      if(count == 0) {
        console.log('count = '+ count +' 的时候,结果为:')
        console.log(temp);
        if(tempSum <= rules[count].max * rules[count].length) {
          count++;
          result.push(temp)
          console.log('条件符合');
        }
      }else {
        console.log('count = '+ count +' 的时候,结果为:')
        getResSum = () => {
          let resSum = 0;
          for(let i = 0; i < result.length; i++) {
            resSum += result[i].reduce((a, b) => (a + b), 0)
          }
          return resSum;
        }
        console.log(temp)
        let p = total - getResSum() - rules[rules.length - 1].min * rules[rules.length - 1].length;
        console.log('本次的和:' + tempSum)
        console.log('本次允许最大的量:' + p)
        if(tempSum <= p) {
          count++;
          result.push(temp);
          if(count == rules.length - 1) {
            surplus = total - getResSum();
            rules[count].max = surplus - rules[count].min * (lastLen - 1);
            rules[count].length = lastLen - 1;
          }
          console.log('条件符合');
        }else {
          console.log('条件不符合继续随机');
        }
      }
    }
    if(count > rules.length - 1) {
      console.log('结束')
      return false;
    }
    createRes();
  }
  createRes();
  return result;
}

// 规则中的每一项 必须包含最小值 和 生成个数
let rules = [
  {
    min: 100,
    length: 3, // length 越大 消耗cpu越多
  },
  {
    min: 1000,
    length: 4, 
  },
  {
    min: 10000,
    length: 3
  }
];

// 放大倍数,用于保留小数
let _fraction = 100;
// 开始调用
var r = go(rules, 50000, _fraction);
let s = 0;
console.log(r);
console.log('开始缩小倍数:')
for(let i = 0; i < r.length; i++) {
  s += r[i].reduce((a, b) => (a + b), 0)
  for(let k = 0; k < r[i].length; k++) {
    r[i][k] /= _fraction; 
  }
}
console.log(r);
console.log('总和:' + s / _fraction)
好来污影后 | 园豆:287 (菜鸟二级) | 2018-07-11 13:02

思路貌似一样,但是怎么感觉你实现的好复杂,我写了主体,25行,加上附加的判断,应该也就50多行吧

支持(0) 反对(0) Mario0315 | 园豆:340 (菜鸟二级) | 2018-07-13 18:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册