Fibonacci Algorithmus

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hi zusammen,

ich habe die Aufgabe einen Algorithmus zu implementieren, der die Fibonacci-Zahl berechnet.
Dabei lautet die Aufgabenstellung:

Sei F(n) die n-te Fibonacci-Zahl. Zur konkreten Berechnung von F(n) zu
einem bekannten n gibt es zwei Algorithmen:
(Algorithmus A)
Man f¨uhrt fibonacci(n) durch. Die Programmroutine fibonacci(k)
bekommt als Eingabevariable k und liefert F(k) zur¨uck. Ihr Ablauf:
• Wenn k = 0, dann F(k) := 0
• Wenn k = 1, dann F(k) := 1
• Wenn k /2 {0, 1}, dann:
– F¨uhre fibonacci(k-1) durch; erhalte F(k − 1)
– F¨uhre fibonacci(k-2) durch; erhalte F(k − 2)
– Berechne F(k) = F(k − 1) + F(k − 2)
• Liefere den Wert F(k) zur¨uck.
(Algorithmus B)
1. Starte mit F(0) = 0, F(1) = 1, k = 0
2. Setze G(k) = (F(k + 1), F(k))
3. Speichere G(k)
4. Berechne F(k + 2) als Summe der beiden Komponenten von G(k)
5. Erh¨ohe k um 1
6. Abbruch für k + 1 = n, sonst zurück zu Schritt 2
(i) Berechne die Anzahl der benötigten Additionen für beide Algorithmen
am Beispiel n = 6.

Meine Implementierung:
Code:
public int algoA(int n) {
		if (n == 0)
		{
			return 0;
		}
		else if (n == 1)
		{
			return 1;
		}
		else {
			counter++;
			return algoA(n - 1) + algoA(n - 2);
		}
	}

	public int algoB(int n) {
		int k = 0;
		int fK = 0;
		int[] gK = new int[2];
		do {
			gK[0]= k + 1;
			gK[1]=k;
			counter++;
			fK = gK[0] + gK[1];
			k++;
		}
		while (k + 1 < n);
		return fK;
	}

Allerdings erhalte ich mit algoA(6) als Ergebnis 8 und mit algoB(6) als Ergebnis 9.
Meine Frage daher: Sind die beiden Algorithmen so korrekt nach der Aufgabenstellung programmiert? Mich verwundert das unterschiedliche Ergebnis von AlgoA und B.
 

Landei

Top Contributor
Du musst bei algoB die Werte in deinem Feld "weiterrücken", nicht einfach mit dem Zähler k belegen, also so:
1) [0, 1]
2) [1, 0+1] = [1, 1]
3) [1, 1+1] = [1, 2]
4) [2, 1+3] = [2, 3]
5) [3, 2+3] = [3, 5]
6) [5, 3+5] = [5, 8] <- 8 ist die 6. Fibo-Zahl
...

Aus'm Kopp - keine Gewähr
Code:
public int algoB(int n) {
  if (n < 2) return n;
  int[] gK = new int[]{0, 1}; 
  for(int k = 2; k <= n; k++) {
     int fK = gK[0] + gK[1]; 
     gK[0] = gK[1];
     gK[1] = fK; 
  }
  return gK[1];
}
 

Unikate

Aktives Mitglied
Java:
public class Fibonacci {

	public static void main (String[]args){
		
		int x=1;
		int y=1;
		int folge=ergebnis(x,y);
	
		System.out.println(folge);
	}
	
	public static int ergebnis(int x, int y){
		int z;
		
		if (x+y == 1597)
			return x=610;
		else {
			z = x + y;
			System.out.println(x + "," + y);
			return z + ergebnis(x + y,y + z);
		}
	}
		
}

Ergebnisse in der Console:
1,1
2,3
5,8
13,21
34,55
89,144
233,377
1596


Ich habe den Algo so gelöst.
Wie kann ich denn die ausgegebenen Zahlen nebeneinander schreiben?
Und hat jemand eine elegentarer lösung für die abbruchbedingung?

gruß+danke
kate
 
S

SlaterB

Gast
System.out.print statt System.out.println

-----

return x=610;

welchen Sinn hat es hier, x noch schnell einen Wert zuzuweisen?

-----

die Abbruchbedingung ist n, die Stufe, 6 oder so, übergib doch n mit als Parameter

was ist denn
 

Unikate

Aktives Mitglied
danke für den print tip! kannte ich noch nicht. hab programmieren erst seit 2 monaten.
ich wusste nicht wie ich die abbruchbedingung definieren sollte, da der algo ja unendlich sein kann.
hab ich einfach einen stoppwert gewählt^^
haben heut erst rekursion gelernt. deswegen bin ich mit der abbruchbedingung noch nicht so fit ;)
was meinst du mit "abbruchbedingung stufe 6"?

gruß
:)
 
S

SlaterB

Gast
du prüfst doch ob x + y irgendwas ist, == 1597, und nun sollst was anderes prüfen, == 6, recht ähnlich

aber x + y sind nicht an dieser Stelle 6 sondern was anderes, du musst mehr Information übergeben,
es ist ja erlaubt, beliebig viele Parameter zu übergeben, also auch einen der an dieser Stelle 6 ist,
 

Unikate

Aktives Mitglied
genau, ich will dass er bei einer bestimmten algo zahl (z.b. 610) die ganze sache einfach abbricht.
also wenn x+y==610, dann brich ab. und dann muss ich x 6 zuweisen??
sorry dass ich es nich direkt raffe
 
S

SlaterB

Gast
1. 1,1
2. 2,3
3. 5,8
4. 13,21
5. 34,55
6. 89,144
7. 233,377

ob nun 6 oder 7 ist ja egal, jede Ausgabe ist eine Stufe, einfach einen zusätzlichen Parameter,
mit x und y hat das absolut nix zu tun

public static int ergebnis(int x, int y, int n){
 

Unikate

Aktives Mitglied
Java:
	public static int ergebnis(int x, int y, int n){
		int z;
		
		if (n == 10)
			return n;
		else {
			z = x + y;
			System.out.print(x + "," + y + ",");
			return z + ergebnis(x + y,y + z, n+1);
		}
	}
		
}
 

Unikate

Aktives Mitglied
ist das immer so das prinzip, dass man in einer rekursion "stufen" hat und sie mit n hochzählt?
ne oder?nur wenn ich was aufzähle?
weil wir auch eine aufgabe hatte, in der wir die quersumme berechnen mussten.
da war die abbruchbedingung :

if (x<=9)
return x;

=> also wenn x kleiner gleich 9, so gebe direkt x aus und wenn nicht mache es solange bis x<=0 wird!
 
Zuletzt bearbeitet:
S

SlaterB

Gast
Rekursion brauch man hier gar nicht, ne Schleife ginge auch,
und return n; ist ganz schlecht, n ist nur für den Abbruch zuständig, doch nicht plötzlich ein Wert
 

Unikate

Aktives Mitglied
aaaaaaaa verwirrung. ja wir müssen das rekusriv schreiben. als übung halt.
also muss die abbruchbedingung dann immer einen wert annehmen. hmmmmmmmm irgendeinen beliebigen oder der sich aus den zahlen ableiten lässt?:D zielloooooooos! :D
 

Unikate

Aktives Mitglied
Java:
	public static int ergebnis(int x, int y, int n){
		int z;
		
		if (n == 12)			//jedes n ist eine stelle z.b. 5 und 8
			return x = -17711;
		else {
			z = x + y;
			System.out.print(x + "," + y + ",");
			return z + ergebnis(x + y,y + z, n+1);
		}
	}

Habe es nun so gelöst.Ergebnis:

1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28656

problem ist nur, dass wenn man die abbruchbedingung ändert, müsste man den x wert neu ausrechnen.
hab ihn durch den debugger einfach berechnet!
 
S

SlaterB

Gast
was genau bei dieser Rekursion rauskommen soll, sehe ich kaum durch,
aber du solltest auf keinen Fall irgendwelche Werte manuell berechnen, gib das aktuelle x, y oder z zurück, irgendwas davon muss doch gesucht sein,
wenn du einen dieser Werte wieder abziehst, dann kommt das x, y oder z des vorherigen Durchgangs raus, das bedeutet dass du damals schon hättest abbrechen müssen oder ähnliches

Java:
public class Test {
	public static void main(String[] args) {

		int x = 0;
		int y = 1;
		int folge = ergebnis(x, y, 1);

		System.out.println("\n" + folge);
	}

	public static int ergebnis(int x, int y, int n) {
		System.out.println(x + "," + y + ",");
		if (n == 11) {
			return x;
		}
		int z = x + y;
		return z + ergebnis(z, y + z, n + 1);
	}

}
 

partsch

Aktives Mitglied
Falls du noch eine Lösung suchst
die rekursive hatte ich mal zur Hausübung ist deiner Angabe sehr ähnlich

Java:
import java.util.Scanner;
public class Fibonacci {
	
	
	public static void main(String...args){
		countFibo();
	}
	
	public static void countFibo(){
		Scanner sc = new Scanner(System.in);
		System.out.print("Bitte geben sie an bis wohin die Fibonaccizahlen aufgelistet werden sollen: ");
		int toCount = sc.nextInt();
		System.out.println("");
		nextFibo(0, 1, toCount);
	}
	
	private static int nextFibo(int numb_1, int numb_2, int n){
		if(numb_1>numb_2){
			numb_2 ^= (numb_1^=numb_2);
			numb_1 ^= numb_2;
		}
		System.out.print(numb_1+", ");
		if(numb_2 < n){
			return nextFibo(numb_2, (numb_1+numb_2), n);
		}
                if(numb_2<= n)
		        System.out.print(numb_2);
		return n;
	}
}
 
Zuletzt bearbeitet:

Unikate

Aktives Mitglied
wenn ich als abbruchbedingung definiere:

if (n == 12)
return x;

Ergebnis:
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,75024


:-/

guten mooorgen
 
S

SlaterB

Gast
bei deinem Programm vielleicht, nicht bei meinem,
aber selbst 75024 ist nicht schlecht, ist irgendeine Zahl aus der Fibonacci-Reihe, man muss nur alle Parameter und n so wählen, dass man zufrieden ist,

das merkwürdige Aufaddieren beim return kann man sich auch sparen:
return ergebnis(z, y + z, n + 1);
schon siehts wieder etwas anders aus, Ergebnis ist immer noch eine der Zahlen aus der Reihe, aber eine andere kleinere

was die Methode ausrechnen sollte/ derzeit tut kann ich wie gesagt eh nicht nachvollziehen,
da aber immer nur x + y addiert wird, kommt sicherlich überall was Fibonacci-mäßiges raus
 

ARadauer

Top Contributor
Java:
		if (x+y == 1597)
			return x=610;
hab mir jetzt nicht alles angesehen... aber was soll das sein? :eek:

Java:
   public static int fibu(int f){
      if(f<2)
         return f;      
      return fibu(f-2)+fibu(f-2);
   }

Fibunacci... mehr ist das nicht...

Natürlich ist der Algo praktisch nicht anzuwenden da man extrem lange Laufzeiten hat...
besser ist, wenn man das Ergebnis chached...

Java:
 public static HashMap<Integer, Integer> fibuNumbers = new HashMap<Integer, Integer>();
   public static int fastFibu(int f){
      if(f<2){
         return f;
      }else{
         if(fibuNumbers.containsKey(f)){
            return fibuNumbers.get(f);
         }else{
            int newF = fastFibu(f-1)+fastFibu(f-2);
            fibuNumbers.put(f, newF);
            return newF;
         }
      }
   }
 

lumo

Top Contributor
hab das mit fibonacci etwas anderst gelöst.
nach etwas testen ists mir zu nervig geworden, dass das immer so lange dauert, ein paar fibs zu berechnen... hab darum eine liste eingeführ und siehe da... es rauscht nur so dahin. (in null komma nix)

wusstet ihr dass die 200erste fib zahl 3721511182311577122 ist? :D

als kleines zuckerl hab ich noch die zeckendorf-zerlegung dazugemacht (also zerlegung einer zahl in fibonacci-zahlen)

Code:
import java.util.LinkedList;
import java.util.List;

public class Zeckendorf {
	List<Long> zeck = new LinkedList<Long>();
	List<Long> fibs = new LinkedList<Long>();

	public Zeckendorf() {
		fibs.add(1L); // fib(0)
		fibs.add(1L); // fib(1)
	}

	public void zeck(Long n) {
		int i = new Integer(Long.toString(n));
		fibonacci(i);
		Long z = n;
		while (z > 0) {
			Long small = getSmaller(z);
			zeck.add(0, small);
			z = z - small;
		}
	}

	public void printLongZeck() {
		for (int i = zeck.size() - 1; i >= 0; i--) {
			if (i == zeck.size() - 1) {
				System.out.print("[" + zeck.get(i) + ", ");
			} else if (i == 0) {
				System.out.print(zeck.get(i) + "]");
			} else {
				System.out.print(zeck.get(i) + ", ");
			}
		}
		System.out.println();
	}

	public Long getSmaller(Long n) {
		int i = 1;
		while (fibs.get(i) < n) {
			i++;
		}
		return fibs.get(i - 1);
	}

	public static void main(String[] args) {

		Zeckendorf z = new Zeckendorf();
		long start = System.currentTimeMillis();
		System.out.println("the 200th Fibonacci number is: "
				+ z.fibonacci(200));
		long stopp = System.currentTimeMillis();
		System.out.println(String.format(
				"calculating 200th Fibonacci took %dms", stopp - start));
		start = System.currentTimeMillis();
		Long num = 1662500L;
		z.zeck(num);
		stopp = System.currentTimeMillis();
		System.out.println(String.format(
				"calculating Zeckendorf(%d) took %dms", num, stopp - start));
		System.out.print("Zeckendorf = ");
		z.printLongZeck();
	}

	public Long fibonacci(int n) {
		// {0,1} size = 2 - list at start
		if (n > fibs.size() - 1) {
			Long newFib = 0L;
			while (n >= fibs.size()) {
				newFib = fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2);
				fibs.add(newFib);
			}
			return newFib;
		} else {
			if (n >= 0) {
				// the fib is already in the list
				return fibs.get(n);
			} else {
				return 0L;
			}
		}
	}
}

falls jemand noch verbesserungsvorschläge hat... ich bin dafür offen

BTW: bis jetzt gibts ne einschränkung auf int (als index der liste... -> ist die höchste int zahl die höchste fibonacci zahl, die mein algorithmus errechnet.) und für zeckendorf bedeutet das die zahl Long num = 1662500L; wie im codebeispiel gewählt
 

Unikate

Aktives Mitglied
ist das nicht ein bisschen zu komplex?programmieren hat doch zum ziel, so wenig wie möglich zeilen niederzuschreiben oder nicht?
 

lumo

Top Contributor
ne, eigentlich nicht.
eigentlich ist das ziel (zumindest meines) dass die programme möglichst schnell laufen. (und speicherfreundlich sind)
note: rekursion frisst meist mehr speicher als iterative funktionen
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Iterativer Algorithmus zur Berechnung der Fibonacci Zahlen Java Basics - Anfänger-Themen 1
S Abwandlung der Fibonacci Folge Java Basics - Anfänger-Themen 3
T Fibonacci mit einer Hilfsmethode berechnen Java Basics - Anfänger-Themen 10
123456789sssssaaaa Which is the best way to Print Fibonacci Series in Java? Java Basics - Anfänger-Themen 3
jhCDtGVjcZGcfzug Fibonacci Zahlen rekursiv und iterativ Java Basics - Anfänger-Themen 21
J Fibonacci-Reihe Java Basics - Anfänger-Themen 12
G Fibonacci Zahlenreihe Fehler Java Basics - Anfänger-Themen 4
D Fibonacci overflow integer Java Basics - Anfänger-Themen 8
B Fibonacci Zahlen dynamische Programmierung Java Basics - Anfänger-Themen 7
N Dynamisches Programmieren/Fibonacci Java Basics - Anfänger-Themen 1
V Fibonacci Folge Java Basics - Anfänger-Themen 4
S Fibonacci Zahlen rekursiv Java Basics - Anfänger-Themen 1
A Fibonacci Zahlen Java Basics - Anfänger-Themen 1
M Methoden Fibonacci-Folge Java Basics - Anfänger-Themen 6
J Fibonacci -Folge rekursiv berechnen Java Basics - Anfänger-Themen 18
P Fibonacci -Verallgemeintert Java Basics - Anfänger-Themen 2
K Methoden Fibonacci in Array mit rekursiver Methoden Java Basics - Anfänger-Themen 19
M Fibonacci rekursiv mittels Cache Java Basics - Anfänger-Themen 17
T Stack Overflow - Rekursive Fibonacci Java Basics - Anfänger-Themen 10
K Fibonacci Zahlen Java Basics - Anfänger-Themen 3
B Fibonacci Zahlen rekursiv Array Java Basics - Anfänger-Themen 12
M Fibonacci-Folge mit while-Schleife Java Basics - Anfänger-Themen 4
P fibonacci - do while Statement Logik Fehler Java Basics - Anfänger-Themen 5
A Fibonacci-numbers Java Basics - Anfänger-Themen 9
K Rekursion Fibonacci Java Basics - Anfänger-Themen 3
J Fibonacci Zahlen berechnen Java Basics - Anfänger-Themen 3
Z Fibonacci rekursiv meine Erklärung stimmt so? Java Basics - Anfänger-Themen 2
Z Fibonacci Array Erklärung Java Basics - Anfänger-Themen 5
A Gerade Terme der Fibonacci-Folge aufsummieren Java Basics - Anfänger-Themen 12
M Fibonacci, Fakultaet, GGT Java Basics - Anfänger-Themen 9
C Fibonacci Zahlen Java Basics - Anfänger-Themen 7
J Ausgabe der fibonacci Zahlen Java Basics - Anfänger-Themen 4
S Fibonacci Folge Java Basics - Anfänger-Themen 34
D Fibonacci Java Basics - Anfänger-Themen 11
M Fibonacci-Linear und Rekursiv Java Basics - Anfänger-Themen 14
W Fibonacci Zahlenberechnung Java Basics - Anfänger-Themen 9
X Fibonacci mit durchschnittlicher Zeit Java Basics - Anfänger-Themen 5
I Fibonacci-Folge , direkter Weg. Java Basics - Anfänger-Themen 5
0 Fibonacci Zahlen seeeehr schnell berechnen Java Basics - Anfänger-Themen 9
S Fibonacci Rückrechnung! Java Basics - Anfänger-Themen 5
K Fibonacci Zahlen Java Basics - Anfänger-Themen 2
K Programmieren von den ersten 70 Fibonacci-Zahlen Java Basics - Anfänger-Themen 2
G fibonacci was stimmt an meinem code nicht? Java Basics - Anfänger-Themen 2
S Fibonacci Zahlenvergeich Java Basics - Anfänger-Themen 6
P Fibonacci-Zahlen Java Basics - Anfänger-Themen 6
laxla123 Eigenschaften eines Algorithmus (determiniert vs.. deterministisch) Java Basics - Anfänger-Themen 2
C Gewinnspiel erstellen mit Algorithmus Java Basics - Anfänger-Themen 3
C negamax-Algorithmus für Tic-Tac-Toe spielt manchmal falsch Java Basics - Anfänger-Themen 10
H Minimax Algorithmus in Tic Tac Toe Java Basics - Anfänger-Themen 3
M Minimax-Algorithmus für Vier gewinnt Java Basics - Anfänger-Themen 11
ohneInformatik; Trockentest Algorithmus, mathematischen Zusammenhang angeben Java Basics - Anfänger-Themen 3
M Minimax-Algorithmus Java Basics - Anfänger-Themen 17
mervanpolat Binary Search Algorithmus ausführen Java Basics - Anfänger-Themen 1
J Rekursiver Algorithmus Java Basics - Anfänger-Themen 9
M monte carlo Algorithmus für 4 gewinnt Java Basics - Anfänger-Themen 12
izoards Sortier Algorithmus für Bounding Box Elememte Links nach Rechts und von Oben nach Unten Java Basics - Anfänger-Themen 33
S Algorithmus entwicklen, der zu einem gegebenen Datum die Jahreszeit ermittelt Java Basics - Anfänger-Themen 13
rosima26 Merge-Algorithmus Java Basics - Anfänger-Themen 53
C Ein Algorithmus soll schneller werden Java Basics - Anfänger-Themen 24
D Dijkstra Algorithmus Hilfe!! Java Basics - Anfänger-Themen 9
U Den Kuchen aufteilen - aber wie? (Rebalancing-Algorithmus) Java Basics - Anfänger-Themen 14
s_1895 Pseudocode Naiver Algorithmus Java Basics - Anfänger-Themen 17
H String verschlüsseln - eigener Algorithmus Java Basics - Anfänger-Themen 104
T Algorithmus für Index mit min-Wert Java Basics - Anfänger-Themen 2
Düsseldorf2002 Testen meines Algorithmus Java Basics - Anfänger-Themen 1
D Primzahlen Rechner nach Eratostenes von Kyrene Algorithmus Java Basics - Anfänger-Themen 2
KogoroMori21 Frage zum Euklidischen Algorithmus Java Basics - Anfänger-Themen 11
S Algorithmus java searchAll IKey Java Basics - Anfänger-Themen 4
S Algorithmus Datensätze einfügen wenn... Java Basics - Anfänger-Themen 26
KogoroMori21 MergeSort Algorithmus Java Basics - Anfänger-Themen 2
KogoroMori21 Textdatei einlesen im Array (Selection Sort Algorithmus) Java Basics - Anfänger-Themen 3
fendix Compiler-Fehler Algorithmus zur Bestimmung von Primzahlen Java Basics - Anfänger-Themen 7
S Algorithmus (reelle Zahl <65536 von dezimal zu dual) max. 10 Nachkommastellen Java Basics - Anfänger-Themen 4
G Algorithmus Graphen Java Basics - Anfänger-Themen 10
D Input/Output fehlerhafter Algorithmus zum Ersetzen von Array-Werten nach logischem Schema Java Basics - Anfänger-Themen 1
N Selection Algorithmus: Methode wird nicht erkannt (BlueJ) Java Basics - Anfänger-Themen 3
U Meinung zum Dijkstra Algorithmus Java Basics - Anfänger-Themen 6
U Dijkstra Algorithmus Laufzeit Java Basics - Anfänger-Themen 3
L Math.exp also eigenen Algorithmus Java Basics - Anfänger-Themen 2
Kirby.exe Algorithmus entwickeln Java Basics - Anfänger-Themen 37
M Algorithmus Max-Heap? Java Basics - Anfänger-Themen 3
I Labyrinth auf der Basis eines rekursiven Algorithmus Java Basics - Anfänger-Themen 27
CptK Best Practice Algorithmus nach jedem Schritt zum Visualisieren pausieren Java Basics - Anfänger-Themen 3
A Algorithmus effizienter machen Java Basics - Anfänger-Themen 1
V Algorithmus zur fortlaufenden Berechnung des duechscjnt Java Basics - Anfänger-Themen 1
M Dijkstra Algorithmus in Graphen auf mehrere verschiedene Knoten anwenden lassen Java Basics - Anfänger-Themen 11
O Labyrinth Algorithmus Java Basics - Anfänger-Themen 3
G Quicksort Algorithmus Java Basics - Anfänger-Themen 12
S Binäre-Suche Algorithmus Java Basics - Anfänger-Themen 1
D Algorithmus in Pseudocode mit log2(n) Operationen erstellen Java Basics - Anfänger-Themen 3
C Laufzeit eines Sortier-Algorithmus ermitteln Java Basics - Anfänger-Themen 4
H aufgabe java luhn algorithmus Java Basics - Anfänger-Themen 10
A Datenstruktur für Savings Algorithmus und Planung von kleinen Programmierprojekten Java Basics - Anfänger-Themen 1
J Algorithmus für eine Reihe implementieren Java Basics - Anfänger-Themen 2
S Dijkstra Algorithmus funktioniert nicht Java Basics - Anfänger-Themen 4
N Denksportaufgabe durch Algorithmus lösen Java Basics - Anfänger-Themen 2
S Problem mit einem rekursivem FloodFill Algorithmus Java Basics - Anfänger-Themen 62
B Algorithmus Square und Multiply Java Basics - Anfänger-Themen 3
J Algorithmus - Strings auf eigene Reihenfolge miteinander vergleichen Java Basics - Anfänger-Themen 4
D Frage Boyer-Moore Algorithmus Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben