AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Doppel schnell aus Liste löschen.

Ein Thema von Bjoerk · begonnen am 7. Dez 2014 · letzter Beitrag vom 14. Dez 2014
Antwort Antwort
Seite 1 von 2  1 2      
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 21:22
Ich muss eure Euphorie leider trüben. Die Methode von Dejan Vu liefert unter Umständen falsche Ergebnisse.

Stellt euch mal folgende Punktkonstellation vor:
Code:
            A B





            C
Die Koordinaten sind z.B. A(10.0, 2.0), B(10.001, 2.0), C(10.0, 5.0). A und B sollen im Rahmen des Epsilons als identisch gelten.

Wenn du das jetzt lexikographisch nach sortierst (nach der X-Koordinate zuerst), dann kommt die Reihenfolge A, C, B heraus. A und B werden also nie als Duplikate erkannt, weil sie nach der Sortierung nicht hintereinander stehen.

Das funktioniert leider so nur im Eindimensionalen.

Im Mehrdimensionalen braucht man andere Indexstrukturen, wie K-d-Bäume. Genau für solche Anwendungsfälle, wie die nächsten Nachbarn eines Punktes suchen, wurden die erfunden.

Geändert von Namenloser ( 8. Dez 2014 um 21:24 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 22:10
Ich muss eure Euphorie leider trüben. Die Methode von Dejan Vu liefert unter Umständen falsche Ergebnisse.
Ok. Was denkst du denn über # 16?

Edit: Vergiss es. Genasu so falsch..

Hast du ein Beispiel für K-d-Bäume?

Geändert von Bjoerk ( 8. Dez 2014 um 22:13 Uhr) Grund: Edit:
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 22:30
Ich habe leider kein Beispiel dafür. Es muss aber auch kein K-d-Baum sein, es gibt ja noch andere mehrdimensionale Indexstrukturen.

Die einfachste wäre hier denke ich die Hashmap-Lösung. Im Grunde ist die Idee, dass man ein grobes Raster über die Punkte legt, und pro Kästchen abspeichert, welche Punkte darin liegen:

Code:

|-----|-----|-----|---
|x   |     |     |
|     |     |     |
|-----|-----|-----|---
|     | xx |     |
|     |     |     |
|-----|-----|-----|---
|     |     |    x|
|    x|x   |     |
|-----|-----|-----|---
(Sorry, die DP zerstört mal wieder das Layout, aber ich denke es ist klar, wie es gemeint ist.)

Dann muss man, um „identische“ Punkte zu finden, nur noch die Punkte aus dem gleichen Kästchen und aus den 8 Nachbarkästchen überprüfen.

Im Grunde braucht man nicht mal eine Hashmap, sondern ein einfaches 2D-Array tut es auch, ist nur u.U. weniger speichereffizient, wenn es größere, Bereiche gibt, die leer stehen.

Ein genereller Nachteil dieser Lösung ist, dass man die Kästchengröße irgendwie von Hand tunen muss.

Geändert von Namenloser ( 8. Dez 2014 um 22:32 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 22:46
Ok. Thanx. Schau ich mir an.

Als letzter Versuch fäll tmir noch das ein? Der Quicksort ist ja unfassbar schnell. Ist das so korrekt?

Delphi-Quellcode:
function SortCompareX(const A, B: TFLoatPoint): integer;
const
  Eps = 1E-4;
begin
  Result := CompareValue(A.X, B.X, Eps);
end;

function SortCompareY(const A, B: TFLoatPoint): integer;
const
  Eps = 1E-4;
begin
  Result := CompareValue(A.Y, B.Y, Eps);
end;

function SortCompareXY(const A, B: TFLoatPoint): integer;
begin
  if SortCompareX(A, B) = 0 then
    Result := SortCompareY(A, B)
  else
    Result := 0;
end;

procedure TFloatPoints.Sort;
begin
  if FCount > 1 then
  begin
    QuickSort(0, FCount - 1, SortCompareX);
    QuickSort(0, FCount - 1, SortCompareXY);
  end;
end;
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 23:21
Ich bezweifel es, aber einen Gegenbeweis kann ich jetzt nicht direkt liefern.

Ein paar Dinge, die man berücksichtigen sollte:
- Du hast bei Quicksort keinen Einfluss darauf, welche Paare miteinander verglichen werden und in welcher Reihenfolge
- Die „Gleichheit“ von Float-Werten ist keine Äquivalenzrelation, die Transitivität ist nicht erfüllt. Also macht es eben wohl einen Unterschied in welcher Reihenfolge die Elemente verglichen werden.
- Quicksort ist nicht stabil. Bei mir schrillen deshalb die Alarmglocken, wenn ich sehe, dass du zwei Sortiervorgänge direkt hintereinander ausführst. Was auch immer du dir davon erhoffst, wird nicht erfüllt sein.

Ich denke, man kann dieses Problem prinzipiell nicht mit eindimensionaler Sortierung lösen, egal was für eine ausgeklügelte Sortierung man sich einfallen lässt.
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Doppel schnell aus Lise löschen.

  Alt 8. Dez 2014, 23:55
Der QuickSort hat die unangenehme Angewohnheit, daß wenn es Beispielsweise in einer Adressenverwaltung 2 Hans Müller in 12345 Berlin gibt, und man die Adressen nach Postleitzahl sortiert, daß einmal der eine und einmal der andere Müller vorne stehen kann. M.E. hat das hier aber keinen Einfluß, weil identisch und hintereinander (Wenn 2 Durchläufe). Ich weiß es aber eben auch nicht genau ..
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Doppel schnell aus Lise löschen.

  Alt 9. Dez 2014, 00:08
Das Ding ist, dass durch deinen zweiten Sortiervorgang der erste theoretisch komplett zunichte gemacht wird. Instabil heißt ja gerade, dass eine wie auch immer geartetet Vorsortierung nicht erhalten bleibt. Wenn der erste Sortiervorgang also irgendeinen Einfluss hat, dann ist das lediglich Zufall, und du kannst dich im Allgemeinen nicht darauf verlassen.
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: Doppel schnell aus Lise löschen.

  Alt 9. Dez 2014, 20:05
Ok. Thanx. Schau ich mir an.

Als letzter Versuch fäll tmir noch das ein? Der Quicksort ist ja unfassbar schnell. Ist das so korrekt?
HybridSort oder RadixSort? Es geht so einiges, wenn man keinen zusätzlichen Code oder Speicher-Verbrauch in Betracht zieht.

Geändert von EgonHugeist ( 9. Dez 2014 um 20:05 Uhr) Grund: Typo
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Doppel schnell aus Lise löschen.

  Alt 9. Dez 2014, 20:39
Ok. Sagt mir aber leider nix.

Hab doch noch Bock.

Ungetestet:

Delphi-Quellcode:
procedure TFloatPoints.RemoveDoubles;
const
  Eps = 1E-4;
var
  X: double;
  I, J: integer;
  NewList, SortList: TFloatPoints;
begin
  NewList := TFloatPoints.Create;
  try
    SortList := TFloatPoints.Create;
    try
      SortByX;
      I := 0;
      while I < FCount do
      begin
        SortList.Clear;
        X := FItems[I].X;
        while (I < FCount) and (SameValue(X, FItems[I].X, Eps)) do
        begin
          SortList.Add(FItems[I]);
          Inc(I);
        end;
        SortList.SortByY;
        for J := SortList.Count - 1 downto 1 do
          if SameFloatPoint(SortList[J], SortList[J - 1]) then
            SortList.Delete(J);
        NewList.AddPoints(SortList);
      end;
      Assign(NewList);
    finally
      SortList.Free;
    end;
  finally
    NewList.Free;
  end;
end;
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Doppel schnell aus Lise löschen.

  Alt 9. Dez 2014, 20:59
Ok. Sagt mir aber leider nix.
Macht nix, google es mal. Radix baut eine zweite Liste auf(Speicher x2) aber die Raten sind unglaublich! Es existieren so einige Radix Übersetzunengen.
Alexandr's HybridSort schlägt die "kleine/niedliche" QuickSort Variante um's 1,5fache. Radix dagegen ... kommt auf den Fall an.. x10 oder viiiel mehr!

@Nameloser: QSort ist in der Lage "unendlich" sogar mit Zufalls Ergebnissen zu arbeiten! e.g. FastCode-Project -> SortBV(Ein validation Test betrachtet diese Variante), Alle noch X-mal schnelleren Interpretationen/Replacements können jedoch nur mit "exakten" Ergebnissen umgehen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz