BeginPackage["MendelBeans`"] TYPE = "Plant genome (sexless) with self-fertilization."; NOTE = "Crossover frequency = 1.0 (100%)" COPYRIGHT = "This Package created by Dr. Garrett R. Love for the Shodor Education Foundation. Copyright 2001" MakePop::usage = "MakePop[size] creates a population, i.e. a list of (size) creatures, each represented by a genetic code randomly generated from traits in the current genome package." ShowOne::usage = "ShowOne[code] displays the traits associated with the given genetic code." ShowPop::usage = "ShowPop[population] displays the traits associated with each member in a population, such as that generated by MakePop[]." Breed::usage = "Breed[code1,code2,numoff] creates a population of (numoff) offspring, using genetic recombination of parental codes (code1) and (code2). Self-fertilization is allowed for genderless species." BreedPop::usage = "BreedPop[population,numpairs,numoff] creates a list of genetic codes by randomly selecting a given number (numpairs) of breeding members from a population and using genetic recombination to produce (numoff) offspring for each parental pair. Selection of a single individual for self-fertilization is possible for genderless species." PickOne::usage = "PickOne[population,index] selects the individual genetic code in position (index) from a population. Synonymous with the syntax population[[index]]." CountTrait::usage = "CountTrait[population,trait] gives a three part list {match,total,ratio} where match is the number of individuals in the population with the given trait, total is the size of the population, and ratio is the fraction of the population with the given trait. Note: the string in trait must perfectly match the string for the genome (as generated by ShowOne or ShowPop)." CountTraitMatch::usage = "CountTraitMatch[population,traitlist,operator] gives a three part list {match,total,ratio} where match is the number of individuals in the population with all the traits supplied in traitlist (if operator is And), or any of the traits supplied in traitlist (if operator is Or).total is the total size of population, and ratio is the fraction of the population fitting the description. Note: the strings in traitlist must perfectly match the string for the genome (as generated by ShowOne or ShowPop)." FindTraitMatches::usage = "FindTraitMatches[population,traitlist,operator] gives a new list of individuals from the population, either those with all the traits supplied in traitlist (if operator is And), or those with any of the traits supplied in traitlist (if operator is Or)." Begin["`Private`"] Beans = { {1, 5, .50, "Seeds", "Smooth", "Smooth", "Wrinkled"}, {1, 10, .50, "Seeds", "Yellow", "Yellow", "Green" }, {1, 15, .50, "Stems", "Tall", "Tall", "Dwarf"}, {1, 20, .50, "Pods", "Inflated", "Inflated", "Constricted"}, {1, 25, .50, "Pods", "Green", "Green", "Yellow"}, {1, 30, .50, "Flowers", "Purple", "Purple", "White"}, {1, 35, .50, "Flowers", "Axial", "Axial", "Terminal"} }; GENOME = Beans; COPCT = 1.0; CBASE = Table[Power[46, i], {i, 1, 3}]; MakeCrit[genome_] := (glist = Table[ (coin1 = Random[]; coin2 = Random[]; gentyp = If[coin1 >= genome[[i, 3]], 0, 1] + 2*If[coin2 >= genome[[i, 3]], 0, 1]; phen = Switch[gentyp, 3, 1, 2, 2, 1, 2, 0, 3]; CBASE[[2]]*genome[[i, 1]] + CBASE[[3]]*genome[[i, 2]] + CBASE[[1]]*gentyp + phen ), {i, Length[genome]}]; Prepend[glist,"Neutral Gender"]); MakeIphen[genome_, crit_] := Table[ If[i == 1, crit[[1]], (phen = Mod[Mod[crit[[i]], CBASE[[3]]], CBASE[[1]]]; StringJoin[ If[genome[[i - 1, 4 + phen]] != "", StringJoin[genome[[i - 1, 4 + phen]], " "], ""], genome[[i - 1, 4]]])], {i, Length[crit]}]; MateCrits[crit1_, crit2_, numoff_,COpct_] := ( Catch[If[Quotient[Drop[crit1, 1], CBASE[[3]]] == Quotient[Drop[crit2, 1], CBASE[[3]]], Table[ (clist = Range[Max[Quotient[Mod[Drop[crit1, 1], CBASE[[3]]], CBASE[[2]]]]]; coin1 = Table[Random[Integer],{i, Length[clist]}]; coin2 = Table[Random[Integer],{i, Length[clist]}]; COtags1 = Table[If[ Random[] <= COpct, Random[Integer,{1, 50}], 50], {i, Length[clist]}]; COtags2 = Table[If[ Random[] <= COpct, Random[Integer,{1, 50}], 50], {i, Length[clist]}]; Table[If[i == 1,"Neutral Gender", (csome = Quotient[Mod[crit1[[i]], CBASE[[3]]], CBASE[[2]]]; cloc = Quotient[crit1[[i]], CBASE[[3]]]; cr1gt = Quotient[Mod[Mod[crit1[[i]], CBASE[[3]]], CBASE[[2]]], CBASE[[1]]]; cr2gt = Quotient[Mod[Mod[crit2[[i]], CBASE[[3]]], CBASE[[2]]], CBASE[[1]]]; side1 = If[cloc > COtags1[[csome]], 1 - coin1[[csome]], coin1[[csome]]]; side2 = If[cloc > COtags2[[csome]], 1 - coin2[[csome]], coin2[[csome]]]; gentyp = 2*(side1*Quotient[cr1gt, 2] + (1 - side1)*Mod[cr1gt, 2]) + ((1 - side2)*Quotient[cr2gt, 2] + side2*Mod[cr2gt, 2]); phen = Switch[gentyp, 3, 1, 2, 2, 1, 2, 0, 3]; CBASE[[2]]*csome + CBASE[[3]]*cloc + CBASE[[1]]*gentyp + phen)], {i, Length[crit1]}]),{j, numoff}], Throw["Error: Different gene lists - mixing species?"]]] ); MakePop[size_] := Table[MakeCrit[GENOME] , {i, size}]; ShowPop[pop_] := Transpose[Table[MakeIphen[GENOME, pop[[i]]], {i, Length[pop]}]] // TableForm; ShowOne[crit_] := MakeIphen[GENOME, crit] // TableForm; PickOne[pop_, num_] := pop[[num]]; Breed[crit1_, crit2_, numoff_] := MateCrits[crit1, crit2, numoff, COPCT]; BreedPop[pop_, pairs_, broodsize_] := Flatten[ (genlist = Transpose[pop][[1]]; Table[ (crit1 = pop[[Random[Integer, {1, Length[pop]}]]]; crit2 = pop[[Random[Integer, {1, Length[pop]}]]]; MateCrits[crit1, crit2, broodsize, COPCT]), {i, pairs}]), 1]; CountTrait[pop_,trait_] := {a = Count[Flatten[ Table[MakeIphen[GENOME, pop[[i]]],{i,Length[pop]}]],trait], b = Length[pop], a/b}; CountTraitMatch[pop_,traitlist_,operator_] := (poplist = Table[MakeIphen[GENOME, pop[[i]]],{i,Length[pop]}]; {a = Count[Thread[Apply[operator, Table[MemberQ[poplist[[i]],traitlist[[j]]], {j,Length[traitlist]}, {i,Length[poplist]}]]],True], b = Length[pop], a/b} ) FindTraitMatches[pop_,traitlist_,operator_] := (poplist = Table[MakeIphen[GENOME, pop[[i]]],{i,Length[pop]}]; a = Flatten[Position[Thread[Apply[operator, Table[MemberQ[poplist[[i]],traitlist[[j]]], {j,Length[traitlist]}, {i,Length[poplist]}]]],True]]; Part[pop,a] ) End[ ] EndPackage[ ]