Beim Einrichten von for-Schleifen möchte ich in der Lage sein, eine unbekannte Anzahl von Parametern zu durchlaufen.
Durch eine Eingabedatei kann der Benutzer so viele oder so wenige Schleifenparameter einrichten, wie er möchte, und ich möchte in der Lage sein, diese unabhängig von der Anzahl der von ihnen eingerichteten Parameter zu durchlaufen. Loop Input Beispiel: (Beachten Sie, dass meine Eingaben auch Listen von Strings und Zahlenkombinationen sein können)
Fall 1:
- Gewicht 45000: 5000: 75000
- Höhe 10000
- Geschwindigkeit 0.2: 0.1: 0.9
Fall 2:
- Gewicht 30000
- Höhe 1000: 1000: 10000
- Klappen 10, 20
- Temperatur -10: 1: 10
Die Länge der Liste kann unterschiedlich sein und kann zwischen 0 und 15 Variablen enthalten. Ich kenne die Problemumgehung, aber es ist wirklich chaotisch, eine Reihe von geschachtelten for-Schleifen dafür zu verwenden. Ich suche nach einer Möglichkeit, eine Methode einzurichten, vielleicht mit Rekursion, wo der Code unabhängig von der Anzahl der beteiligten Parameter ein geeignetes For-Loop-System einrichtet und immer noch diese Variablen im Auge behält.
Rekursion.
Sie haben hier keine Geschwindigkeitsanforderungen gestellt. Diese Antwort ist langsam, verwendet Speicher schlecht, aber ist die einfachste mögliche Umsetzung dieser Idee. Es gibt viele bessere Implementierungen, die komplizierter sind, viel weniger Speicher benötigen und wesentlich schneller sind. Kommt darauf an, wie eng die inneren Schleifen sein müssen ...
%Vor%Definieren Sie dann Ihren Simulator als etwas wie:
%Vor%Die Codegenerierungslösung
Nun, Sie haben bereits eine Reihe von ziemlich guten Lösungen. Ich werde nur einen hineinwerfen, der Code-Generierung beinhaltet. MATLAB hat nicht wirklich viel von diesen Tools, aber Sie können es mit ein paar Loops und fprintf
vortäuschen. Hier ist mein Codegenerierungsskript:
Generierter Code ( thisrun.m
):
Ergebnis der Ausführung generierten Codes:
%Vor%Die Codegenerierung benötigt Zeit, aber wenn Sie die Datei mehrmals ausführen müssen, ist dies möglicherweise immer noch eine effiziente Lösung.
Das Ausführen von verschachtelten for
-Schleifen für alle Parameter ist die einfache Lösung, konstante Parameter führen einfach zu einer einzelnen Iteration für diese spezifische Schleife.
Sie können auch ndgrid
verwenden, um einen Satz mehrdimensionaler Arrays zu erstellen sind die Parameter für jeden Aufruf von computeFunction(...)
und iterieren über die ngrid's
-Ausgabe, anstatt verschachtelte for-Schleifen für jeden potenziell variablen Parameter zu erstellen, wenn Sie die Anzahl der Parameter ändern möchten.
Beachten Sie jedoch, dass es zu einem höheren Preis kommen kann. Je nachdem, was genau Sie in welcher Matlab-Version tun, profitiert es möglicherweise nicht von den integrierten Optimierungen, die die 'einfache' for-loop-Version erhält.
Hier ist eine rekursive Funktion, die alle möglichen Sätze von Parametern als Spaltenvektoren eines Arrays erzeugt:
%Vor% Beispielausgabe: Schleife über 5:7
, dann 8
, dann [2,3,5,7]
:
Die Ausgabe entspricht der von ndgrid
(außer meiner Meinung nach intuitiver gestaltet). (Auch einige vorläufige Benchmarks zeigten, dass dies etwas schneller sein könnte als ndgrid
...?! Zu bestimmen)
Hauptschleife: Verwenden Sie jetzt nur eine Schleife, um die Spalten von idx
zu durchlaufen. Beachten Sie, dass dieses Lösungskonzept ähnlich zu ist Lösung , wie von @ Daniel auf dem OP kommentiert.
EDIT: um sowohl String- als auch numerische Eingaben zu verarbeiten
Ein einfacher Mod zu der ursprünglichen rekursiven Funktion, die ich gepostet habe, erlaubt es, Indizes anstelle von tatsächlichen Elementen zurückzugeben, so dass String-Zellen in Ordnung sind:
%Vor%Alles in allem würde Ihre Funktion vermutlich so funktionieren:
%Vor% wobei die Funktion numORcell
die numerischen Daten im Vergleich zu den Zellen korrekt analysiert:
Beispiel mit Zeichenfolgen:
%Vor%oder stattdessen:
%Vor% Übung, die dem Leser überlassen wird: Wenn das Speichern aller Indizes in idx
ein Speicherproblem darstellt, müssen Sie einige ziemlich schwere Schleifen durchführen. Nichtsdestoweniger können Sie eine Funktion erstellen, die aus dem aktuellen Index den nächsten lexikografischen Indexsatz bestimmt, dh Sie müssten nur einen Satz Indizes speichern und am Ende jeder Schleife iterieren.