暴力吧,暴力出奇迹
思路可以这样,只随机尾数:
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));
一万的,先从一万开始,随机尾数;如果不想彻底重复,就用数组存起来,每次随机完值,就去数组中检查,有重复就重新随机生成数字;
以前的从三千开始,随机尾数;
总数减除前面的,后面的留给百位随机;
百位最后一个有总数减除上面所有随机的数字;
这方法虽然有点笨,但是合理分配值,是可以用的,后面再慢慢优化
你好,Math.random()*100 是什么原因呢 ?
@好来污影后: 尾数随机数,你在控制台打印就知道了
存在一定范围的错误
原谅我,连你的问题都没理解到。
——理解同上。
如果是取10个不为0,只需要逐个random就行了,下一个就是剩余值内random。
嘛意思,还能描述的再差一点么
你的意思是保留两位之后,要总和为50000吗? 还是你写的这个就是你想要的答案?
没有表达清楚呀。。
/** * 函数将返回分割后的数据 格式为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)
思路貌似一样,但是怎么感觉你实现的好复杂,我写了主体,25行,加上附加的判断,应该也就50多行吧
是类似红包分配的算法吗?其中什么是变参?什么是固参?
– Ben_Mario 6年前