首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在mathematica中模拟以下场景

如何在mathematica中模拟以下场景
EN

Stack Overflow用户
提问于 2011-03-08 06:52:56
回答 4查看 240关注 0票数 2

假设我有n=6不同的单体,每个单体都有两个不同的反应性末端。在每一轮反应中,一个随机末端与另一个随机末端结合,要么将单体拉长为二聚体,要么自缔合成环。当系统中没有自由端时,这个反应过程就会停止。我想用Mma来模拟这个反应过程。

我正在考虑将单体表示为字符串列表,{'1-2','3-4','5-6','7-8','9-10','11-12'},然后通过更新列表的内容进行一轮反应,例如{'1-2-1','3-4','5-6','7-8','9-10','11-12'}或{'1-2-3-4','5-6','7-8','9-10','11-12'}。但由于我在Mma中的编程限制,我不能走得很远。有人能帮帮忙吗?非常感谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-03-08 07:42:43

以下是设置:

代码语言:javascript
复制
Clear[freeVertices];
freeVertices[edgeList_List] := Select[Tally[Flatten[edgeList]], #[[2]] < 2 &][[All, 1]];

ClearAll[setNew, componentsBFLS];
setNew[x_, x_] := Null;
setNew[lhs_, rhs_] := lhs := Function[Null, (#1 := #0[##]); #2, HoldFirst][lhs, rhs];

componentsBFLS[lst_List] := 
 Module[{f}, setNew @@@ Map[f, lst, {2}]; GatherBy[Tally[Flatten@lst][[All, 1]], f]];

这里是开始:

代码语言:javascript
复制
In[13]:= start = Partition[Range[12], 2]

Out[13]= {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}

以下是步骤:

代码语言:javascript
复制
In[51]:= steps = 
NestWhileList[Append[#, RandomSample[freeVertices[#], 2]] &, 
  start, freeVertices[#] =!= {} &]

Out[51]= {{{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}, {{1, 
2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {5, 1}}, {{1, 
2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {5, 1}, {3, 
4}}, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {5, 
1}, {3, 4}, {7, 11}}, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 
10}, {11, 12}, {5, 1}, {3, 4}, {7, 11}, {8, 2}}, {{1, 2}, {3, 
4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {5, 1}, {3, 4}, {7, 11}, {8,
2}, {6, 10}}, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 
12}, {5, 1}, {3, 4}, {7, 11}, {8, 2}, {6, 10}, {9, 12}}}

下面是你可以学习的连通组件(循环等):

代码语言:javascript
复制
In[52]:= componentsBFLS /@ steps

Out[52]= {{{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}, {{1, 2,
5, 6}, {3, 4}, {7, 8}, {9, 10}, {11, 12}}, {{1, 2, 5, 6}, {3, 
4}, {7, 8}, {9, 10}, {11, 12}}, {{1, 2, 5, 6}, {3, 4}, {7, 8, 11, 
12}, {9, 10}}, {{1, 2, 5, 6, 7, 8, 11, 12}, {3, 4}, {9, 10}}, {{1, 
2, 5, 6, 7, 8, 9, 10, 11, 12}, {3, 4}}, {{1, 2, 5, 6, 7, 8, 9, 10, 
11, 12}, {3, 4}}}

发生的情况是,我们将所有对视为一个大图中的边,如果两个顶点目前至多有一个到其他边的连接,则随机添加一条边。在某一时刻,该过程会停止。然后,我们将componentsBFLS函数映射到结果图(表示模拟的步骤),以获得图的连接组件(步骤)。当然,您也可以使用其他度量标准,并编写更多的函数来分析循环等步骤。希望这将帮助您入门。

票数 2
EN

Stack Overflow用户

发布于 2011-03-08 07:06:03

将分子表示为列表而不是字符串似乎更自然。所以从{{1,2},{3,4},{5,6}}开始,依此类推。然后开链就是更长的列表{1,2,3,4}或其他任何东西,并且对于循环有一些特殊的约定,比如以符号"loop“开头。{{loop,1,2},{3,4,5,6},{7,8}}等等。

你的模拟到底需要多详细?例如,您是否真的关心哪些单体最终与哪些单体相邻,或者您是否只关心链长的统计数据?在后一种情况下,您可以极大地简化模拟的状态:例如,它可以由循环长度列表(开始时为空)和开链长度列表(开始时为一串1)组成。然后一个模拟步骤是:随机挑选一个开链;以适当的概率,将其变成一个循环或将其与另一个开链组合。

你可能想要查找的数学东西: RandomInteger,RandomChoice;Prepend,Append,Insert,Delete,ReplacePart,Join;While (虽然实际上是某种“函数式迭代”,比如NestWhile,可能会让代码更漂亮)。

票数 2
EN

Stack Overflow用户

发布于 2011-03-08 08:26:08

这里有一个简单的方法。根据问题中给出的例子,我假设单体具有首选的结合,因此只有{1,2} + {3,4} -> {1,2,3,4} OR {1,2,1} + {3,4,3}是可能的,而{1,2} + {3,4} -> {1,2,4,3}是不可能的。一旦你对下面的代码感到满意,就应该把它打包成一个很好的函数/模块。如果你想要统计,那么也可以编译它来增加一些速度。

初始化:

代码语言:javascript
复制
In[1]:= monomers=Partition[Range[12],2]
        loops={}
Out[1]= {{1,2},{3,4},{5,6},{7,8},{9,10},{11,12}}
Out[2]= {}

循环:

代码语言:javascript
复制
In[3]:= While[monomers!={},
  choice=RandomInteger[{1,Length[monomers]},2];
  If[Equal@@choice, 
     AppendTo[loops, monomers[[choice[[1]]]]];
       monomers=Delete[monomers,choice[[1]]],
     monomers=Prepend[Delete[monomers,Transpose[{choice}]],
                      Join@@Extract[monomers,Transpose[{choice}]]]];
     Print[monomers,"\t",loops]
   ]
During evaluation of In[3]:= {{7,8,1,2},{3,4},{5,6},{9,10},{11,12}} {}
During evaluation of In[3]:= {{5,6,7,8,1,2},{3,4},{9,10},{11,12}}   {}
During evaluation of In[3]:= {{5,6,7,8,1,2},{3,4},{9,10}}   {{11,12}}
During evaluation of In[3]:= {{3,4,5,6,7,8,1,2},{9,10}} {{11,12}}
During evaluation of In[3]:= {{9,10}}   {{11,12},{3,4,5,6,7,8,1,2}}
During evaluation of In[3]:= {} {{11,12},{3,4,5,6,7,8,1,2},{9,10}}

编辑:

如果单体可以在两端结合,你只需添加一个选项来翻转你加入的单体,例如

代码语言:javascript
复制
Do[
  choice=RandomInteger[{1,Length[monomers]},2];
  reverse=RandomChoice[{Reverse,Identity}];
  If[Equal@@choice,
    AppendTo[loops,monomers[[choice[[1]]]]];
      monomers=Delete[monomers,choice[[1]]],
    monomers=Prepend[Delete[monomers,Transpose[{choice}]],
             Join[monomers[[choice[[1]]]],reverse@monomers[[choice[[2]]]]]]];
  Print[monomers,"\t",loops],{Length[monomers]}]

{{7,8,10,9},{1,2},{3,4},{5,6},{11,12}}  {}
{{3,4,5,6},{7,8,10,9},{1,2},{11,12}}    {}
{{3,4,5,6},{7,8,10,9},{11,12}}  {{1,2}}
{{7,8,10,9},{11,12}}    {{1,2},{3,4,5,6}}
{{7,8,10,9,11,12}}  {{1,2},{3,4,5,6}}
{}  {{1,2},{3,4,5,6},{7,8,10,9,11,12}}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5226257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档