Вычисление вероятности потомства, имеющего хотя бы один доминантный аллель

Я пытаюсь решить задачу «Первый закон Менделя» на сайте http://rosalind.info/.

Я пробовал несколько разных подходов, но я просто не могу заставить свое решение возвращать тот же ответ, что и образец проблемы на их странице. Я знаю, что их образец вывода правильный.

Вот что у меня есть:

traitProb :: Int -> Int -> Int -> Double
traitProb k m n = getProb list
      where list = cartProd genotypes genotypes
            genotypes = (replicate k Dominant) ++ (replicate m Heterozygous) ++ (replicate n Recessive)
            getProb = sum . map ((flip (/)) total . getMultiplier)
            total = fromIntegral $ length list
            getMultiplier (Dominant, Dominant) = 1.0
            getMultiplier (Recessive, Dominant) = 1.0
            getMultiplier (Dominant, Recessive) = 1.0
            getMultiplier (Dominant, Heterozygous) = 1.0
            getMultiplier (Heterozygous, Dominant) = 1.0
            getMultiplier (Heterozygous, Heterozygous) = 0.75
            getMultiplier (Heterozygous, Recessive) = 0.5
            getMultiplier (Recessive, Heterozygous) = 0.5
            getMultiplier (Recessive, Recessive) = 0.0

Я не уверен, то ли код неверен, то ли мой метод вычисления вероятности неверен. По сути, идея состоит в том, чтобы получить список всех возможных родителей, а затем, исходя из того, являются ли они гомозиготными, доминантными, рецессивными или гетерозиготными, вычислить вероятность того, что каждая пара родителей произведет ребенка с хотя бы одним доминантным аллелем. Затем разделите каждый результат на общее количество пар родителей. После этого я просто суммирую список. Но мой ответ немного неверен.

Может кто-то указать мне верное направление?

РЕДАКТИРОВАТЬ: cartProd - это "декартово произведение" двух переданных ему списков, если хотите.

cartProd :: [a] -> [a] -> [(a, a)]
cartProd xs ys = [ (x, y) | x <- xs, y <- ys ]

person user3468950    schedule 31.05.2014    source источник
comment
Я думаю, вы должны разделить свою функцию на разные отдельные задачи. Эта функция делает слишком много и не совсем читаема, ИМХО. getMultiplier также можно уменьшить, сопоставив 0.75, 0.5 и 0.0, а все остальное пусть будет 1.0: getMultiplier (_, _) = 1.0. Как ни странно, я сделал то же упражнение сегодня. Мое решение можно найти здесь, если вам нужно вдохновение. :)   -  person Shoe    schedule 01.06.2014
comment
Нам также нужно знать, что делает cartProd. Я предполагаю, что это декартово произведение. Если бы вы могли опубликовать SSCCE, это увеличило бы вероятность получения вашего ответа.   -  person Shoe    schedule 01.06.2014
comment
Спасибо за ответ. Когда я писал getMultiplier, я знал, что делаю это неэффективно, но теперь я понимаю, насколько избыточна большая часть сопоставления с образцом. Я постараюсь изменить свое решение, и если мне нужно, я загляну в ваше.   -  person user3468950    schedule 01.06.2014
comment
Если вы можете предоставить SSCCE (просто предоставив компилируемую версию, на Ideone или где-либо еще), я с радостью помогу вам.   -  person Shoe    schedule 01.06.2014
comment
Сколько стоит немного?   -  person Code-Apprentice    schedule 01.06.2014
comment
Джеффри: ideone.com/GOeDT3, Code-Guru: Достаточно того, что я знаю, что это неправильно.   -  person user3468950    schedule 01.06.2014
comment
Вероятно, вы можете упростить свой подход, рассчитав вероятность выбора каждого генотипа для каждого родителя, а не явно перечисляя все пары родителей.   -  person Code-Apprentice    schedule 01.06.2014
comment
Я пытался и был уверен, что делаю это правильно, но в конце концов прибег к этому, потому что я не мог получить правильный ответ даже для примера ввода 2 2 2.   -  person user3468950    schedule 01.06.2014


Ответы (1)


Я предлагаю немного изменить свое мышление, выполнив расчет в три шага:

  1. Какова вероятность получения генотипа X у первого родителя? (Кроме того, сколько различных вариантов есть для X?)

  2. Какова вероятность получения генотипа Y у второго родителя?

  3. Учитывая генотипы X и Y родителей, какова вероятность того, что у ребенка будет доминантный генотип?

Суммируйте шаги 1-3 для каждой пары (X, Y).

Когда я нарисовал древовидную диаграмму от руки, мне стало легче рассчитать вероятность того, что у ребенка НЕ ​​будет доминантного аллеля. Вариантов для суммирования меньше, и тогда вы можете вычесть эту сумму из 1.

person Code-Apprentice    schedule 01.06.2014
comment
Вот решение, которое я придумал, используя этот подход: traitProb' k m n = let j = k + n + m a = k + n + m - 1 in ((k/j) * (((k-1)/a) + (n/a) + (m/a))) + ((n/j) * ((k/a) + (m/a/2))) + ((m/j) * ((k/a) + (n/a/2) + ((m-1)/a * 0.75 ))) В основном это решение только для записи, но оно работает. Я пробовал это изначально, но не мог получить правильный ответ по какой-то причине. - person user3468950; 01.06.2014