C++ Übung



  • CPPler schrieb:

    double x = findMinimum(-100.0, 100.0, 0.0001);

    Das die x-Koordinate gesucht ist, hätte man auch am Beispiel-Code erahnen können. Trotzdem muss ich Euch recht geben, die Aufgabe ist nicht sauber formuliert.

    Der interessante Teil der Aufgabe ist eigentlich, dass evaluate() so selten wie möglich aufgerufen werden soll. Wenn man epsilon nicht als Konstante betrachtet könnte man ein Gradientenabstiegsverfahren implementieren und evt. schneller ans Ziel kommen (in Rechenzeit gesehen). Aber ich fürchte, dass geht zu weit und ist hier nicht gefragt.



  • ich stehe jetzt total aufm Schlauch XD. ich muss von links l nach recht r mit Schritten von epsilon das mache ich einfach mit l += epsilon, dann gebe ich jedes wert in evaluate ein das wäre dann l also evaluate(l); das was rauskommt vergleiche ich mit dem vorherigen also if(min > evaluate(l)) dann min = evaluate;

    die Umsetzung wäre dann bei mir

    double findMinimum(double l, double r, double epsilon)
    {
    double min = 99999999999999999.9, ev;

    for(l; l<=r; l+=epsilon)
    {
    ev = evaluate(l);

    if(ev < min)
    min = ev;
    }

    return min;
    }

    oder mit for Schleife

    double findMinimum(double l, double r, double epsilon)
    {
    double min = 99999999999999999.9, ev, pos = l;

    while(pos <= r)
    {
    ev = evaluate(pos);

    if(ev < min)
    min = ev;

    pos += epsilon;
    }

    return min;
    }

    das was zurückgegeben wird müsste normal die richtige Koordinate sein oder nicht? ich weiß nicht was ich sonst zurückgeben müsste 😕



  • "Ist [der Funktionswert] nicht kleiner, bist du fertig."
    Nicht: "Ist [der Funktionswert] nicht kleiner, laufe ich trotzdem bis r durch."

    Und was ist unklar an X vs Y?

    Und bitte benutze C++-Tags.

    Und bitte schalte Warnungen ein. Das hier:

    for(l; l<=r; l+=epsilon)
    

    sollte warnen... (auch wenn es so trotzdem richtig funktioniert).



  • Wie in den meisten fällen, gilt auch hier:

    y=f(x)y=f(x)

    Was ist dein f, was ist dein, x, was dein y und was wird als Rückgabe erwartet?



  • hmm ich hatte den Text total falsch verstanden, ich hatte den Text irgendwann gelesen und mich dann auf die Aufgabe irgendwann anders rangemacht XD. Ich Danke Euch für die nützlichen Tipps, ich werde mich am Wochenende die Aufgabe versuchen fertigzumachen (muss jetzt arbeiten^^). Nochmals vielen Dank an Alle! 👍



  • Hey Leute, Dank eure Hilfe habe ich das erste Teil gelöst und wollte mich heute an das zweite Teil ranmachen, aber schon wieder verstehe ich nicht was von mir verlangt ist. Die Aufgabenstellung:

    Die zweite Funktion

    double findMinimum2(double x1, double x4, double epsilon)

    implementiert eine Iteration mit Hilfe von vier Werten x1, x2, x3, x4, wobei
    x2 = x1 + (x4 − x1) ⋅ 0.38196601 und x3 = x1 + (x4 − x1) ⋅ 0.61803399 sein soll. Es sei nun y2 der
    Funktionswert an der Stelle x2, und y3 analog. Je nachdem, ob y2 < y3 ist, werden die vier Werte auf
    folgende Weise neu gesetzt:
    (Hier kommt ein Bild welches Ihr euch im Link ansehen könnt)
    https://einfprog.cosy.sbg.ac.at/content-angabeblaetter.html?show=4

    Dabei kommt jeweils ein neuer Wert hinzu, der nach obigen Formeln ermittelt wird. Das wird wiederholt,
    bis beide Abstände x3 − x2 und | y3 − y2 | kleiner als ε werden.

    Auch hier soll evaluate so selten wie möglich aufgerufen werden. Der Test

    init(1.0, 2.0, 3.0);
    double x = findMinimum2(-100.0, 100.0, 0.0001);
    std::cout << getCount() << " " << x << std::endl;

    sollte 30 -1.0000697 ergeben.

    mein Code sieht bisher so aus:

    double findMinimum2(double x1, double x4, double epsilon) 
    {
    	double l1 = x1, l2 = x1, y2, y3;
    	double x2 = x1 + (x4 - x1) * 0.38196601, x3 = x1 + (x4 - x1) * 0.61803399;
    
    	while(x3-x2 && fabs(y3 - y2) > epsilon)
    	{
    		for(l1; l1<=x2; l1 += epsilon)
    		{
    			evaluate(l1);
    		}
    		y2 = l1;
    
    		for(l2; l2<=x2; l2 += epsilon)
    		{
    			evaluate(l2);
    		}
    		y3 = l2;
    
    		if(y2 < y3)
    		{
    
    		}
    	}
    
    	return ;
    }
    

    wobei ich mir sicher bin dass es komplett falsch ist, ich hoffe auf Aufklärung, vielen Dank 🙂 !


  • Mod

    Es wäre ein Anfang, wenn du vielleicht auch was tust, mit den Ergebnissen deiner Rechnung.

    Ansonsten: Was genau ist deine Frage? Verstehst du die Aufgabe nicht?



  • 1. Überleg dir mal, was das hier bedeutet:

    while(x3-x2 && fabs(y3 - y2) > epsilon)
    

    Hinweis: eine double-Variable d ist genau dann wahr, wenn d==0 gilt.

    2. Wer hat dir dieses Pattern beigebracht?

    double d = start;
    // viel code
    // ...
    // noch mehr code
    for (d; d < irgendwas; d += irgendwas) ...
    

    Ich habe dir schon einmal geschrieben, dass du hier eine Warnung erhalten solltest - nämlich die, dass d eine ungenutzte Variable vor dem ersten Bereich der for-Schleife ist.

    Gewöhn dir an, die Schleifenvariable erst in der Schleife zu erstellen:

    for (double d = start; d < ende; d += irgendwas) ...
    

    Und mach nicht zu viel in einer Zeile. Dies hier ist total unübersichtlich:

    double l1 = x1, l2 = x1, y2, y3;
        double x2 = x1 + (x4 - x1) * 0.38196601, x3 = x1 + (x4 - x1) * 0.61803399;
    

    Besser:

    double x2 = x1 + (x4 - x1) * 0.38196601;
        double x3 = x1 + (x4 - x1) * 0.61803399;
    

    Die anderen Variablen brauchst du dort noch gar nicht. Vor allem erstelle nicht einfach irgendwelche Variablen, die du nicht initialisierst wie y2 und y2. Im while fragst du gleich als erstes, ob fabs(y3 - y2) > epsilon - aber da sind y2 und y3 noch nicht initialisiert!

    Du rufst zwar evaluate mehrmals in irgendwelchen Schleifen auf, aber du machst nichts mit dem Ergebnis... Denk mal drüber nach, ob du nicht doch wissen willst, was rauskommt...



  • Ich glaube der Trick ist, dass du den Abstand immer halbierst, bis er ε erreicht hat. Und weil die Funktion linear ist, kannst du in jedem Schritt die Richtung einfach umschalten, um dich dem Ziel zu nähern.

    Mein naiver Ansatz:

    abstand: s = length/epsilon 
       y1 = f(x), y2 = f(x+s)
    loop:
       s_halb = s/2
       wenn s_halb <= epsilon dann fertig!
       wenn y2 > y1 dann y3 = f(x+s-s_halb) 
           sonst wenn y2 < y1 dann y3 = f(x+s+s_halb)
       y1 = y2, y2 = y3, s = s_halb
       goto loop
    

  • Mod

    Andromeda schrieb:

    Ich glaube der Trick ist,

    Hier gibt es keine Tricks. Die Aufgabe nimmt einen doch Schritt für Schritt am Händchen und sagt genau, was wann zu tun ist. Man braucht nicht selbst zu denken, sondern muss einfach nur Deutsch nach C++ übersetzen. Malen Programmieren nach Zahlen!

    PS: Die Funktion ist nicht linear!



  • Zur Entspannung und Zerstreuung: 🙂
    https://en.wikipedia.org/wiki/Golden-section_search



  • SeppJ schrieb:

    PS: Die Funktion ist nicht linear!

    Stimmt, Sorry. 😞



  • Zuallererst die Funktion war nicht ganz fertig, ich habe sie trotzdem gepostet, weil ich nicht wusste was ich wo eingeben und wo ich was rausgeben soll und beim return wusste ich nicht mal nach welcher variable gefragt worden ist.

    @SeppJ, das Erste was ich nicht verstehe ist, "Es sei nun y2 der
    Funktionswert an der Stelle x2", soviel ich weiß sind doch die Funktionswerte das was eine Funktion zurückgibt, bei Teil 1 war es aber der Parameter, der gemeint war. Das zweite was genau ist gemeint y2 an der Stelle x2? Ist das damit gemeint das wenn ich bei evaluate an der Stelle ankomme welches x2 entspricht, dass dann y2 das ist was ich an dieser Stelle evaluate übergeben habe?
    Und von zu dem mit einfach von Deutsch nach C++ übersetzen: egal wie gut du Deutsch sprechen kannst wenn du etwas in eine andere sprache übersetzten musst, musst du auch dieses können und in C++ bin ich ein Neuling 😉

    @wob, 1. Das sollte eher so aussehen:

    while(x3-x2 > epsilon && fabs(y3 - y2) > epsilon)
    

    aber ja, ich denke das ist "weniger falsch" aber immer noch nicht richtig

    2. Das habe ich mir irgendwie selber angewöhnt, normalerweise wird immer double i; i<0, i++ etc. eingegeben aber es kommt vor dass man keine variable extra erzeugen muss sondern bestehende "verwerten kann", war in dem Fall nicht so, da wie du schon geschrieben hast, ich ungenutzte Variablen genutzt habe.

    3. Ich habe die Variable benutzt und dann initialisiert, das war sehr unbedacht.

    Ich glaub mittlerweile es hat kein Sinn die Übungen von der Uni zu machen da man ja normalerweise die Aufgaben nach Vorlesung gerichtet bekommt, da ich nicht weiß was die durchnehmen weiß ich auch nicht was mit den Zeichnungen gemeint ist.



  • Mit evaluate berechnest du den Funktionswert an einer bestimmten Stelle.

    Also z.B. sowas:

    double y2 = evaluate(x2);
    

    Du hast bei dem ersten Teil der Aufgabe geschrieben, dass du die Uni nicht besuchst sondern dir nur die Aufgaben holst. Ich denke, hier liegt das grundlegende Problem. Wenn es sich um Übungen aus einem Informatik Studium hanldelt haben die neben den "handwerklichen" Programmiervorlesungen auch einen ganzen haufen Mathematik Vorlesungen. Und ich habe das Gefühl, dass dir das notwendige mathematische Verständnis fehlt um mit den Aufgaben klar zu kommen.

    Besorg dir lieber ein gutes Buch und mach die Aufgaben daraus. Die sind dann auch entsprechend gestellt und nicht unbedingt auf mathematische Probleme beschränkt, die man erstmal verstehen muss.

    Zu deinem "while" noch ganz kurz. Setz Klammern um die entsprechenden Ausdrücke, damit die Reihenfolge der Auswertung klar wird. Oder weist du ohne nachzugucken, ob erst ">" oder erst "&&" ausgewertet wird.

    Und double als Laufvariablen sind auch eher ungewöhnlich und würde ich versuchen zu vermeiden, als kleiner Denkanstoß.


  • Mod

    CPPler schrieb:

    Und von zu dem mit einfach von Deutsch nach C++ übersetzen: egal wie gut du Deutsch sprechen kannst wenn du etwas in eine andere sprache übersetzten musst, musst du auch dieses können und in C++ bin ich ein Neuling 😉

    Ich wollte damit vor allem betonen, dass man hier nicht selber zu planen braucht (wie Andromeda es versuchte), sondern nur Schritt für Schritt der Anleitung folgen muss. Ja, dafür muss man C++ können, es ist schließlich eine Lehraufgabe für C++ 🙂



  • SeppJ schrieb:

    Ja, dafür muss man C++ können, es ist schließlich eine Lehraufgabe für C++ 🙂

    Hm, warum haben dann in der Aufabe alle Funktionen Signaturen, die nach Java aussehen und warum heißen die Beispieldateien etwa "Function.java"? In C++ heißt Function.evaluate(x) auch Function::evaluate(x);
    Das ist hier vielleicht noch recht egal, aber spätestens bei fortgeschritteneren Dingen wäre es vielleicht sinnvoll, C++ mit einem C++-Kurs statt einem Java-Kurs zu lernen 😉



  • Am mathematischen Verständnis wird es wahrscheinlich nicht liegen, da ich eigentlich recht gut in mathe bin . Ich denke es liegt einfach nur daran dass ich noch sehr frisch in der Programmierwelt bin und ich einfach keine meinem Level entsprechende Übungen habe. Das Videotraining was ich hatte war auch ziemlich schlecht muss ich sagen. Aber was vielleicht das Ausschlaggebende sein könnte ist, dass ich einfach nicht die Zeit finde mich hinzusetzen und über etwas längere Zeit nachzudenken. Das könnten auch nur Ausreden sein, aber ich bleib trotzdem am Ball. Euch vielen Dank für eure hilfreichen Antworten 🙂



  • Hey ich hätte noch eine letzte Frage XD. ich habe jetzt vier Bücher vor mir liegen und ich weiß nicht in welcher Reihenfolge ich anfangen soll.
    Bücher: Der C++ Programmierer von Ulrich Breymann, Die C++ Programmiersprache von Stroustrup. Grundstudium Mathematik (Lineare Algebra 1 und 2, Analysis 1 und 2) und (Hoch-)Schulmathematik (das ist so ein Zwischending von Gymnasium zu Uni).

    Ich weiß man braucht für Programmieren viel Mathematik und es wäre ratsam erst mit mathe anzufangen, jedoch bin ich recht gut in mathe (was ich hier nicht unter Beweis stellen konnte XD) und würde gleich mit dem Programmieren anfangen wollen.

    Deshalb wäre meine Idee:

    1. Der C++ Programmierer von Ulrich Breymann
    2. (Hoch-)Schulmathematik
    3. Grundstudium Mathematik
    4. Die C++ Programmiersprache von Stroustrup

    Begründung: Ich denke für Ulrich Breymann reichen meine Vorkenntnisse und ich kann gleich mit dem Programmieren anfangen und zu Beginn meines Studiums kann ich vielleicht ein Studentenjob als Programmierer ergattern.
    Dann würde ich Richtung "Grundstudium Mathematik" gehen mit dem kleinen Umweg über "(Hoch-)Schulmathematik" (für den leichteren einstieg). Und dann wieder zurück zum Programmieren mit "Die Programmiersprache" um das gelernte weider zu aufzufrischen und gegebenenfalls zu vertiefen.

    Ich bin aber noch unsicher weil die Reihenfolge normalerweise die richtigere wäre:

    1. (Hoch-)Schulmathematik
    2. Grundstudium Mathematik
    3. Der C++ Programmierer von Ulrich Breymann
    4. Die C++ Programmiersprache von Stroustrup

    Was würdet Ihr mir raten? Ich war euch dankbar für Eure Antworten und werde auch für kommende Antworten dankbar sein 😃 😃 😃 🙂


  • Mod

    Du brauchst zum Programmieren keine Hochschulmathematik.



  • Hier findest du eine Buchsammlung rund um C++ mit kurzer Rezension und Einordnung für wen die Bücher geeignet sind.

    Wenn du die, von genannten, Bücher eh da hast, fang mit "der C++ Programmierer" an. Ich habe das Buch zwar nicht, aber es wurde hier im Forum schon an verschiedenen Stellen empfohlen.

    Die Mathematikbücher würde ich erstmal links liegen lassen. Meine Anspielung auf mathematisches Verständnis bezog sich darauf, dass du dir Übungen aus einem Informatikstudium gezogen hast und ein Informatik Studium zum großteil aus Mathematik besteht. Aber Informatik != Programmieren.
    Wenn du Programmieren kannst, kommt es auf die Probleme an, die du lösen möchtest, ob du dir da noch mehr drauf schaffen musst.

    Wenn du an Hochschulmathematik Spaß hast, hau rein. Aber ich glaube, um sich das autodidaktisch anzueignen braucht man eine leicht masochistische Veranlagung 😃


Anmelden zum Antworten