使用字母

时间:2015-08-12 00:07:49

标签: javascript php algebra

我正在构建一个脚本,用于计算一起繁殖的动物的遗传。每只动物都有一组基因(例如BbEeKk),程序应该计算后代的所有遗传可能性。但我不知道如何对字母进行方程式,因为整个解决方案只使用字母来处理乘法多项式。到目前为止,脚本是用PHP编写的。但是如果PHP无法处理这种类型的等式,它可以很容易地转移到另一个等式。

这是一个如何(在纸面上)你会找到BbEEKk和bbeeKk之间交叉的后代的例子:

// First we take the individual gene pairs and multiply them together
(B + b)(b + b) = 2Bb + 2bb
(E + E)(e + e) = 4Ee
(K + k)(K + k) = 1KK + 2Kk + 1kk

// Take those and form a polynomial
(2Bb + 2bb)(4Ee)(1KK + 2Kk + 1kk)

// Multiply first two expressions
(6BbEe + 6bbEe)(1KK + 2Kk + 1kk)

// Multiply remaining two expressions
(6BbEeKK + 12BbEeKk + 6BbEekk + 6bbEeKK + 12bbEeKk + 6bbEekk)

提取我们得到的最终值:

12/64 (18.75%) offspring as BbEeKk
12/64 (18.75%) offspring as bbEeKk 
6/64 (9.375%) offspring as BbEeKK
6/64 (9.375%) offspring as BbEekk
6/64 (9.375%) offspring as bbEeKK
6/64 (9.375%) offspring as bbEekk

我似乎无法为PHP找到一种处理此类操作的方法,而且我不熟悉JavaScript以了解它是否可以。

3 个答案:

答案 0 :(得分:3)

有趣:)

让数学与编程相结合。

首先,我认为你在例子中犯了一个错误,应该是

// First we take the individual gene pairs and multiply them together
(B + b)(b + b) = 2Bb + 2bb
(E + E)(e + e) = 4Ee
(K + k)(K + k) = 1KK + 2Kk + 1kk

// Take those and form a polynomial
(2Bb + 2bb)(4Ee)(1KK + 2Kk + 1kk)

// Multiply first two expressions
(8BbEe + 8bbEe)(1KK + 2Kk + 1kk)

// Multiply remaining two expressions
(8BbEeKK + 16BbEeKk + 8BbEekk + 8bbEeKK + 16bbEeKk + 8bbEekk)

这样,所有可能的弹簧总和为100%

这可以通过应用矩阵计算轻松解决,

第一步是将基因视为数字

bb ==> 0
bB ==> Bb ==> 1
BB ==> 2

任何字母都相同。

一旦你有以下等式:

(2Bb + 2bb)(4Ee)(1KK + 2Kk + 1kk)

您可以将其翻译为矩阵操作:

[2 2 0] * [0 4 0] * [1 2 1]

考虑对矩阵进行转置以进行尺寸匹配。结果矩阵将为您提供总和为64的数字。

答案 1 :(得分:2)

因此,如果我理解正确,那么首先我们必须分开" BbEEKk"进入" Bb"," EE",Kk",和" bbeeKk"相同。
之后,我们应该有" Bb"和" bb"。
我用这个摆弄了一点,我认为如果你把它们分开来解决第一部分,就像我写的一样:

function test($a,$b){
if ($a[0] == $a[1]) {

    if ($b[0] == $b[1]) {
        return "4" . $a[0] . $b[0];
    }
    return "2" . $b[0] . $a[0] . "+2" . $a[0] . $a[0];
} elseif ($b[0] == $b[1]) {

    if ($a[0] == $a[1]) {
        return "4" . $b[0] . $a[0];
    }
    return "2" . $a[0] . $b[0] . "+2" . $b[0] . $b[0];
} elseif ($a[0] != $a[1]) {
    return "1" . $a[0] . $a[0] . "+2" . $a . "+1" . $a[1] . $a[1];
}
}

应该可以像我在这里做的那样做其他步骤。

答案 2 :(得分:0)

一种解决方案(它是一种“蛮力”解决方案而不是很漂亮):

<?php
    $seqs = ["BbEEKk", "bbeeKk"];
    // chunk them to parts of 2 chars
    $seqs = array_map(function($el) {return str_split($el,2);}, $seqs);
    echo "<pre>".print_r($seqs,true)."</pre>";
    // cross the two sequence strings:
    $step1 = [];
    for($i=0;$i<count($seqs[0]);$i++)
        $step1[] = multiplySequences([$seqs[0][$i], $seqs[1][$i]]);
    echo "<pre>".print_r($step1,true)."</pre>";
    // now multiply the result and sort them:
    $step2 = multiplySequences($step1);
    usort($step2, function($a, $b) {
        return $b[0]-$a[0];
    });
    echo "<pre>".print_r($step2,true)."</pre>";

    // takes an array of sequenzes. a sequenze is an array of sequenzeparts. a sequenzepart is an array [0=>number, 1=>the sequenz as chars]
    function multiplySequences($seqs) {
        foreach($seqs as &$seq)
            multiplySequencesPrepare($seq);
        // multiply them all:
        $t = $seqs[0];
        for($i=1;$i<count($seqs);$i++) {
            $t = multiplySequencesHelper($t, $seqs[$i]);
            $t = multiplySequencesPrepare($t);
        }
        return $t;
    }
    // prepare the data to process them. it defines the format from above: input can be a string "2Bb" or an array. if it's an array there are to possibilities: 1) [0=>number, 1=>sequence] or [[0=>number, 1=>sequence],[0=>number, 1=>sequence],...]
    function multiplySequencesPrepare(&$seq) {
        if(is_array($seq))
            $seq = array_map(function($s) { if(is_array($s)) return $s; preg_match('/(\d*)(\w+)/', $s, $s); $s[1]=(int)$s[1]==0?1:(int)$s[1]; return array_slice($s,1);}, $seq);
        else
            $seq = call_user_func(function($s) {
                preg_match('/(\d*)(\w+)/', $s, $s);
                $s[2] = str_split($s[2]);
                $s[1]=(int)$s[1]==0?1:(int)$s[1];
                return array_map(function($sp) use($s) { return [$s[1], $sp]; }, $s[2]);
            }, $seq);
        return $seq;
    }
    // calculate the result of two sequences:
    function multiplySequencesHelper($seq1, $seq2) {
        $res = [];
        $cnt = [];
        foreach($seq1 as $s1)
            foreach($seq2 as $s2) {
                $c1 = $s1[1];
                $c2 = $s2[1];
                $res[] = $tcc = ($c1<$c2?$c1.$c2:$c2.$c1);
                $cnt[$tcc] = $s1[0]*$s2[0];
            }
        $tmp = array_count_values($res);
        return array_map(function($el) use($tmp,$cnt) { return ($cnt[$el]*$tmp[$el]).$el; }, array_unique($res));   
    }
代码中的

测试注释应该解释它。