AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign FreePascal Schnittmenge von mehreren Mengen ermitteln

Schnittmenge von mehreren Mengen ermitteln

Offene Frage von "Horst_"
Ein Thema von Laser · begonnen am 11. Mär 2012 · letzter Beitrag vom 21. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2   
Furtbichler
(Gast)

n/a Beiträge
 
#1

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 07:09
@Furtbichler:
Dafür müssten alle Dateien komplett gelesen werden oder?
Meinst Du "komplett in den RAM"? Nein.
Meinst Du "komplett"? Ja, wie willst Du sonst die Schnittmenge ermitteln?

Jede Binärsuche ist vom Aufwand O(log n), jede Suche in einer Hashmap O(1).

Das nur mal so am Rande.

Geändert von Furtbichler (12. Mär 2012 um 07:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von patti
patti

Registriert seit: 20. Okt 2004
Ort: Mittelfranken
665 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 11:14
Jede Binärsuche ist vom Aufwand O(log n), jede Suche in einer Hashmap O(1).

Das nur mal so am Rande.
Das Problem wird hier nicht die Suche an sich sein, sondern das Laden von der Platte (langsames I/O...). Bei deinem Ansatz müssen zuerst alle Daten von der Platte gelesen werden (und zwar sicher *alle*), zusätzliche müssen sie dann noch in eine Hashtable geschmissen werden, und erst dann beginnt die Suche (das mag in O(1) klappen, aber vorher ging schon sehr viel Zeit für das Laden drauf...). Die Idee mit der Binär-Suche ist ja gerade, nicht alle Elemente lesen zu müssen. Mein Ansatz liest zwar auch (im schlimmsten Fall) alle Elemente ein, allerdings hab ich den Overhead von 'ner Hashtable nicht (O(1) ist nicht gleich O(1)...).

lg
Patrick Kreutzer
[Informatik-Student im 4. Semester]
http://www.patti-k.de/
  Mit Zitat antworten Zitat
Horst_

Registriert seit: 22. Jul 2004
Ort: Münster Osnabrück
116 Beiträge
 
#3

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 13:28
Hallo,

Das Problem wird hier nicht die Suche an sich sein, sondern das Laden von der Platte (langsames I/O...). Bei deinem Ansatz müssen zuerst alle Daten von der Platte gelesen werden (und zwar sicher *alle*)
Darum wird fast kaum herum kommen, alle einzulesen, selbst bei Deinem Verfahren http://www.delphipraxis.net/1156016-post2.html
Hier etwas abgewandelt
Code:
- feststellen der Anzahl der Datensätze in den n Dateien
 - Anzahl dieser Datensätze sortieren, ergibt Dateien n1... <... n12, n1 enthält wenigste Datensätze, n12 die meisten
 - n1 -> tmp
 - wiederhole für Datei = n2 bis n12
 --tmpIndex = 0, DateiIndex = 0
 --wiederhole solange (TmpIndex noch nicht maximal) ODER (DateiIndex noch nicht maximal )
 ---Falls tmp(tmpIndex)=Datei(DateiIndex)=>
 ----Schreibe Schluessel nach Out
 ----tmpIndex= tmpIndex+1
 ----DateiIndex= DateiIndex+1
 ---sonst
 ----Solange (tmp(tmpIndex)<Datei(DateiIndex)) UND (TmpIndex noch nicht maximal)
 -----tmpIndex= tmpIndex+1
 ----Solange (tmp(tmpIndex)>Datei(DateiIndex)) UND (DateiIndex noch nicht maximal )
 -----DateiIndex= DateiIndex+1
 --
 -- tmp löschen
 -- out in tmp umbennen
 -
 - tmp in out umbennen
->EDIT: @Laser<-
Das hin- und herspringen in einer 50 MB Datei zum Beispiel
zu Beginn von Mitte dann 0.25 dann 0.125 ..
zum Ende von Mitte dann 0.75 dann 0.875..
ist ja auch nicht das schnellste, ausser man hat wirklich nur noch wenige Elemente in der Restliste.
Aber vielleicht lässt sich das ja nutzen, indem man sich die Position/Schlüssel also den Weg merkt.
Selbst 2^32 Schluessel haben bei binärer Suche nur 32 Wegpunkte.

Gruß Horst

Geändert von Horst_ (12. Mär 2012 um 15:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von patti
patti

Registriert seit: 20. Okt 2004
Ort: Mittelfranken
665 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 13:36
Darum wird fast kaum herum kommen, alle einzulesen, selbst bei Deinem Verfahren http://www.delphipraxis.net/1156016-post2.html
Schon klar, siehe mein Post oben:

Verstehe ich Deinen Pseudocode richtig, dass nahe zu alle Schlüssel von der Platte gelesen werden?
Im schlimmsten Fall, ja.


Das hin- und herspringen in einer 50 MB Datei zum Beispiel
zu Beginn von Mitte dann 0.25 dann 0.125 ..
zum Ende von Mitte dann 0.75 dann 0.875..
ist ja auch nicht das schnellste
Was aber ja bei meinem Ansatz nicht der Fall ist
Patrick Kreutzer
[Informatik-Student im 4. Semester]
http://www.patti-k.de/
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#5

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 14:10
Da die Daten sortiert vorliegen, würde mir folgendes Vorgehen einfallen:
Alle Dateien öffnen und den Datensatzzeiger auf Anfang stellen von jeder Datei.

1)
alle Datensätze wo der Zeiger steht vergleichen
-wenn gleich dann ist es eine Schnittmenge in allen Dateien -> merken/ausgeben -> Alle Zeiger einen weiterschieben.

Jeweils den Datensatzzeiger weiterschieben, wo der aktuelle Datensatz der kleinste von den gerade gelesen ist. Wenn mehrere gleich sind alle weiterschieben.

Springe zu 1)
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Laser

Registriert seit: 1. Jan 2009
Ort: Ubunutu 10.10
18 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 20:42
Moin,
Da die Daten sortiert vorliegen, würde mir folgendes Vorgehen einfallen:
Alle Dateien öffnen und den Datensatzzeiger auf Anfang stellen von jeder Datei.

1)
alle Datensätze wo der Zeiger steht vergleichen
-wenn gleich dann ist es eine Schnittmenge in allen Dateien -> merken/ausgeben -> Alle Zeiger einen weiterschieben.

Jeweils den Datensatzzeiger weiterschieben, wo der aktuelle Datensatz der kleinste von den gerade gelesen ist. Wenn mehrere gleich sind alle weiterschieben.

Springe zu 1)
wenn ich das richtig verstehe, wird hier sehr viel von Platte gelesen. Vor allem werden die Dateien n3...nx gelesen, wenn man nach dem Lesen von n1 und n2 teilweise schon feststellen kann, dass eine Identität bzw. Schnittmenge über alle nicht mehr möglich ist.

Einzelne Schlüssel zu lesen, bremst ziemlich aus. Das wurde hier gut beschrieben:
http://www.delphipraxis.net/1156224-post17.html
Liebe Grüße
Laser
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#7

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 21:19
Wie wäre es mit einer Kombination?

Erstmal die zwei kleinsten Dateien in den Speicher laden, und die Schnittmenge bilden. (Mit zwei Indizes, wie von generic erklärt)
Danach immer die nächste Datei in den Speicher laden und die bisherigen Einträge per binärer Suche in der Datei suchen.

Das laden der Datei könnte man noch in einen Thread auslagern. Ist aber fraglich ob sich das lohnt - die Datenmenge klingt nach einer Rechenzeit von 300ms. Die Synchronisation von Threads könnte das schon wieder verlangsamen.

Damit sollte die Schnittmenge schnell kleiner werden (damit die binäre Suche flott ist) aber am Anfang dürfte das Verfahren mit den zwei Indizes besser sein. Und solange es geht immer im RAM arbeiten, und keine einzelnen Werte von der Platte lesen! Damit kann man jeden Algorithmus zum Schneckentempo zwingen. (ggf. ein Bandlaufwerk in Erwägung ziehen....)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#8

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 21:22
Bei Sprüngen würde ich mit Memory Mapped Files arbeiten. Damit überlässt du das Lesen aus der Datei dem Betriebssystem und das ist ein Bereich, in den die Betriebssystemler ewig rumoptimieren. Davon kannst du nur profitieren.
Deshalb könnte das auch einen Geschwindigkeitsschub geben, wenn du einen Ansatz ohne Sprünge wählst.

Ich persönlich würde allgemein einen der Ansätze wählen, die die Dateien gleichzeitig fortlaufend durchgehen.

Aber mit den fortlaufenden Zahlen könntest du den Aufwand vermutlich auf die Größe der kleinsten Datei drücken, mehr Informationen (oder vielleicht ein Beispiel) wären schön.
  Mit Zitat antworten Zitat
Laser

Registriert seit: 1. Jan 2009
Ort: Ubunutu 10.10
18 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 20:31
Moin,
Hallo,
->EDIT: @Laser<-
Das hin- und herspringen in einer 50 MB Datei zum Beispiel
zu Beginn von Mitte dann 0.25 dann 0.125 ..
zum Ende von Mitte dann 0.75 dann 0.875..
ist ja auch nicht das schnellste, ausser man hat wirklich nur noch wenige Elemente in der Restliste.
Aber vielleicht lässt sich das ja nutzen, indem man sich die Position/Schlüssel also den Weg merkt.
Selbst 2^32 Schluessel haben bei binärer Suche nur 32 Wegpunkte.
Ich habe das noch nicht vertieft. Es wird keine übliche binäre Suche sein, bei der das Intervall in der Mitte geteilt wird. Statt dessen wird ein Sprungziel aus dem 64-Bit Schlüssel berechnet.

Die unteren 32 Bit des Schlüssels enthalten eine fortlaufende Zahl. Damit kann ein gutes Sprungziel berechnet werden, was die Plattenzugriffe noch einmal reduziert.
Liebe Grüße
Laser
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#10

AW: Schnittmenge von mehreren Mengen ermitteln

  Alt 12. Mär 2012, 20:40
Bin mal gespannt, wie schnell ihr mit eurem Rumgehüpfe seid.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 18:20 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