WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Zu bereich von Matirx 1 Addieren

 

Amper_Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.10.2013, 12:32     Titel: Zu bereich von Matirx 1 Addieren
  Antworten mit Zitat      
Hallo Leute,

Sollte ich das hier jetzt zum zweiten mal schreiben bitte löschen da ich meinen gerade abgeschickten Eintrag nicht mehr finde.

Ich spar mir mal das ich bin Anfänger und Co.

Folgendes Problem:

Ich möchte eine Art Spiel des Lebens (http://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens) berechnen und als 3D Plot ausgeben. Klappt auch alles so weit ganz gut. Es dauert nur zulange zu berechnen ab 50x50x50 wird es echt langsam und ich denke das 125.000 Zellen nicht zu viel sein sollte.

Ich möchte Berechnen wie viele benachbarte lebende Zellen jede Zelle hat und dann größer und kleiner eines Wertes die Zellen leben lassen oder sterben lassen, Verinfacht:

Anfang:
000000
001000
000100
000000

Ergebnis:
011100
012210
012210
001110

Und dann halt alles z.b. größer 2 und kleiner 5 = 1 der Rest = 0,

Die Funktion dafür sieht wie folgt aus:

Code:

function answer = generation_3d(leben)
 
xy=size(leben);
 
x=xy(1);
y=xy(2);
z=xy(3);
 
leben2(xy(1),xy(2),xy(3))=0;
leben3(x,y)=0;
 
while x>2;    
    x=x-1;    
    while y>2;
        y=y-1;
        while z>2
            z=z-1;
            if leben(x,y,z)==1
       
                leben3(x,y)=1;
                leben3(x+1,y)=1;
                leben3(x-1,y)=1;
                leben3(x,y+1)=1;
                leben3(x,y-1)=1;
                leben3(x+1,y+1)=1;
                leben3(x-1,y+1)=1;
                leben3(x+1,y-1)=1;
                leben3(x-1,y-1)=1;
               
                leben2(:,:,z-1)=leben3(:,:)+leben2(:,:,z-1);
                leben2(:,:,z)  =leben3(:,:)+leben2(:,:,z);
                leben2(:,:,z+1)=leben3(:,:)+leben2(:,:,z+1);
               
                leben3=0;
                leben3(xy(1),xy(2))=0;
            end
        end
        z=xy(3);
    end
   y=xy(2);    
   
end
 
%ränder abschneiden (auf 0 setzte)
leben2(:    ,1    ,:    )=0;
leben2(1    ,:    ,:    )=0;
leben2(xy(1),:    ,:    )=0;
leben2(:    ,xy(2),:    )=0;
leben2(:    ,:    ,1    )=0;
leben2(:    ,:    ,xy(3))=0;
 
answer=leben2;

 


Ach ja wenn noch einer eine Idee hat wie ich eine Matrix x,y,z, zufällig mit x% 1 füllen kann bitte gerne. Wie gesagt was ich hab geht dauert nur zulange.

Danke für die Hilfe und Grüße
Amper


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 09.10.2013, 13:38     Titel: Re: Zu bereich von Matirx 1 Addieren
  Antworten mit Zitat      
Hallo Amper_Gast,

Ich finde die Namen "leben", "leben2" und "leben3" unübersichtlich.
Die als WHILE formulierten FOR-Schleifen sind ebenfalls weniger klar.
Es fehlt noch jegliche Dokumentation. Es ist für einen Leser im forum zunächst mal schwer zu erraten, ob der Input "leben" eine DOUBLE-Matrix oder ein UINT8-3D-Array ist. Bei der Rechengeschwindigkeit kommt es aber darauf an.

Wann immer man code optimieren möchte, sollte man zunächst den Flaschenhals finden. Es wäre ja sinnlos eine Zeile um den Faktor 1000 zu beschleunigen, die nur 1% der Rechenzeit benötigt. Der Profiler dient genau zu diesem zweck (siehe "doc profile").

Ich rate mal, dass "leben3=0; leben3(xy(1),xy(2))=0;" sehr viel Zeit vertrödelt, denn es wird in jeder Iteration eine Matrix im Speicher reserviert und wieder freigegeben. Viel effizienter ist es, die Matrix nur mit Nullen zu füllen: "leben3(:) = 0".

Code:
function leben2 = generation_3d(leben)
 
[nx,ny,nz] = size(leben);
leben2 = zeros(nx,ny,nz);
leben3 = zeros(nx, ny);

for x = 2:nx-1
  for y = 2:ny-1
     for z = 2:nz -1
        if leben(x,y,z) == 1
          leben3(x-1:x+1,y) = 1;
          leben3(x-1:x+1,y+1)=1;
          leben3(x-1:x+1,y-1)=1;
          leben2(:,:,z-1*z+1) = bsxfun(@plus, leben3 + leben2(:,:,z-1:z+1));
          leben3(:) = 0;
        end
     end
  end
end
 
%ränder abschneiden (auf 0 setzte)
leben2([1, nx]   ,:    ,:    )=0;
leben2(:    , [1, ny],:    )=0;
leben2(:    ,:    , [1, nz])=0;

Das wäre ein Punkt, von dem ich starten würde.

Um eine Matrix mit n Einsen an zufälliger Stelle zu füllen, fügt man n Einsen ein und mischt das Array dann:
Code:
n = 13;
M = zeros(4,5,6);
M(1:n) = 1;  % Linear index
M = M(randperm(numel(M));  % Linear Index

% Alternative mit modernen Matlab Versionen:
M(randperm(numel(M), n)) = 1;


"Matrix x,y,z" ist nicht klar: Matrizen haben immer nur 2 Dimensionen.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Amper_Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.10.2013, 14:44     Titel:
  Antworten mit Zitat      
Hallo Jan S,

danke erst mal für die Antwort.

Na ja was die Namensgebung angeht bin ich nicht besonder erfinderrisch deswegen hab ich die einfach durch nummerriert.

der Input ist noch eine Double-3D-Array sollte aber noch auf UINT8-3D geändert werden. Hab ich auch vorhin schon gelesen, dass das helfen soll hat aber noch nicht geklap ist aber ein anders Thema.

WHILE schleifen hab ich genommen da ich die kenne und hinbekommen habe.

Ich probier jetzt mit den Code von dir rum. Und meld mich später noch mal.

Danke
Amper
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.