{"id":2575,"date":"2016-09-14T13:41:00","date_gmt":"2016-09-14T12:41:00","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=2575"},"modified":"2016-09-14T13:41:00","modified_gmt":"2016-09-14T12:41:00","slug":"kategorien-von-algorithmen-implementations-muster-und-fehler","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=2575","title":{"rendered":"Kategorien von Algorithmen Implementations Muster und Fehler"},"content":{"rendered":"<p>Mir ist aufgefallen dass die Implementierung von Algorithmen in verschiedene<br \/>\nKategorien passen. Es geht also nicht um das, was der Algorithmus macht, sondenr<br \/>\nwie er programmiert ist. Die Kategorien sind auch meist Sprach uebergreifend.<\/p>\n<p>Beispiel: segmentTools vertex-collapse<\/p>\n<p>In der derzeitigen Version faellt der Algorithmus in die Kategorie<br \/>\n\"korret, aber nicht vollstaendig\".<br \/>\nDas bedeutet, das Programm bearbeitet die Probleme richtig, aber nicht fuer alle<br \/>\nFaelle. Es fehlen also einige Sonderfallbehandlungen.<\/p>\n<p>Die Kategorie \"Datenabhaenigkeit\" ist sehr komplex und oft untergliedert. Fuer den vertex-collaps<br \/>\nAlgorithmus gilt, dass ein Segment mit mehreren anderen Segmenten zusammen fallen kann. Also<br \/>\neine 1-n Beziehung. Momentan wird immernur eine 1-1 Beziehung bearbeitet.<br \/>\nDaher ist die derzeitige Version auch in der Kategorie \"nicht vollstaenig\". (Gluecklicherweise<br \/>\nkann durch wiederholte Aufrufe des Programms das Problem umgangen werden).<\/p>\n<p>Auch trifft die Kategorie \"langsam - quadratisch Laufzeit\" zu. Das bedeutet einfach,<br \/>\ndass die Berechnung statt Sekunden (mehrere) Tage dauert.<br \/>\nDementsprechend gibt es noch die Kategorie \"schnell - linear logarithmische Laufzeit\".<\/p>\n<p>Um nun den Algorithmen in die Kategorie \"schnell\" zu heben, gibt es einige schon ausgearbeitet<br \/>\nTechniken. Darum den Sweepline Algorithmus. Dieser steuert, auf einer intelligentere Art und Weise,<br \/>\nwelche Segmente der vertex-collapse Algo in welcher Reihenfolge bearbeiten wird. Der Sweepline Algorithmen<br \/>\nbedient sich eines weiteren Algorithmus zum Sortieren von Daten. <\/p>\n<p>Der vertex-collapse Algorithmus faellt also in weitere Kategorien.<br \/>\nEinmal \"Datenabhaenigkeit - Reihenfolge\". Dadurch entstehen weitere Sonderfaelle welche die 1-n Beziehnung noch<br \/>\nverkomplizieren.<\/p>\n<p>Und es gibt zusaetzliche die Kategoie \"Daten Redundanzen\/Kopien\".<br \/>\nHier gibt es zwei aehnliche Faelle.<\/p>\n<p>Fall 1:<br \/>\nUm nicht den orignal Datensatz zu veraendern, macht man in der Regel eine Kopie davon und sortiert ihn dann<br \/>\nmit Sweepline. Das funktioniert bei gro\u00dfen Datensatzen nicht mehr, da hier der RAM oft zu klein ist. (Der<br \/>\nErgebnisdatensatz sollte auch noch in den RAM passen).<\/p>\n<p>Eine g\u00e4ngige Methode um das zu umgehen ist, statt das eigentliche Datenobjekt zu sortieren (das Segment)<br \/>\nwerden nur die IDs sortiert. Aber nicht die ID als Nummer, sondern der (speziell hierfuer angepasster) Sortier Algoritmus greift beim<br \/>\nsortieren ueber die ID auf das Segmente Objekt zurueck und erstellt dementsprechend eine Sortierung der IDs.<\/p>\n<p>Das hat Vorteile und auch viele Nachteile.<\/p>\n<p>Vorteile:<br \/>\n* Der Speicherverbrauch sink. Nehmen wir z.B. ein Segment mit zwei 3D Punkten und doppelter Zahlengenauigkeit.<br \/>\n  2*3*8byte = 48byte pro Segment. Werden stattdessen nur IDs kopiert und sortiert, fallen nur 4byte pro Segment<br \/>\n  zusaetzlich an.<br \/>\n* Die Geschwindigkeit steigt. Im jeder Sortieriteration werden Daten bewegt. Statt 48byte muessen nur 4byte im Ram<br \/>\n  bewegt werden.<\/p>\n<p>Nachteile:<br \/>\n* Nicht jeder Datencontainer kann ueber eine integer ID effizient angesprochen werden. Das funktioniert nur effizent<br \/>\n  bei Vector Containern. Deque, Hash und Sorted Maps sind auch noch moeglich. Bei Listen funktioniert es nicht mehr.<\/p>\n<p>* Nicht jeder Datencontainer kann ueberhaupt ueber eine integer ID angesprochen werden. Oft werden auch andere Typen<br \/>\n  als ID benutzt. Zum Beispiel kurze Strings. Ein Mapping String ID -> Integer ID ist zwar moeglich, kostet aber wieder<br \/>\n  Speicherplat und Geschwindigkeit.<\/p>\n<p>* Die ID Variable enthaelt keine Informationen ueber den Datentype auf den sie verweist. Arbeitet man mit mehreren Datensaetze<br \/>\n  z.B. Segmente und Punkte, so ist es moeglich mit einer Segment ID Variable auf den Punkt Datensatz zuzugreifen ohne<br \/>\n  dass dieser Programmierfehler sofort bemerkt wird.<\/p>\n<p>Fall 2:<br \/>\nDer zweite Fall bezieht sich auf Daten die der Sweepline Algoritmus zwischenspeichert. Auch hier muss wie beim Sortieren<br \/>\nauf die Datenobjekte zugegriffen werden und es entstehen die selben Vor und Nachteile.<\/p>\n<p>Weiterhin muss auch der Sortier Algorithmus darauf hin ausgelegt sein, nicht die eigentlichen Daten zu sortieren, sondern ihre<br \/>\nIDs.<br \/>\nDies fuehrt zu dem Problem, dass der Programmierer des Sort und auch Sweeplines mit einem unbekannten, benutzer definierten,<br \/>\nDatentype arbeiten muss.<br \/>\nDies wurde in C und Fortran dadurch geloest, dass der Benutzer definierte Datentype nur als Pointer von Type void (also<br \/>\nkeine Type Information), oder noch schlimmer: als Typ double, der Sortier Routine uebergeben wurde. Der Algorithmus arbeitet<br \/>\nalso blind aus den Daten und es liegt in der Hoffnung des Programmiers, dass es auch immer funktioniert.<\/p>\n<p>Noch dazu gibt es von C std lib keine Sortierfunktion die zusaetzlich auch IDs beruecksichtigt. Die Routine muss also immer<br \/>\nneu geschrieben werden mit allen Fehlern und Sonderfaelle. Insbesondere bei Fortran. Da es hier nicht mal eine Sortierfunktion<br \/>\nvon der Standardlib selbst gibt.<\/p>\n<p>Das Problem mit den benutzer definierten Datentypen wurde mit der Einfuehrung von C++ im Jahre 1984, und die integierte Template<br \/>\nSprache, geloest.<br \/>\nEs koennen nun abstrakt geschrieben werden und zur Compilierzeit wird der benutzer definierten Datentype eingebaut und entsprechende<br \/>\nFehler vom Compiler weise auf Probleme hin.<\/p>\n<p>Um die Probleme mit den IDs anzugehen kann man als erstes Versuchen satt einer Integer ID, einen Pointer auf das Datenobjeckt zu speichern<br \/>\nund zu sortieren. <\/p>\n<p>Vorteile:<br \/>\n* Es funktionieren nun alle Containertypen.<br \/>\n* Kein Problem mehr mit string IDs, da auf das Datenobjekt selbst zugegriffen wird.<br \/>\n* Keine extra Mapping sortierte ID -> container -> Datenobjekt mehr noetig<br \/>\n* Weiterhin Platzersparnig als wenn eine Kopie des Objekt sortiert wird<\/p>\n<p>Nachteile:<br \/>\n* Pointer verbrauchen auf 64bit Systemen 8byte, also doppelt so viel wie integer IDs<br \/>\n* Pointer koennen invalid sein. Immer ein Check noetig.<br \/>\n* Pointer muessen immer explizit dereferenziert werden um an das Objekt zu gelanden auf das sie zeigen.<\/p>\n<p>Weiterhin muss der Sortierfunktion eine Funktion uebergeben werden, die besagt, wie zwei Pointer Objeckte auf kleiner \"<\" verglichen werden konnen.\nDas ist aber schon immer in C und C++ moeglich. Nur eine Frage der kryptischen Syntax.\n\n\nUm auch die Nachteile der Pointer zu kompensieren, k\u00f6nnen Referenzen genutzt werden. \n\nVorteil: \n* Referenzen sind immer valid.\n* Refreenzen muessen nicht extrea dereferenziert werden.\n\nNachteil:\n* Referenzen brauchen wie Pointer 8byte.\n\nSeit C++ 2011 ist es moeglich auch Referenzen in einem Container zu speichern. Weiterhin gibt es mit Lambdas eine elegante Moeglichkeit\ndie relations Funktion zweite Datenobjekte zu formulieren. Kein kryptischer Code mehr.\n\nSomit bietet C++ seit 2011 die fehlerfreiste und performanteste Moeglichkeit einen Algorithmus schneller durch Sortierung zu machen.\n\nViele Worte, wenig Code. So siehts aus:\n\n\n\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mir ist aufgefallen dass die Implementierung von Algorithmen in verschiedene Kategorien passen. Es geht also nicht um das, was der Algorithmus macht, sondenr wie er programmiert ist. Die Kategorien sind auch meist Sprach uebergreifend. Beispiel: segmentTools vertex-collapse In der derzeitigen Version faellt der Algorithmus in die Kategorie \"korret, aber nicht vollstaendig\". Das bedeutet, das Programm [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17],"class_list":["post-2575","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2575","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2575"}],"version-history":[{"count":1,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2575\/revisions"}],"predecessor-version":[{"id":2576,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2575\/revisions\/2576"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2575"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2575"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}