【问题标题】:How do you properly distribute children?如何正确分配孩子?
【发布时间】:2017-02-09 11:41:36
【问题描述】:

我有一组想要生孩子的父母,还有一个空数组(我需要固定长度)等待填充。

我需要婴儿——孩子——根据他们父亲的英俊程度平均分配;但是,我需要每个人都得到一个克隆,以防他们的变异孩子更丑/更漂亮,然后还有另一个机会......(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。 因此,如果 children 数组的长度为 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,我想我很困惑。

【问题讨论】:

  • How do you properly distribute children? 这听起来更像是一个法律问题,而不是编程问题。听起来在道德上也有点可疑。
  • 我不得不赞成这个问题,以及你的评论@SamAxe。前提是历史性的。大声笑I need babies。 LOL 父数组是按颜值排序的,所以parents[0] = me
  • 这整个问题都是秘密的贩卖广告。
  • 您意识到您的软件永远不会运行,对吗?所有的父母都是爸爸......虽然这在某些地方可能在社会上是可以接受的......无论您的位置,政治,道德等如何,这都是生殖上的不可能性。
  • makeABabyWith(aRandomDaddy) 看看这就是当今社会的问题

标签: javascript arrays algorithm sorting genetic-algorithm


【解决方案1】:

关于这个问题的法律影响,你应该联系律师,但我想我可以在技术方面为你提供帮助;)

卡米诺(阿尔法体育场)工厂的蓝图:

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));

免责声明:该设施不对生产的克隆在任何外国命令下执行的任何行为负责。

我认为大部分代码都应该自我解释,并且应该很容易移植/应用到您的代码库中。添加了一些钩子和配置,以便能够操纵算法的行为/分布。

【讨论】:

  • 很好的解决方案,真的很优雅
  • 你能在 javascript/console.log() 中做“%i”类型替换吗?或者它是一个 ES6 特性,因为我注意到你使用了一些 lambda 函数。
猜你喜欢
  • 1970-01-01
  • 2017-07-04
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
相关资源
最近更新 更多