我有一系列我想要生孩子的父母,还有一个空数组(我需要一个固定的长度)等待填充。
我需要婴儿 - 孩子 - 根据父亲的英俊程度来均匀分配;但是,我需要每个人得到一个克隆,因为他们变异的孩子更丑陋/更漂亮,然后又是另一个机会......(parents.length <= children.length
)
父数组按英俊度排序,因此parents[0] = me;
。
到目前为止我所做的是:
for (var p = parents.legth; parent--;) {
var myself = parents[p],
aRandomDaddy = parents[~~(Math.random()*parents.length)]
iDeserveMoreThan1Child = parents.length-p;
// if this is 0 they're last in the array and just get their 1 clone. Should be different, right?
makeABabyWith(myself);
if (iDeserveMoreThan1Child) {
makeABabyWith(aRandomDaddy);
}
}
我现在要做的是找出一种算法makeABabyWith(aRandomDaddy)
,children.length - parents.length
次的方法,并考虑到爸爸们的英俊程度。
我想过这样做:
for(var c = parents.length, totalHandsomeness = 0; c--;)
totalHandsomeness+= parents[c].handsomeness;
...
makeABabyWith(myself);
for (var handsomenessComparedToEveryoneElse
= ~~(myself.handsomeness * children.length / totalHandsomeness);
handsomenessComparedToEveryoneElse--;) {
makeABabyWith(aRandomDaddy);
}
...
现在,这给出了相对于父母的优势的分布。 然而,当地板发生时,你有时会得到0。 因此,如果子阵列的长度为20,那么你的后代可能会非常广泛。
我认为应对此问题的一种方法是明确地运行这个前景,如下所示:
...
var childrenToBeCreated = children.length - parents.length;
...
makeABabyWith(myself);
while (childrenToBeCreated) for (var handsomenessComparedToEveryoneElse
= ~~(myself.handsomeness * children.length / totalHandsomeness);
handsomenessComparedToEveryoneElse--;) {
if (childrenToBeCreated) {
makeABabyWith(aRandomDaddy);
childrenToBeCreated--;
} else break;
}
//EDIT: realised this would run to the end in the first loop and break, instead of run through all and check for left overs.
//EDIT OF THE EDIT: no it wouldn't...
//ED...: Yes it would, the while loops inside the for loop.
...
console.log("is","this"+"a good way to do it?? would this even work");
虽然这是用JS编写的,但它在任何语言中都是完全相同的原则。
我在编写这个问题时想到的方法是否足够,你会怎么做?
编辑:最后一个示例意味着使用childrenToBeCreated
而不是ptotal
的百分比,我想我感到困惑。
答案 0 :(得分:0)
关于这个问题的法律含义,你应该联系律师,但我想我可以帮助你解决问题的技术方面;)
卡米诺(阿尔法体育场)工厂的蓝图:
var int = v => 0|v;
//creates mostly average and below values, and fewer high values
var randomHandsomeness = () => int( Math.pow(Math.random(), 2) * 100 ) + 1;
var breedClone = (parent) => ({
id: int(Math.random() * 0x80000000).toString(36), //no time for names
handsomeness: int( .25 * parent.handsomeness + .75 * randomHandsomeness() ), //a bit genetic heritage but mostly luck
parent: parent //just for the record
});
var deriveBatch = (parents, numClonesToBreed, minChildrenPerParent, distribution) => {
console.log("starting batch of", numClonesToBreed);
if(typeof minChildrenPerParent === "function"){
distribution = minChildrenPerParent;
minChildrenPerParent = 0;
}
if(typeof distribution !== "function"){
distribution = (handsomeness) => handsomeness;
}
minChildrenPerParent = Math.max(int(minChildrenPerParent), 0);
//I'll add these back in the loop
numClonesToBreed -= parents.length * minChildrenPerParent;
if(numClonesToBreed < 0){
throw new Error("increase batch size, insufficient capacities for these specs");
}
//order doesn't matter, only handsomeness in relation to the total handsomeness
var totalHandsomeness = parents.reduce((acc, p) => acc + distribution( p.handsomeness ), 0);
return parents.reduce((newBatch, parent) => {
//this computation doesn't only compute the relative handsomeness of the parent to the group,
//and the amount of children he's entitled to, but also balances the delta
//between the computed value and the rounded numChildren
//(partial clones are of no use and are therefore avoided).
//At the same time it's important to neither overproduce nor stay short of the goal.
var handsomeness = distribution( parent.handsomeness );
var numChildren = Math.round( handsomeness / totalHandsomeness * numClonesToBreed );
totalHandsomeness -= handsomeness;
numClonesToBreed -= numChildren;
//add the minimum amount of children per parent to the computed/distributed numChildren
numChildren += minChildrenPerParent;
console.log("handsomeness: %i, children: %i", parent.handsomeness, numChildren);
while(numChildren--) newBatch.push( breedClone( parent ) );
return newBatch;
}, []);
}
让生产开始:
//prepare a first batch
var parents = deriveBatch([{
id: "Jango Fett",
handsomeness: 75,
parent: null //file corrupted
}], 10);
//breed new clones from the parent batch
//create 30 clones
//create at least 1 clone per parent
//and a weighting function how the handsomeness impacts the amount of children
//pow < 1: handsome people get more children, but not that much more
//pow = 1: linear correlation of handsomeness to distribution
//pow > 1: handsome people get significantly more children
var children = deriveBatch(parents, 30, 1, handsomeness => Math.pow(handsomeness, 1.25));
免责声明:对于任何外国指令下制作的克隆所执行的任何操作,本机构不承担任何责任。
我认为大多数代码都应该自行解释,并且应该很容易移植/应用到您的代码库。添加了一些钩子和配置,以便能够操纵算法的行为/分布。