2012-04-23 110 views
6

我試圖想出一個好的算法來創建right handed DNA串用破折號字符,字符任意數量的主要和次要凹槽的表示。雙螺旋生成算法

這是我目前擁有,使用776 #的:

#########     ########## 
    #########    ########## 
     #########    ########## 
     #########   ########## 
      ##########  ########## 
      ########## ########## 
       ###### ########## 
       ## ########## 
       ########## # 
       ########## ##### 
      ########## ######### 
      ########## ########## 
     ##########  ########## 
     ##########   ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########   ########## 
    ##########  ########## 
    ########### ########## 
     ######### ########## 
     ##### ########## 
      # ########## 
      ########## ### 
     ########## ####### 
     ########## ########## 
    ##########  ########## 
    ##########   ########## 
    ##########    ########## 
    ##########    ########## 
    ##########     ########## 
    ##########     ########## 
    ##########    ########## 
     ##########    ########## 
     ##########   ########## 
      ##########  ########## 
      ########## ########## 
       ####### ########## 
       #### ######### 
        ######### # 
        ########## ### 
       ########### ####### 

但是當我嘗試手動通過複製/粘貼重複螺旋螺旋不完全一致。

與上述示例具有相同寬度但也具有底層交叉粘結(如this image或下面的圍巾圖案)的解決方案也是可以接受的。

scarf pattern

+4

你爲什麼不張貼到現在爲止您編寫的代碼?它可能會鼓勵人們回答。 – user1202136 2012-04-23 14:42:25

+0

上面的例子是手動完成的。但是這種調整是費力和錯誤的,所以我認爲必須有更好,更算法的方法來做到這一點。 – BioGeek 2012-04-23 14:45:22

回答

6

的關鍵,這個問題是要認識到,你可以代表對耳輪爲正弦波的組合每一條鏈 - 一個用於週期性的部分,以及一個用於「深度」進入頁面。一旦你參數的問題,這樣一來,你可以控制你的螺旋的各個方面。下面的示例使用*#以顯示不同鏈說明這一點。如果你選擇的是不相稱的整數值的波長值,你會得到不到最佳的效果 - 但現在你可以輸入發揮找到你認爲最美觀的表示。

from numpy import * 

amp = 10 
length = 100 
wavelength = 20 

omega = (2*pi)/wavelength 
phi = wavelength*(0.5) 
X = arange(1,length) 
Y1 = round_(amp*(sin(omega*X) + 1)) 
Y2 = round_(amp*(sin(omega*X+phi) + 1)) 

offset = phi/2 
Z1 = sin(omega*X + offset) 
Z2 = sin(omega*X + phi + offset) 

T1 = " ######### " 
T2 = " ********* " 
clen = len(T1) 

H = zeros((length,amp*2+clen),dtype='str') 
H[:,:] = " " 

for n,(y1,y2,z1,z2) in enumerate(zip(Y1,Y2,Z1,Z2)): 
    H[n,y1:y1+clen] = list(T1) 
    H[n,y2:y2+clen] = list(T2) 

    # Overwrite if first helix is on top 
    if z1>z2: H[n,y1:y1+clen] = list(T1) 

for line in H: 
    print "".join(line) 

這些值給出:

********* #########   
    *********  #########  
*********   ######### 
*********   ######### 
    *********   ######### 
    *********  ######### 
     ********* ######### 
      ****** #########  
       #########   
      ######### ****  
     ######### ********* 
    #########  ********* 
    #########   ********* 
#########   ********* 
#########   ********* 
#########  *********  
    ######### *********  
    ###### *********   
     *********    
     ********* ####   
    ********* #########   
    *********  #########  
*********   ######### 
*********   ######### 
    *********   ######### 
    *********  ######### 
     ********* ######### 
      ****** #########  
       #########   
+1

在線19上,不清楚哪個線在哪個線上。每一個都出現在另一個之後。 – recursive 2012-04-23 16:30:51

+1

@recursive同意,在z順序上添加一個簡單的偏移量來修復這個問題。他們需要使各自相位的z階移動半個波長。謝謝! – Hooked 2012-04-23 17:40:53

1
    ########## #### 
       ########## ######## 
      ########## ########### 
      ##########  ########## 
     ##########   ########## 
     ##########   ######### 
    ##########    ######### 
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########   ########## 
    ##########  ########## 
    ########### ########## 
     ######### ########## 
     ##### ########## 
      # ########## 
      ########## ### 
     ########## ####### 
     ########## ########## 
    ##########  ########## 
    ##########   ########## 
    ##########    ########## 
    ##########    ########## 
    ##########     ########## 
    ##########     ########## 
    ##########    ########## 
     ##########    ########## 
     ##########   ########## 
      ##########  ########## 
      ########## ########## 
       ####### ########## 
       #### ######### 
        ######### # 

。 。 。

可悲的是,我想這是總和我的回答。但是,我要說明一下:當您執行變更tesselations,你需要的基本重複單元的工作(如果你修改tesselates的方式,你必須修改它的其他部分,但你沒有這樣做)。我砍你的模式成什麼樣我想看起來像一個重複單元,然後複製粘貼一次;當我對底部做出改變時,我對頂部做了同樣的改變。

<濃濃的思念>有時候最簡單的解決方案,而無需過多的思考中。 < /深層次的想法>

儘管如此,你絕對可以對DNA圖像執行後調算法,將其轉化爲位圖。 (你可以做到這一點給你的。版權的圖像)如果你不感激使用相同的字符,你也可以使用一個ASCII藝術發生器,其中你可以找到幾十個在網絡上和開源軟件通過一些谷歌搜索。但是,這並不在StackOverflow常見問題解答的範圍內,所以我不會詳細討論這方面的細節,除了將此計算機科學論文鏈接到矢量風格的ASCII藝術轉換之外:http://www.cse.cuhk.edu.hk/~ttwong/papers/asciiart/asciiart.pdf

+1

如果不需要通過算法創建,這當然是最簡單的方法。 – 2012-04-23 14:54:11

2

這應該給你一個體面的開始:

from math import sin, cos, pi 

class RightHelix(object): 
    def __init__(self, maxima, minima, period, offset): 
     self.mid = 0.5 * (maxima + minima) 
     self.mag = 0.5 * (maxima - minima) 
     self.k = 2.0 * pi/period 
     self.offs = self.k * offset 
    def x(self, t): 
     return self.mid + self.mag * sin(self.k*t - self.offs) 
    def y(self, t): 
     return -self.mag * cos(self.k*t - self.offs) 

def main(): 
    rh = RightHelix(33, 7, 20, -2) 

    for t in range(40): 
     x,y = rh.x(t), rh.y(t) 
     print(' '*int(x-0.5) + ('O','X')[y>0]) 

if __name__=="__main__": 
    main() 

給出,生產

      O 
           O 
           O 
           O 
           X 
           X 
          X 
         X 
        X 
       X 
      X 
     X 
     X 
     X 
     O 
     O 
      O 
       O 
        O 
         O 
          O 
           O 
           O 
           O 
           X 
           X 
          X 
         X 
        X 
       X 
      X 
     X 
     X 
     X 
     O 
     O 
      O 
       O 
        O 
         O 

(X們和OS只是表明它確實是一個右手螺旋)。

2

這個怎麼樣:

import math 

phaseA = math.pi/1.5 
phaseB = 0 
step = math.pi/20 
width = 30 # screen size 
breadth = 8 # breadth of DNA single string 

x = 0.0 
while True: 
    x += step 
    if x > 30.0: break 
    yA = math.sin(x + phaseA) 
    zA = math.cos(x + phaseA) 
    yB = math.sin(x + phaseB) 
    zB = math.cos(x + phaseB) 
    if zA > zB: # which is in front? 
    yTop, yBottom = yA, yB 
    else: 
    yTop, yBottom = yB, yA 
    # screenify values: 
    yTop = 1 + int((1.0 + yTop) /2.0 * (width-breadth)) 
    yBottom = 1 + int((1.0 + yBottom)/2.0 * (width-breadth)) 
    line = ' ' * yBottom + '#' * breadth + ' ' * (width-yBottom) 
    line = list(line) # make mutable 
    line[yTop-1] = ' ' 
    line[yTop+breadth+1] = ' ' 
    for i in range(breadth): 
    line[yTop+i] = '#' 
    print ''.join(line) 

它不使用散列對輸出的具體數量,但。也許這是你們中的一個要求,不知道...

只要step值是math.pi的整數部分,它就會產生重複模式。

2

這是我的方法。這可能與其他人沒有本質區別,但是我寫了它,所以這裏寫着:

上半部分是配置。下半部分是行動。

from math import cos, sin, pi 

length = 50 
width = 30 
thickness = 10 
rotation = 0.15 
strands = [0, 2 * pi/3] 
strand_char = "#" 

radius = width/2 
for line in range(length): 
    output = [" "] * (width + thickness + 2) 
    total_rotation = -line * rotation 
    sorted_strands = sorted(strands, key=lambda s: cos(total_rotation + s)) 
    for strand_offset in sorted_strands: 
     pos = int(radius * sin(total_rotation + strand_offset) + radius) 
     output[pos : pos + thickness + 2] = " " + strand_char * thickness + " " 
    print("".join(output)) 

輸出:

   ########## ##########  
      ##########  ########## 
      ##########   ########## 
     ##########   ########## 
     ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ##########  
    ##########    ##########  
##########    ##########  
##########    ##########   
##########   ##########   
##########   ##########    
    ##########  ##########    
    ########## ##########     
    ######## ##########     
    ##### ##########      
     # ##########      
     ########## #      
    ########## #####      
    ########## ########     
    ########## ##########     
##########  ##########    
##########   ##########    
##########   ##########   
##########    ##########   
##########    ##########  
    ##########    ##########  
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
     ##########    ########## 
     ##########   ########## 
      ##########   ########## 
      ##########  ########## 
       ########## ##########  
        ######## ##########  
        ##### ##########  
         # ##########   
         ########## #   
        ########## #####  
       ########## #########  
       ########## ########## 
      ##########  ########## 
      ##########   ########## 
     ##########   ########## 
     ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ##########  
+1

請注意,這是一個左手螺旋... – 2012-04-23 16:23:13

+0

感謝您的更正。我已經扭轉了代碼中的旋轉。 – recursive 2012-04-23 16:25:20