Schleifen wiederholen
Hallo Zusammen.
Ich stoße mittlerweile ein Bisschen an meine Grenzen. Das Problem, ich will über einen Integer einen Wert eingeben, über welchen bestimmt wird, wie oft eine Schleife durchlaufen wird. Diese Schleifen können als Exponenten angesehen werden. Hier ein kleines Beispiel zu der manuellen Lösung des Problems:
Delphi-Quellcode:
Das ist so natürlich überaus unpraktisch. Ich kam nun auf die Idee eine Funktion entsprechend zu erstellen, jedoch bin ich auch nach längerem Überlegen nicht auf eine Lösung gekommen...
for z1 := 1 to 10 do
begin l12 := l11 +0.1; l11 := l11 + 0.1; for z2 := 1 to 10 do begin l13 := l12 + 0.1; l12 := l12 + 0.1; for z3 := 1 to 10 do begin l14 := l13 + 0.1; l13 := l13 + 0.1; for z4 := 1 to 10 do begin l15:= l14 + 0.1; l14:= l14 + 0.1; for z5 := 1 to 10 do .. Noch ein Hinweis, es werden maximal 20 Loops durchlaufen. Hat jemand vielleicht eine Idee? |
AW: Schleifen wiederholen
Warum hast du da tausend einzelne Variablen und kein Array?
|
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Etwas in der Art?
Delphi-Quellcode:
procedure Machwas(AWieoft: Integer);
var LiLooper: Integer; begin for LiLooper := 1 to AWieoft do begin // end; end; |
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Zitat:
Ob man
Delphi-Quellcode:
schreibt oder
l12 := l11 + 0.1
Delphi-Quellcode:
ändert an der Lesbarkeit nicht viel und man kommt dabei auch nicht mehr oder weniger durcheinander.
l[12] := l[11] + 0.1
Aber sei es so, wie du möchtest. Zitat:
Delphi-Quellcode:
Allerdings wird es dann immer noch nicht funktionieren, da deine Schleifen geschachtelt sind. Somit kannst du die Prozedur nicht iterativ aufrufen. Hier hilft meiner Ansicht nach nur ein rekursiver Aufruf, was aber nicht geht, weil du keinen Zähler für die Rekursionstiefe hast. Dafür müsstest du deine Werte in einem Array speichern.
procedure Machwas(AWieoft: Integer; Var L1, L2 : <Dein-Float-Typ>);
var LiLooper: Integer; begin for LiLooper := 1 to AWieoft do begin L1 := L2 + 0.1; L2 := L2 + 0.1; end; end; Also entweder feste Variablenbezeichner für deine Werte und deine geschachtelten Schleifen nehmen oder auf Array umstellen und rekursiv programmieren. Aber vielleicht fällt ja noch jemandem etwas besseres ein. |
AW: Schleifen wiederholen
Zitat:
Ich verzichte nicht im allgemeinen auf Arrays, sondern nur in diesem speziellen Fall. Das Problem sehe ich auch in der Verschachtelung und das ist der Punkt, an dem ich nicht weiterkomme. Nimm es mir bitte nicht übel, aber ich verstehe nicht ganz so viel der Informationstechnik. Ich selber bin auch nur kurzweilig gezwungen mich damit auseinander zusetzten. |
AW: Schleifen wiederholen
Zitat:
Rekursiv heißt, dass du eine Prozedur oder Funktion schreibst, die sich selbst wieder aufruft. Dafür brauchst du ein Kriterium, dass die Rekursion irgendwann abbricht. Bei einem Array könnte es die Arraygröße sein. Bei festen Variablen habe ich spontan keine Idee, wie man das sinnvoll realisieren kann. Daher bleibt nur deine Variante mit der Verschachtelung übrig. |
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Zitat:
OK, Letzteres ist unünstiger, da der Compiler hier nicht schon alles prüfen kann und ein ungültiger Bezeichner erst zur Laufzeit knallen "kann" und natürlich auch die Codevervollständigung hier nicht hilft. |
AW: Schleifen wiederholen
Zitat:
Und es war auch nur als Denkanstoß gedacht, nicht als Komplettlösung. ;-) |
AW: Schleifen wiederholen
Nur mal aus Neugier, passier im inneren der letzten Schleife etwas mit den Variablen oder geht es in der Schleifen-Orgie nur darum die Variablen auf einen bestimmten Wert zu bringen und nachher (außerhalb der Schleifen) wird mit den Variablen weitergerechnet?
|
AW: Schleifen wiederholen
Zitat:
Je schwerer der Balken, desto mehr Halterungen braucht es (Anzahl der Schleifen). Das Problem, ein Balken mit mehr als zwei Halterungen gilt als unbestimmt. Nun gibt es Verfahren, um das zu lösen, aber meine Aufgabe lautet, alle Halterungen sollen in etwas gleich beansprucht werden. Um dies zu erreichen, will ich iterativ die Halterungen ein wenig verschieben und dann so lange rechnen, bis die Halterungen annähernd gleich viel Gewicht aufnehmen. Im inneren der letzten Schleife geschieht dann die Berechnung. |
AW: Schleifen wiederholen
Was Jumpy sagen will, als einfaches Beispiel:
Delphi-Quellcode:
for a := 1 to 10 do
for b := 1 to 20 do i := i + 2; // oder i := i + 20 * 10 * 2; |
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
:roll: Läßt sich das nicht mathematisch lösen? :gruebel:
[***H***|***H***|***H***] Jeder Halter hat dann imho ein Drittel der Last? Oder :gruebel: Die Positionen der Halter lassen sich dann auch ausrechnen. Natürlich braucht man die Gesamtlast und die Länge und die MaxLast eines Halters. |
AW: Schleifen wiederholen
Zitat:
Länge des Brettes durch Anzahl Halterungen sollte dem notwendigen Abstand entsprechen. Es gibt noch Randbedingungen, wie der Abstand zum Rand des Brettes, aber das kann man sicher einbauen. Problematisch wird es erst, wenn das Brett ungleichmäßig schwer ist. |
AW: Schleifen wiederholen
Zitat:
Zitat:
|
AW: Schleifen wiederholen
Zitat:
Auch wenn es logisch klingt, aber die Annahme ist falsch. Wenn es nur so einfach wäre :D. Nicht nur, das die Kräfte immer unterschiedlich verteilt sind, sondern auch die Biegung des Balkens muss berücksichtigt werden. Aber dafür gibt es mich ja :) nur das Implementieren ist mein Problem. |
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
[***H***|***H***|***H***]
Joar, wenn der Balken grade ist und sich nicht biegt, dann passt es ja. Bei Biegen müsstest du aber an den |-Stellen ein Gelenk einbauen*1, da sich die dort zusammenlaufenden Biegungen gegenseitig beeinflussen*2, aber das lässt sich bestimmt auch direkt berechnen, ohne Schleifchen. *1 um diesen Effekt zu eliminieren *2 sich durch das gegenläufige Biegemoment hochheben, während die Enden weiter runter hängen, die äußeren H als Drehpunkt nutzen und die Mitte bissl "leichter" wird. :freak: Kommt blos nicht auf die Idee ein gerades Regal bauen zu wollen, der für eure CNC berechnen zu wollen wie weit sich der Querträger in der Mitte durchbiegen würde. |
AW: Schleifen wiederholen
Ich weiß, spezifischer Ratschlag (oder gar Code) kommt immer besser an, als allgemeiner, aber ich probiere es mal :angel2:
Ein passendes Sprichwort: "In der Informatik gibt es nur drei sinnvolle Maße: 0, 1 oder beliebig viele" (https://de.wikipedia.org/wiki/Zero_One_Infinity) Insofern solltest du hier versuchen, beliebig viele Halterungen zuzulassen. Fassen wir also die Aufgabenstellung zusammen: - Es gibt 1 Brett der Länge l - Es gibt n Halterungen an n Stellen Für letzteres solltest du ein dynamisches Array verwenden. Dann kannst du in deiner Rechnung jeden Punkt separat verschieben. Eine Möglichkeit wäre z.B. sowas:
Delphi-Quellcode:
Nebenbei möchte ich aber anmerken, dass du da ein relativ schlechtes Verfahren implementierst. Du machst noch nicht mal gradient descent, sondern zuppelst jede Dimension um 0.1 (Woher der Wert kommt .... :?: ) und hoffst, dass du damit was erwischst ^^
procedure Vary(Brettdaten: TBrettData; Punkte: Array of Double, idx: Integer);
var AlterWert: Double; begin if (idx > Length(Punkte)) begin Solve(Brettdaten, Punkte) end // Variiere nur einen Punkt hier AlterWert := Punkte[idx]; Punkte[idx] := AlterWert - 0.1; Vary(Brettdaten, Punkte, idx + 1); Punkte[idx] := AlterWert; Vary(Brettdaten, Punkte, idx + 1); Punkte[idx] := AlterWert + 0.1; Vary(Brettdaten, Punkte, idx + 1); end; Ein besseres Verfahren ist gradient descent, wo du für deinen Vektor (also alle n Lager) eine Ableitung berechnest (also wie stark Richtung Optimum bringen mich hier 0.1 ?) und dann in Richtung dieses Gradienten läufst. Und noch besser wird das ganze, wenn du dein Problem in eine gängige Matrix-form bringen kannst, weil dann kannst du auf ungemein viele und gute Löser zurückgreifen. |
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Also ich bin mir nicht mehr ganz sicher, wie ich weiterkommen soll. Ich will mein Problem mal so beschreiben.
Der Sachverhalt lautete wie folgt: Es gibt n Elemente, die auf k Stellen platziert werden können. Bedingung ist, dass sich alles der Reihe nach bewegen muss, also Elemente 1 wird niemals vor Element 2 sein. Hier ein Beispiel mit 5 Elementen und 7 Stellen. *****--- ****-*-- ****--*- ****---* ***-**-- ***-*-*- ***-*--* **-***-- **-**-*- **-**--* *-****-- *-***-*- *-***--* -*****-- -****-*- -****--* -***-**- -***-*-* -**-***- -**-**-* -*-****- -*-***-* usw. Von mir aus, packe ich die Längen auch alle in Arrays rein, aber bezüglich der Kombination bin ich mir unsicher. Um das mal Verbal zu beschreiben: Am Anfang sind alle Halterungen im Abstand von 0,1 m voneinander entfernt. Dann geht die letzte Halterung bis ganz nach außen. Ist sie dort angekommen, dann rück die Vorletzte nach und die letzte Halterung ist wieder 0,1 m von der Vorletzten entfernt und bewegt sich nun nochmal bis ganz nach außen. Dann rückt die Vorvorletzte nach... Leider bekomme ich es nicht hin, dieses logisch Problem zu verpacken... |
AW: Schleifen wiederholen
Zitat:
ich interpretiere mal, dass das mehrere Beispiele waren und in meinem Quote das erste Beispiel zu sehen ist. Dann ist das m.E. ein einfacheres Problem und auch ich würde hier einen (dynamischen) array vorschlagen. Länge des arrays ist dann die Anzahl der Stellplätze. Jeder einzelne Wert ist dann das "Objekt" (oder was auch immer da liegt) Auf das Beispiel von dir bezogen:
Delphi-Quellcode:
Dann hättest du die Vorgabe dafür und musst nur noch eine Routine schreiben, welche die Items (Bei mir die Integer 1-5) beginnend mit dem letztmöglichen verschiebt.
SetLength(myArray, 8);
myArray[0] := 1; myArray[1] := 2; myArray[2] := 3; myArray[3] := 4; myArray[4] := 5; myArray[5] := 0; myArray[6] := 0; myArray[7] := 0; Zumindest, wenn ich deine Aufgabe verstanden habe :) |
AW: Schleifen wiederholen
Zitat:
Da ich vom Fach bin, habe ich mir dazu mal ein paar Gedanken gemacht. Wie wäre es mit einem anderen Lösungsansatz: Du verteilst die Auflager zunächst gleichmäßig unter dem Balken. Damit hast du schon man eine Ausgangslage an Unterschieden in den Auflagerkräften. Dann verschiebst du die Auflager nur noch iterativ, bis alle in etwa die gleiche Auflagerkraft bekommen. Das Auflager mit der geringeren Auflagerkraft rückt näher an das benachbarte Auflager ran. Dann schaust du dir das nächste Feld an und so weiter. Ist die Belastung eigentlich gleichmäßig verteilt? Dann kannst du die Verschiebungen ja gleich symetrisch durchführen. Ich bin mir nicht sicher, ob das in allen Fällen funktioniert, insbesondere bei nicht gleichmäßg verteilter Belastung. Aber vielleicht ist das ein Denkanstoß. |
AW: Schleifen wiederholen
Hi du,
ich würde im ersten Schritt nur die Positionen beachten und die Längen außen vor lassen. Ich würde die Elemente auch nicht positionieren, sondern nur Elemente verteilen und am Ende sagen "das Element ganz links ist Element 1, das daneben 2, ...", damit du die Problematik erstmal aus dem Kopf bekommst. Es bietet sich halt ein Array an mit der angegebenen Länge. Dann halt eine Funktion, welche ein Element platziert. Zunächst muss das erste Element im Bereich 0 bis L-N platziert werden. Nur L-N, da du ja wenigstens Platz für die verbleibenden Elemente benötigst. Danach wechselnd die verbleibenden Elemente aufteilen. Unterm Strich also eine Liste mit allen Möchlichkeiten und dort dann je eine Liste mit den verwendeten Elementen. "Array of Array of Boolean" vielleicht!? Funktion könnte für jeden Durchgang die Liste selbst erweitern, oder du errechnest zuerst die Anzahl der Möglichkeiten und setzt die Listenlänge zuerst. Letztes müsstest du machen, falls du zu viele Variationen hast und du sonst zu oft die Listenlänge neu setzen würdest ... das müsste dann aber schon echt oft sein ... merkst du, wenn dein Programm zu lange braucht ... Arraylängen neu setzen (=Arrays umkopieren) dauert auf dem PC noch mit am Längsten. Im Gegensatz zu meinem Vorgänger wäre das die "einfachere" Brute-Force-Methode. Nur so als Denkanstoß. Ich hoffe das hilft bei der Lösungsfindung. MfG Incocnito |
AW: Schleifen wiederholen
Zitat:
Wenn es so wie bei den Beispielen aussehen soll, könnte ich mir vorstellen dass man Binärzahlen hochzählt. Dann hätte man auch alle Positionen und würde sich so verhalten von rechts nach links. Weiß nicht ob das weiterhilft. |
AW: Schleifen wiederholen
In jedem Fall solltest du die Variation der Zustände von der Berechnung trennen.
Falls die Variationen tatsächlich so diskret sind, sind das ja Kombinationen. Dafür gibt es auch für Delphi einige Beispiele: https://www.delphipraxis.net/194333-...inationen.html Dein erstes Problem wäre dann: => Wie viele Möglichkeiten gibt es, 5 Stützstellen auf 7 Positionen zu verteilen Das zweite Problem: => Gegeben eine Anordnung von Stützstellen, berechne die Lasten Software Entwicklung ist die systematische Zerlegung von Problemen in kleinere Teile, solange bis man sie lösen kann :wink: |
AW: Schleifen wiederholen
Zitat:
Die Belastung ist nicht gleichmäßig verteilt. Die Berechnung soll nach diesem Prinzip(http://www.kulle.at/Statik/Unterlage...k/Statik64.pdf) erfolgen. |
AW: Schleifen wiederholen
Zitat:
|
AW: Schleifen wiederholen
Zitat:
Zitat:
|
AW: Schleifen wiederholen
Zitat:
Das ist schon klar, aber wenn der Computer das alles macht und es nur unwesentlich länger dauert ist es mir egal. |
AW: Schleifen wiederholen
Hallo, ich habe die Bewertungsfunktion nicht angeschaut.
Wenn du zum Beispiel zehn feste Punkte hast, an vier Punkten was reinhängen willst und aufgrund der fest vorgegebenen Punkte lediglich an allen (10 tief 4) möglichen Kombinationen sowie an einer besten Lösung interessiert bist, dann könntest du es so tun.
Delphi-Quellcode:
type TBewertungstyp = integer;
TBrett = record wo : array[0..9] of byte; // hier speichern wir, wo wir was tun: 0=nix tun, 1=was tun anz, pos : integer; // In function bewerte gehen wir brett zum beispiel von links=0 nach rechts=9 durch. pos: da befinden wir uns gerade. anz: so oft haben wir was getan (d.h. wo[i]=1 gesetzt) end; TRes = record br : TBrett; bew : TBewertungstyp; end; function meingebewertungsfunktion( brett : TBrett) : TRes; var hres : TBewertungstyp; begin Result.br := brett; Result.bew := ...; // hier musst du deine Bewertung abhängig von brett.wo einsetzen end; // hier werden alle (n tief k) Kombinationen aufgezählt und bewertet: function bewerte( brett : TBrett ; n, k : integer ) : TRes; var b0, b1 : TRes; begin inc(brett.pos); if ( k-brett.anz > n-brett.pos ) then Result.bew := 0 // Abbruch, da wir noch k-brett.anz Mal was tun müssten, aber nur noch n-brett.pos Postionen frei sind else if brett.anz = k then // k Postionen sind besetzt => auswerten: Result := meingebewertungsfunktion( brett ) // hier werden alle (n tief k) Kombinationen ausgewertet else begin // Fall 1 - an brett.pos nix tun: b0 := bewerte( brett, n, k ); // Fall 2 - an brett.pos was tun: brett.wo[brett.pos] := 1; inc(brett.anz); b1 := bewerte( brett, n, k ); // hier wählst du die bessere variante aus if b0.bew > b1.bew then Result := b0 else Result := b1; end; end; Aufruf:
Delphi-Quellcode:
function loesung_str( loesung : TRes ):string;
var hs : string; begin hs := loesung.bew.ToString + ' : '; for var i := 0 to length( loesung.br.wo )-1 do hs := hs + loesung.br.wo[i].ToString; Result := hs; end; function loesung( n, k : integer ) : TRes; var meinbrett : TBrett; begin // Brett "initialisieren": fillchar(meinbrett.wo[0], n, 0 ); meinbrett.pos := -1; meinbrett.anz := 0; // beste Kombination suchen: Result := bewerte( meinbrett, n, k ); end; procedure TForm29.Button1Click(Sender: TObject); var best : TRes; begin best := loesung( 10, 4 ); showmessage( loesung_str( best ) ); end; |
AW: Schleifen wiederholen
Zumal du differenzieren solltest: Gleichmäßige Belastung der Lager oder des Balken? Bzw. minimalste Belastung der einzelnen Komponenten.
Beispiel Annahme: Der Balken wird von oben gleichmäßig belastet. _****_ > Lager sind gleich stark belastet, der Balken jedoch hat in der Mitte die stärkste Belastung **__** > Lager sind gleich stark belastet, der Balken jedoch hat außen die stärkste Belastung *_**_* > Der Balken hat eine Gleichmäßige Belastung und die Lager auch. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz