2014-11-24 13 views
5

Mi piacerebbe modificare un mio script Python che funziona su un reticolo quadrato (è un modello basato su agenti per la biologia), per lavorare in un universo esagonale.Generare, riempire e tracciare un reticolo esagonale in Python

Ecco come creare e inizializzare la matrice 2D nel modello quadrato: in pratica, N è la dimensione del reticolo e R indica il raggio della parte della matrice in cui è necessario modificare il valore all'inizio del algoritmo:

a = np.zeros(shape=(N,N)) 
center = N/2 

for i in xrange(N): 
    for j in xrange(N): 
     if((pow((i-center),2) + pow((j-center),2)) < pow(R,2)): 
      a[i,j] = 1 

ho poi lascio la matrice evolvere in base alle leggi certains e infine stampare tramite la creazione di un file di salamoia:

name = "{0}-{1}-{2}-{3}-{4}.pickle".format(R, A1, A2, B1, B2) 
pickle.dump(a, open(name,"w")) 

Ora, vorrei fare esattamente lo stesso, ma su un reticolo esagonale. Ho letto this interessante domanda StackOverflow che chiarite come rappresentare le posizioni su un reticolo esagonale con tre coordinate, ma un paio di cose rimangono oscure, a mia conoscenza, vale a dire

(a) come dovrei trattare con i tre assi in Python , considerando che ciò che voglio non è equivalente a una matrice 3D, a causa dei vincoli sulle coordinate, e

(b) come tracciarlo?

Per quanto riguarda (a), questo è quello che stavo cercando di fare:

a = np.zeros(shape=(N,N,N)) 

for i in xrange(N/2-R, N/2+R+1): 
    for j in xrange(N/2-R, N/2+R+1): 
     for k in xrange(N/2-R, N/2+R+1): 
      if((abs(i)+abs(j)+abs(k))/2 <= 3*N/4+R/2): 
       a[i,j,k] = 1 

Mi sembra abbastanza contorto per inizializzare una matrice NxNxN del genere e poi trovare un modo per stampare un sottoinsieme di esso in base ai vincoli sulle coordinate. Sto cercando un modo più semplice e, cosa più importante, per capire come tracciare il reticolo esagonale risultante dall'algoritmo (non ho idea di ciò, non ho ancora provato nulla per il momento).

risposta

3

Concordo sul fatto che provare a calzare un reticolo esagonale in un cubico è problematico. Il mio suggerimento è di usare uno schema generale - rappresentare i siti vicini come un grafico. Funziona molto bene con l'oggetto dizionario Python e è banale implementare lo "schema di coordinate assiali" in uno dei collegamenti che hai fornito. Ecco un esempio che crea e disegna il "reticolo" usando networkx.

import networkx as nx 
G = nx.Graph(directed=False) 
G.add_node((0,0)) 

for n in xrange(4): 
    for (q,r) in G.nodes(): 
     G.add_edge((q,r),(q,r-1)) 
     G.add_edge((q,r),(q-1,r)) 
     G.add_edge((q,r),(q-1,r+1)) 
     G.add_edge((q,r),(q,r+1)) 
     G.add_edge((q,r),(q+1,r-1)) 
     G.add_edge((q,r),(q+1,r)) 

pos = nx.graphviz_layout(G,prog="neato") 
nx.draw(G,pos,alpha=.75) 

import pylab as plt 
plt.axis('equal') 
plt.show() 

enter image description here

Questo non è l'implementazione più ottimale ma può generare arbitrariamente grandi reticoli:

enter image description here

Problemi correlati