Eine einfache binäre Suche

Gast #1958453
Lesenswert?
• ▲
▼
Hallöchen!
Ich versuche hier gerade eine einfache binäre Suche (in C#) zu 
implementieren. Leider will es nicht funktionieren...

Die Situation: ich habe eine Liste mit Messwerten (Paare aus Wert & 
Zeitstempel). Nun möchte ich zu einem gegeben Zeitpunkt den 
entsprechenden Messwert finden (ein Messwert gilt immer bis zum 
nächsten).

Hier mein Code:
1
double GetValueAtTime( double t )
2
{
3
  // Start binary search at the middle
4
  int searchPos = mSamples.Count / 2;
5
  int searchStep = mSamples.Count / 4;
6

7
  while (searchStep > 0)
8
  {
9
    // Jump to the right
10
    if (t > mSamples[searchPos + 1].Timestamp)
11
      searchPos += searchStep;
12
      
13
    // Jump to the left
14
    else if (t < mSamples[searchPos].Timestamp)
15
      searchPos -= searchStep;
16
      
17
    // We have found the value
18
    else
19
      break;
20

21
    searchStep /= 2;
22
  }//end while
23

24
  return mSamples[searchPos].Value;
25
}

Leider bekomme ich ich ständig falsche Werte. Ich vermute mal dass das 
daran liegt, dass die Anzahl der Messwerte nicht immer eine 2er Potenz 
ist?
Oder mache ich generell etwas falsch?
#1958470
Lesenswert?
• ▲
▼
Miffel schrieb:

> Ich versuche hier gerade eine einfache binäre Suche (in C#) zu
> implementieren. Leider will es nicht funktionieren...

Sowas gibt es zwar sicherlich schon auch fertig, aber es ist löblich das 
du Basisalgorithmen lernen willst.


> Leider bekomme ich ich ständig falsche Werte. Ich vermute mal dass das
> daran liegt, dass die Anzahl der Messwerte nicht immer eine 2er Potenz
> ist?
> Oder mache ich generell etwas falsch?

Binäre Suche sieht so einfach aus, ist es aber nicht. Das Problem 
besteht darin, dass bei einer ungeraden Anzahl Elemente im Suchraum, man 
höllisch aufpassen muss, wo die Hälfte liegt und dass man dann das 
Intervall richtig neu aufteilt.


Du musst lernen dir selbst zu helfen und zu debuggen.
Und ein Weg und bei weitem nicht der schlechteste, ist es, sich an 
strategischen Stellen strategisch wichtige Variablen ausgeben zu lassen. 
In C# steht dir ohnehin ein ausgezeichneter Weg über das Developer 
Studio und dessen Output-Fenster zur Verfügung, in das man leicht Werte 
ausgeben kann.

http://support.microsoft.com/kb/815788

Also lass dir hier jeweils beim Durchgang durch den Anfang der 
Suchschleife die Variablen ausgeben
1
  while (searchStep > 0)
2
  {
3

4
>>>>   hier ist interessant: welche Werte haben searchPos und searchStep

Und dann wird dieser Mitschrieb studiert und daraus Schlüsse gezogen

> Oder mache ich generell etwas falsch?
IMHO ja.
Beim Binären suchen hat man ein Intervall, das man durch Startindex und 
Endindex definiert und nicht durch Startindex und Größe. Wird nämlich 
ein Intervall in 2 aufgeteilt und entschieden in welchem davon 
weitergesucht werden muss, dann hat dieses neue Intervall nicht 
unbedingt eine neue Größe von step / 2
Gast #1958575
Lesenswert?
• ▲
▼
@Samuel:
Die Dictionary Klasse kannte ich noch gar nicht. Kann man die denn auch 
in meinem Fall benutzen? Denn die Werte, nach denen ich suche stehen ja 
nicht explizit im Speicher.
Wenn ich z.B. zwei Werte habe:

Wert 1:  4
Zeitstempel 1: 0

Wert 2: 9
Zeitstempel: 10

Dann soll meine Suche für ALLE Zeiten 0 < t < 10 den Wert 4, für alle 
Zeiten t >= 10 den Wert 9 zurückgeben...


@KHB:
Danke für die ausführliche Antwort! Da werde ich mich wohl nochmal etwas 
hinein-vertiefen müssen...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren