2015-08-12 6 views
2

Je construis un script qui calcule la génétique des animaux élevés ensemble. Chaque animal a un ensemble de gènes (par exemple BbEeKk) et le programme devrait calculer toutes les possibilités génétiques de la progéniture. Mais je ne suis pas sûr de savoir comment faire des équations sur les lettres, car toute la solution traiterait de multiplier les polynômes en utilisant seulement des lettres. Jusqu'à présent, le script est en PHP. Mais si PHP ne peut pas gérer ce type d'équation, il peut facilement être déplacé vers un autre type.Equations polynomiales utilisant des lettres

Voici un exemple de la façon dont (sur le papier), vous trouverez la progéniture d'un croisement entre BbEEKk et 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) 

Extraire les valeurs finales, nous obtenons:

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 

Je simplement Je n'arrive pas à trouver un moyen pour PHP de gérer ce genre d'opération, et je ne connais pas suffisamment JavaScript pour savoir si ça peut l'être.

+0

c'est intéressant. Ma copine va me tuer (elle est biologiste) mais pouvez-vous, s'il vous plait, nous expliquer comment ces combinaisons de caractères sont formées? – baao

+0

Je ne suis pas exactement sûr de ce que vous entendez par formé, mais les combinaisons de caractères sont juste représentatives des différents gènes. Ainsi, chaque parent a un ensemble de 3 gènes (B, E et K) et comme ils peuvent se combiner de manière différente, chaque nombre représente une paire de gènes répétée pour ainsi dire. Si vous avez déjà fait un graphique en punnett, cela tente d'être une représentation mathématique d'un. http://scienceprimer.com/punnett-square-calculator –

+0

Puis-je vous suggérer de poster ceci sur http://codegolf.stackexchange.com/ Je pense qu'il y a de meilleurs langages que php et javascript pour résoudre ceci de façon efficace – baao

Répondre

2

Donc, si je comprends bien, alors d'abord nous devons séparer « BbEEKk » dans
« Bb », « EE », Kk «et la même chose avec « bbeeKk ».
Ensuite, nous devrions avoir » Bb . "et « bb »
Je bidouillé un peu avec cela et je pense que je résolu la première partie avec les multipliant ensemble, si vous les séparer comme je l'ai écrit:

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]; 
} 
} 

Il devrait être possible de faire la même chose comme je l'ai fait ici avec les autres étapes

+0

Bien que j'aime votre réponse, c'est la raison pour laquelle j'ai demandé à l'OP de poser cette question sur le golf de code. Avec php, il y a trop de remplacement et de réécriture de code. Je pense qu'un langage comme J pourrait mieux le résoudre, mais php n'est pas le bon. Cela deviendrait un énorme gâchis jusqu'à la fin. – baao

+1

Oui, je suis tout à fait d'accord avec vous là-bas, je montrais simplement OP que cela pouvait être fait, mais la partie que j'ai faite était juste la partie simple des 3 étapes qu'il fait, et même ce code a l'air désordonné. Je recommanderais également OP d'utiliser une autre langue pour cela. – uruloke

+0

Merci pour cet exemple. Je vais regarder d'autres langues pour résoudre ce problème. –

3

Intéressant :)

Permet d'intégrer les mathématiques à la programmation.

D'abord, je pense que vous avez fait une erreur dans l'exemple, il devrait être

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

De cette façon, somme de tous les ressorts possibles est 100%

Cela peut être facilement résolu en appliquant la matrice calculs,

La première étape serait de considérer les gènes comme nombre

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

Idem pour toutes les lettres.

Une fois que vous avez l'équation suivante:

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

vous pouvez le traduire en une matrice opération:

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

envisage de prendre transposer de la matrice pour la correspondance de dimension. La matrice résultante vous donnera les chiffres dont la somme serait 64.

+0

Bonne prise! C'est ce que je fais pour le faire trop vite pour le faire ici. hehe. Je n'ai jamais pensé à utiliser une opération matricielle non plus! Serait-il facile de redescendre dans un format de chaîne pour l'affichage? –

+0

Oui, vous obtiendrez le résultat pour toutes les combinaisons possibles, le nombre dans la matrice résultante appartiendra à un ensemble de gènes particulier en fonction de la façon dont vous multipliez (séquence). Essayez Matlab, ne prendra que quelques minutes si vous connaissez Matlab. –

0

une solution (il est une solution « force brute » et non RLY assez):

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

testé commentaires dans le code devrait expliquer il.