6

私は、任意の数の文字に対して、ダッシュ文字を使用して主溝と副溝を備えた右利きの DNA 文字列の表現を作成するための優れたアルゴリズムを考え出そうとしています。

これは私が現在持っているもので、 776 を使用しています#:

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

しかし、コピー/貼り付けで手動でらせんを繰り返そうとすると、らせんが完全に整列しません。

上記の例と同じ幅で、塩基対クロスボンド (この画像または下のスカーフ パターンのように) もあるソリューションも許容されます。

スカーフパターン

4

5 に答える 5

6

この質問の鍵は、らせん上の各ストランドを正弦波の組み合わせとして表すことができることを認識することです.1つは周期部分用で、もう1つはページへの「深さ」用です. このように問題をパラメータ化すると、らせんのあらゆる側面を制御できます。以下の例では、 と を使用*#てさまざまなストランドを示し、要点を説明しています。整数値に対応しない波長の値を選択すると、最適な結果が得られなくなりますが、入力を操作して、最も美的に満足できる表現を見つけることができます。

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)

これらの値は次のとおりです。

   *********  #########        
  *********      #########     
 *********         #########   
 *********           ######### 
   *********         ######### 
     *********       ######### 
       *********   #########   
          ****** #########     
              #########        
           ######### ****      
        #########  *********   
     #########      *********  
   #########         ********* 
 #########           ********* 
 #########         *********   
 #########       *********     
   #########   *********       
     ###### *********          
        *********              
      ********* ####           
   *********  #########        
  *********      #########     
 *********         #########   
 *********           ######### 
   *********         ######### 
     *********       ######### 
       *********   #########   
          ****** #########     
              #########        
于 2012-04-23T15:54:17.893 に答える
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 と O は、それが実際に右巻きの螺旋であることを示すためのものです)。

于 2012-04-23T15:30:25.447 に答える
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))

出力:

                ##########  ##########    
             ##########      ##########   
           ##########         ##########  
         ##########           ##########  
       ##########             ##########  
     ##########               ##########  
    ##########               ##########   
  ##########                ##########    
  ##########               ##########     
 ##########               ##########      
 ##########             ##########        
 ##########           ##########          
 ##########         ##########            
  ##########      ##########              
   ##########  ##########                 
    ######## ##########                   
     ##### ##########                     
       # ##########                       
       ########## #                       
     ########## #####                     
    ########## ########                   
  ##########    ##########                
 ##########       ##########              
 ##########         ##########            
 ##########           ##########          
 ##########             ##########        
 ##########               ##########      
  ##########               ##########     
   ##########                ##########   
    ##########                ##########  
     ##########               ##########  
       ##########             ##########  
         ##########           ##########  
           ##########         ##########  
             ##########      ##########   
                ##########  ##########    
                  ######## ##########     
                    ##### ##########      
                      # ##########        
                      ########## #        
                    ########## #####      
                 ########## #########     
               ##########    ##########   
             ##########       ##########  
           ##########         ##########  
         ##########           ##########  
       ##########             ##########  
     ##########               ##########  
    ##########               ##########   
  ##########                ##########    
于 2012-04-23T16:11:09.690 に答える
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)

ただし、出力に特定の数のハッシュを使用するわけではありません。多分これはあなたの要件の1つでした、わかりません...

step値が の整数分数である限り、反復パターンを生成する必要がありmath.piます。

于 2012-04-23T16:00:03.340 に答える
1
                 ########## ####
               ########## ########
             ##########  ###########
           ##########      ##########
         ##########         ##########
       ##########            #########
     ##########              #########
   ##########               ##########
  ##########               ##########
  ##########             ##########
  ##########           ##########
   ##########        ##########
     ###########   ##########
       ######### ##########
         ##### ##########
           # ##########
           ########## ###
         ########## #######
       ##########  ##########
     ##########      ##########
   ##########          ##########
  ##########             ##########
  ##########               ##########
  ##########                 ##########
   ##########                 ##########
     ##########               ##########
       ##########             ##########
         ##########          ##########
           ##########      ##########
             ##########  ##########
               ####### ##########
                 #### #########
                    ######### #

. . .

悲しいことに、それが私の答えの合計になりたかったのです。ただし、説明しておく必要があります。テッセレーションに変更を加える場合、基本的な繰り返し単位を操作する必要があります (テッセレーションの方法を変更する場合は、他の部分を変更する必要がありますが、それは行っていません)。あなたのパターンを繰り返し単位のように見えるものに切り取り、一度コピーして貼り付けました。下に変更を加えたとき、上にも同じ変更を加えました。

<深い考え>あまり考えなくても、最も簡単な解決策が見つかることがあります.</深い考え>

それでも、DNA の画像に対してポスタリゼーション アルゴリズムを実行して、ビットマップに変換することは間違いなく可能です。(著作権のある画像に対してこれを行うことができます。) 同じ文字を使用する義務がない場合は、アスキー アート ジェネレーターを使用することもできます。このジェネレーターは、Web やオープン ソース ソフトウェアで多数見つかります。いくつかのGoogle検索を介して。ただし、これは StackOverflow FAQ の範囲内ではないため、ベクトル スタイルの ascii-art 変換に関するこのコンピューター サイエンスの論文をリンクすることを除いて、詳細には触れません: http://www.cse.cuhk .edu.hk/~ttwong/papers/asciiart/asciiart.pdf

于 2012-04-23T14:52:13.457 に答える