# Simulation Karpfenteich



## WTFProoF (22. Mrz 2011)

Hallo ihr Nerds! :bae:

Mein erster Post hier und schon stell ich Forderungen, fängt ja gut an...

Also, ich habe in meinem Informatikunterricht (Gymnasium Einführungsphase) gerade das Thema Java, es gefällt mir und fällt mir auch rellativ leicht. Nur haben wir jetzt bis Morgen eine Hausaufgabe bekommen, die ich einfach nicht hinkriege. Ihr Wortlaut ist:



> In einem Teich leben anfangs A = 50 Karpfen. Platz ist für höchstens H = 350 vorhanden. Die Forellen vermehren sich jährlich mit einer Rate von 6% der Differenz zwischen Höchstbestand H und aktuellem Bestand A. Wie entwickelt sich die Population?
> a) ohne äußere Einwirkungen
> b) wenn am Ende jedes Jahres 20% des Bestandes entnommen werden?
> Schreibe dazu ein Simulationsprogramm.



Nun habe ich einfach mal keine Idee wie ich das umsetzen soll. Vielleicht kann mir ja einer hier schnell helfen. Ich brauche *KEINEN* fertig programmierten Code oder Links zu Anleitungen für so ein Simulationsprogramm! Ich will lediglich eine grobe Richtung haben, mit was ich das umsetzen kann!

Damit ihr wißt, mit was ich arbeiten kann, zur Zeit behersche ich:

-Int, Double, String
-Alle gänigen Rechenoperationen (+; -; *; /; %)
-Einlesen und Ausgabe von Werten in der Console vom JavaEditor
-If
-switch
-while/do/for


Vielen Dank für eure (schnelle) Hilfe!

MFG

Der ProoF


----------



## kirax (22. Mrz 2011)

Also ich gehe jetzt mal davon aus, dass mit den Karpfen und Forellen die gleichen Lebewesen gemeint sind 

Im ersten Jahr kommen 0,06*(H-A) Karpfen dazu. Das sind 0,06*(300) = 18 Stück. Demnach sind es nach dem ersten Jahr 68 Karpfen und das Spiel geht von vorne los.

Für b) entnimmt man einfach von den 68 Karpfen 20% (gerundet 14) bevor eine neue Runde beginnt.

Spontan kommt mir die Idee, einfach nach dem Start zu fragen, ob a) oder b) ausgeführt werden sollte und dann fragen, wie viele Jahre simuliert werden sollen (sonst läuft das ja endlos weiter).
Man könnte es sogar universell machen und den Anfangsbestand und die Maximalpopulation auch noch abfragen (aber das ist ja Spielerei).

Zur Umsetzung der Formeln:
Die ganzen Zahlen in jeweils eine Variable speichern und ne Funktion schreiben für die beiden Änderungsschritte.
Abhängig von der gewählten Variante (a oder b) wird die Funktion mit der Verminderung nur ausgeführt, wenn b) gewählt wurde. In einer Schleife führst du das ganze dann so oft aus, wie du Jahre simulieren willst. In der Schleife gibst du die jeweils aktuellen Werte aus.


Jetzt hab ich mir echt Mühe gegeben keinen Code zu posten


----------



## WTFProoF (22. Mrz 2011)

Ok cool, danke schon mal für die Antwort. Hab es jetzt auch umgesetzt, blos will das ding irgendwie ned . Kann mir einer sagen wo vielleicht der Fehler liegt:


```
public class koisimulation {
  public static void main(String[] args) {
    double a=50, z=0, j=0, x=0;
    System.out.println("Type in 1 or 2 for 1)No modifier or 2)20% of the Population are taken out each year.");
    x=InOut.readInt();
    if (x != 1){
    System.out.println("Type in the number of years you want the Simulation to run.");
    j=InOut.readInt();
     for (int r=0; r>j; r++){
      z=350-a;
      z=z*0.06;
      z=z+a;
      System.out.println("After the "+r+" year there are "+a+"Kois in the pool");
     }
    }else{
    System.out.println("Type in the number of years you want the Simulation to run.");
    j=InOut.readInt();
     for (int r=0; r>j; r++){
      z=350-a;
      z=z*0.06;
      a=z+a;
      z=a*0.2;
      a=a-z;
      System.out.println("After the "+r+" year there are "+a+"Kois in the pool");
     }
    }
  }
}
```

Danke !


----------



## kirax (22. Mrz 2011)

Definiere "funktioniert nicht".


----------



## Michael... (22. Mrz 2011)

Wenn Du auch weiterhin Spass am Programmieren haben willst, dann gewöhn Dir an den Variablen einen vernünftigen Namen zu geben.

Ausserdem:
- sollte es wohl 
	
	
	
	





```
if(x==1)
```
 heißen, 1 für die Berechnung ohne jährliche Reduzierung
- werden die for-Schleifen niemals durchlaufen (s. Bedingung). Eine Schleife wird durchlaufen, solange die Bedingung wahr ist.


----------



## WTFProoF (22. Mrz 2011)

Mein erstes Funktioniert nicht definierte sich als:

Ich kann das Programm ausführen. Ich kann Option (x) 1 oder 2 Wählen. Ich kann die Anzahl von Jahren(j) angeben. Er rechnet die Population für die angegebene Zeitspanne nicht aus (alles was im for (int r=0; r<j; r++) steht beachtet er nicht).

Habe dieses Problem aber schon gelöst indem ich das > in 
	
	
	
	





```
for (int r=0; r>j; r++) {...
```
 durch ein < ersetzt habe, das da eigentlich hingehört.

Nun die definition von meinem aktuellen Problem:

Er gibt mir für 5 Jahre bei einem knostannten Wachstum (also Teilaufgabe A) 63.475... Karpfen aus obwohl da nach meinen Berechnungen ca. 130 Fische drin se


----------



## Blakh (22. Mrz 2011)

z=350-a; 

Daran ändert sich ja auch nix. In jedem Schleifendurchlauf setzt du z am Anfang wieder auf 300.

 Ich frage mich auch wieso du eine variable a und eine variable z brauchst.

Wie wäre es mit einer Variable 
	
	
	
	





```
int noOfFish = 50;
```

und Konstanten 
	
	
	
	





```
final static int MAX_NO_OF_FISH = 350;
final static double SPREAD_RATE = 0.06
final static double REDUCTION= 0.2
```

Ist unpraktisch, Konstanten als Zahlen im Code direkt zu verwenden. So kannst du ganz einfach Konstanten zentral an einer Stelle ändern, wenn es benötigt wird.

mfg


----------



## WTFProoF (22. Mrz 2011)

Ok, danke auch dir, aber ich versteh nicht warum ich denn z immer auf 300 setze? Die Schleife nutzt doch immer den aktuellen a-/NoOfFish-Wert und der ändert sich doch mit jedem Schleifen-Durchgang, oder nicht?

MFG


----------



## Blakh (22. Mrz 2011)

Ich spiels mal durch mit deinem Code: (a = 50)


```
for (int r=0; r<j; r++){
   z=350-a;
   z=z*0.06;
   z=z+a;
}
```

1. Durchlauf:
Zeile 1 -z = 300
Zeile 2 -z = 18
Zeile 3 -z = 68

2. Durchlauf:
Zeile 1 - z = 300
Zeile 2 -z = 18
Zeile 3 -z = 68

...

2. Variante:


```
for (int r=0; r<j; r++){
      z=350-a;
      z=z*0.06;
      a=z+a;
      z=a*0.2;
      a=a-z;
}
```

1. Durchlauf:
Zeile 1 -z = 300
Zeile 2 -z = 18
Zeile 3 -a = 68
Zeile 4 -z = 13 (int kennt nur ganze Zahlen)
zeile 5 -a = 37

2. Durchlauf:
Zeile 1 -z = 313
Zeile 2 -z = 18 ( 18,78 wird abgeschnitten, da int)
Zeile 3 -a = 55
Zeile 4 -z = 11 (int kennt nur ganze Zahlen)
zeile 5 -a = 44

Definitiv nicht das, was du suchst .

*p.S. Sehe gerade du verwendest ja double. Dann vergiss das mit dem Abschneiden . Du solltest aber für die Anzahl der Fische besser int verwenden, da du ja keine halben Fische im Aquarium haben willst.*


----------



## Michael... (22. Mrz 2011)

WTFProoF hat gesagt.:


> Er gibt mir für 5 Jahre bei einem knostannten Wachstum (also Teilaufgabe A) 63.475... Karpfen aus obwohl da nach meinen Berechnungen ca. 130 Fische drin se


So ein 0,475 Karpfen im Tümpel treibend ist nicht unbedingt ein schönder Anblick.

Hast Du das 
	
	
	
	





```
if (x != 1)
```
 geändert? Wenn nicht bist Du im else Zweig gelandet und rechnest mit einer jährlichen Reduktion um 20%.

Im If- Zweig wir *a* übrigens niemals verändert.


----------



## WTFProoF (22. Mrz 2011)

Ich habe das != in ein == umgewandelt, aber wie kriege ich jetzt die for-schleifen dazu, jedes mal den A wert zu nehmen, der nach der Rechnung eigentlich rauskommen muss?


----------



## Michael... (22. Mrz 2011)

---


----------



## Michael... (22. Mrz 2011)

WTFProoF hat gesagt.:


> aber wie kriege ich jetzt die for-schleifen dazu, jedes mal den A wert zu nehmen, der nach der Rechnung eigentlich rauskommen muss?


Das Zauberwort heisst: Zuweisung 
	
	
	
	





```
a = ...
```
 ;-)

Deshalb auch mein Hinweis mit den vernünftigen/ sprechenden Variablenname, dann sieht man gleich wenn man Schmarrn macht.


----------



## Blakh (22. Mrz 2011)

WTFProoF hat gesagt.:


> Ich habe das != in ein == umgewandelt, aber wie kriege ich jetzt die for-schleifen dazu, jedes mal den A wert zu nehmen, der nach der Rechnung eigentlich rauskommen muss?



Das ist doch einfache Mathematik?! Du musst pro Durchlauf nur folgendes machen:

noOfFish = noOfFish + (das was dazu kommt);

Wen du das als EInzeiler machst, brauchst du keine Werte zwischenspeichern. Alles will ich aber auch nicht verraten, da du schon ein wenig Grips aktivieren sollst :bae:


----------



## WTFProoF (22. Mrz 2011)

So Ich hab das ganze jetzt komplet gelöst und mein Endergebniss sieht so aus:


```
public class koisimulation {

  public static void main(String[] args) {
    double NoOfFish=50;
    int YearsToRun=0, Modificator=0;
    System.out.println("Type in 1 or 2 for 1)No modifier or 2)20% of the Population are taken out each year.");
    Modificator=InOut.readInt();
    if (Modificator == 1){
     System.out.println("Type in the number of years you want the Simulation to run.");
     YearsToRun=InOut.readInt();
     for (int YearsPassed=1; YearsPassed<=YearsToRun; YearsPassed++){
      NoOfFish=NoOfFish+((350-NoOfFish)*0.06);
      NoOfFish=Math.round(NoOfFish);
     }
     System.out.println("After "+YearsToRun+" years there are ~"+NoOfFish+" Kois in the pool.");
    }else{
     System.out.println("Type in the number of years you want the Simulation to run.");
     YearsToRun=InOut.readInt();
     for (int YearsPassed=1; YearsPassed<=YearsToRun; YearsPassed++){
      NoOfFish=NoOfFish+((350-NoOfFish)*0.06*0.2);
      NoOfFish=Math.round(NoOfFish);
     }
     System.out.println("After "+YearsToRun+" years there are ~"+NoOfFish+" Kois in the pool.");
    }
  }
}
```

Danke an alle, die mir heute über den Tag verteilt geholfen haben, ohne euch würde ich jetzt noch da sein wo ich am Anfang stand, danke!

Mit freundlichen Grüßen

Der ProoF


----------



## kirax (22. Mrz 2011)

Wenn du jetzt noch Klassennamen groß- und Variablennamen kleinschreibst, machst du alle hier noch glücklicher


----------



## Blakh (22. Mrz 2011)

```
noOfFish=noOfFish+((350-noOfFish)*0.06*0.2);
```

Das ist so glaub nicht richtig oder täusch ich mich?

Die 0.2 sind verkehrt. 

So sollte es richtig sein.

```
noOfFish=noOfFish+((350-noOfFish)*0.06);
      noOfFish=noOfFish*0.8 // 80% der Fische verbleiben im Tank
```

Oder als Einzeiler:


```
noOfFish=(noOfFish+((350-noOfFish)*0.06))*0.8;
```


----------



## Firephoenix (22. Mrz 2011)

Hi,
zur codeoptimierung:
der if-else zweig unterscheidet sich nur in einer Zeile, da kann man auch direkt die Methode hinschreiben und nur die eine Zeile abfragen 

hier auch nochmal eine kurzschreib-version fürs Archiv (mit dem InOut kann ich selbst irgendwie nicht kompilieren - woher kommt das genau?)


```
public static void main(String[] args) {
		//Startwert der Karpfen
		int anzahlKarpfen = 50;
		//Obergrenze der Population
		int maxKarpfen = 350;
		//Anzahl der Jahre die Simuliert werden sollen
		int anzahlDerJahre = 10;
		//bei true werden Ende jedes Jahres 20% der Karpfen entnommen
		boolean entnahmeAmJahresende = false;
		
		for(int i = 1; i <= anzahlDerJahre; i++){
			anzahlKarpfen += 0.06*(maxKarpfen-anzahlKarpfen);
			if(entnahmeAmJahresende)
				anzahlKarpfen *= 0.8;
			System.out.println("After the "+i+" year there are "+anzahlKarpfen+" Kois in the pool");
		}
	}
```
Gruß


----------



## xehpuk (22. Mrz 2011)

Man sollte aber schon richtig runden, damit man ein korrektes Ergebnis bekommt:
[JAVA=12]anzahlKarpfen += Math.round(0.06 * (maxKarpfen - anzahlKarpfen));[/code]


----------



## Firephoenix (22. Mrz 2011)

Hi,
Ob das Ergebnis im Bezug auf Vermehrung noch korrekt ist würde ich mindestens Anzweifeln, denn Tiere vermehren sich nicht im Kommabereich 
Daher macht an der Stelle das beschränken auf Ganzzahl-Werte sogar Sinn.
Hier mal das Beispiel ohne auslesen per Hand und als Ausgabe:

50 Karpfen, Maximalpopulation 350 ohne rausnehmen:
Jahr 1:
350-50 = 300, davon 6 % sind 18
68 Karpfen am Jahresende

Jahr 2:
350-68 = 282, davon 6 % sind 16,92
68+16 = 84 Karpfen am Jahresende

Jahr 3:
350-84 = 266, davon 6 % sind 15.96
84+15 = 99 Karpfen am Jahresende
usw...

äquivalent dazu meine Ausgabe ohne auslese:


> After the 1 year there are 68 Kois in the pool
> After the 2 year there are 84 Kois in the pool
> After the 3 year there are 99 Kois in the pool
> After the 4 year there are 114 Kois in the pool
> ...



Jetzt das ganze mit der 20% auslese
50 Karpfen, Maximalpopulation 350 mit rausnehmen, 
an der Stelle macht das Runden Sinn, da man wohl eher wirtschaftlich rechnet - ich habe die Zeile entsprechend angepasst:

```
if(entnahmeAmJahresende)
                anzahlKarpfen -= Math.round(0.2*anzahlKarpfen);
```
Jahr 1:
350-50 = 300, davon 6 % sind 18
68 Karpfen am Jahresende
davon nochmal 20% : 13.6
68-14 sind 54

Jahr 2:
350-54 = 296, davon 6 % sind 17.76
54+17 = 71 Karpfen am Jahresende
davon nochmal 20% : 14.2
71-14 sind 57

Jahr 3:
350-57 = 293, davon 6 % sind 17.58
57+17 = 74 Karpfen am Jahresende
davon nochmal 20% : 14.8
74-15 sind 59

Ausgabe entsprechend:


> After the 1 year there are 54 Kois in the pool
> After the 2 year there are 57 Kois in the pool
> After the 3 year there are 59 Kois in the pool
> After the 4 year there are 61 Kois in the pool
> ...



Hier nochmal der korrekte Code komplett:

```
public static void main(String[] args) {
        //Startwert der Karpfen
        int anzahlKarpfen = 50;
        //Obergrenze der Population
        int maxKarpfen = 350;
        //Anzahl der Jahre die Simuliert werden sollen
        int anzahlDerJahre = 10;
        //bei true werden Ende jedes Jahres 20% der Karpfen entnommen
        boolean entnahmeAmJahresende = true;
        
        for(int i = 1; i <= anzahlDerJahre; i++){
            anzahlKarpfen += 0.06*(maxKarpfen-anzahlKarpfen);
            if(entnahmeAmJahresende)
                anzahlKarpfen -= Math.round(0.2*anzahlKarpfen);
            System.out.println("After the "+i+" year there are "+anzahlKarpfen+" Kois in the pool");
        }
    }
```
Gruß


----------



## WTFProoF (23. Mrz 2011)

Danke für alle weiteren Antworten! Ich habe schon selber rausgefunden dass es nicht 0.2 sondern 0.8 sein soll und habe das auch ersetzt. Die InOut-clas hat unsere Info-Lehrerin für uns geschrieben, sie dient dazu werte die der User eingibt auszulesen. Werde heute abend nochmal meine version "verschönern" und sie hochladen.


----------

