C++Guns – RoboBlog blogging the bot

21.01.2017

How do I sort two vectors containing relative entries, using STL?

Filed under: Allgemein — Tags: — Thomas @ 11:01

How do I sort two vectors containing relative entries, using STL? [1]

Da ich mir kein Account auf stackoverflow machen konnte, (ka. warum es passierte einfach nichts), gibt es jetzt hier die richtige Antwort.
Der Ansatz von Nikos Athanasiou war schon richtig, leider total krank programmiert und mit zu vielen Schleifen. So hat der Algo. quatratische Laufzeit und ist unbrauchbar fuer grosse Datenmengen.
Ich uebernehme seinen Ansatz und tausche nur die Funktion rearrange_vector() aus. So ergibt sich eine linear-logaritmische Laufzeit dominiert durch die Sortierung. Und einen linearen Speicherverbrauch. Da aber nur integer indices gespeichert werden, ist der Zusatzverbraucht sehr gering. Gerade einmal 4byte pro Namen. Also ca. 4MB pro eine Millionen Namen. Das sollte nun wirklich niemand stören.


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>

using namespace std;

void rearrange_vector(const vector<int> indices, vector<string> &v) {
    for(int idx1=0; idx1 < v.size(); ++idx1) {
        int idx2 = indices[idx1];
        // nur dann tauschen, wenn nicht schonmal getauscht wurde,
        // und wenn ein tausch ueberhaupt notwenig ist
        if(idx2 > idx1) {
            swap(v[idx1], v[idx2]);
        }
    }
}

int main() {
    // 1. Problem space
    vector<string> firstnames = {"Dennis",  "Alexander", "Bjarne",      "James",   "James" };
    vector<string> lastnames  = {"Ritchie", "Stepanov",  "Stroustrup",  "Coplien", "Gosling" };

    // 2. vector of indices - sorted according to the order of firstnames
    vector<int> indices(firstnames.size());
    // create sequenz 0,1,2,3,...
    iota(begin(indices), end(indices), 0);

    sort(begin(indices), end(indices), [&](int i1, int i2) {
        return firstnames[i1] < firstnames[i2];
    });

    // debug
    cout << "Sorted indices\n";
    for(auto i : indices) {
        cout << i << " ";
    }
    cout << "\n";

    // 3. rearrangement according to the sorted indices
    rearrange_vector(indices, firstnames);
    rearrange_vector(indices, lastnames);

    // 4. print results
    for (size_t i=0; i < indices.size(); ++i) {
        cout << firstnames[i] << " " << lastnames[i] << endl;
    }

    return 0;
}

[1] http://stackoverflow.com/questions/25085015/how-do-i-sort-two-vectors-containing-relative-entries-using-stl

18.01.2017

Dachschaden

Filed under: Allgemein — Thomas @ 12:01

Der letzte Sturm hat zum ersten mal Ziegel runter gerissen. Drei Stück sind in den Hof geklatscht. Zum Glück nichts weiter passiert.

dachschaden2

dachschaden1

17.01.2017

Alle Aktoren per Hand steuerbar

Filed under: Allgemein — Tags: , — Thomas @ 09:01

Alle Weichen und Signale können nun per Hand ferngesteuert werden. Ein großes Zwischenziel auf dem Weg hin zur automatischen Steuerung wurde erreicht!
Das ist aber auch wirklich komfortabel. Man muss den Tisch nicht mehr vor rücken, einmal drumherum laufen und aufpassen, dass keine Kühe und Menschen beschädigt werden, wenn einfach nur die Weiche umgeschaltet werden soll. Auch das Signal kann nun bequem vom Sitzen aus gesteuert werden. Nur der Fahrstrom ist noch nicht durch das Signal geleitet. Aus Platzgründen (der liebe Gott hat den Berg nun einmal so eng erschaffen) konnte nur ein Signal für zwei Bahnsteige gebaut werden. Daher muss der Fahrstrom je nach Weichenstellung umgeschaltet werden. Und die Lokführer müssen ein wenig mehr aufpassen, wer nun fahren darf ;)

bergbahnhofsignal1

bergbahnhofsignal2

14.01.2017

Compile Icecat

Filed under: Allgemein — Tags: — Thomas @ 16:01

Get the source

wget http://mirror.gutscheinrausch.de/gnu/gnuzilla/45.5.1/icecat-45.5.1-gnu1.tar.bz2
tar xjf icecat-45.5.1-gnu1.tar.bz2
mkdir build-icecat-45.5.1

Install dependencies

apt-get install libgtk2.0-dev libgconf2-dev libdbus-glib-1-dev yasm libasound2-dev libpulse-dev libxt-dev

Perhaps you need these too

libnotify-dev libiw-dev mesa-common-dev checkinstall

Configure and compile

../icecat-45.5.1/configure --prefix=/home/kater/bin/icecat-45.5.1 --disable-gstreamer
make

gstreamer is bad software, like systemd, written from mental health people. So disable it.
You may have to correct [:space:] to [[:space:]] in the configure script.
And you may need to


cd icecat-45.5.1/browser/branding/
ln -s official/ unofficial

http://www.gnewsense.org/Documentation/3/MiscellaneousGuides/CompileGnuIcecatSeventeen

Trouble

mozalloc.h: In function ‘void* operator new(size_t, const std::nothrow_t&)’:
mozalloc.h:192:28: error: ‘malloc’ was not declared in this scope

Fixed in 48 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=822716
Use an older compiler version.

CXX=g++-5 CC=gcc-5 ../icecat-45.5.1/configure --prefix=/home/kater/bin/icecat-45.5.1 --disable-gstreamer

25.12.2016

Weihnachtseisenbahn 2016

Filed under: Allgemein — Tags: , — Thomas @ 10:12

Klein, aber fährt vor und zurückimg_6712

22.12.2016

sizeof(int)

Filed under: Allgemein — Tags: — Thomas @ 00:12

According to N3337

3.9.1 Fundamental types [basic.fundamental]
2
There are five standard signed integer types : “signed char”, “short int”, “int”, “long int”, and “long
long int”. In this list, each type provides at least as much storage as those preceding it in the list.
There may also be implementation-defined extended signed integer types. The standard and extended signed
integer types are collectively called signed integer types. Plain ints have the natural size suggested by the
architecture of the execution environment 44
; the other signed integer types are provided to meet special
needs.

44) ) that is, large enough to contain any value in the range of INT_MIN and INT_MAX, as defined in the header .

Thus
sizeof(short) <= sizeof(int) <= sizeof(long) Thx 2 m$ 4 <= instead of < ;)

18.12.2016

Das neue Uptime-Project

Filed under: Allgemein — Tags: — Thomas @ 22:12

Uptime-Chart

Sounds like fun.

26.09.2016

Bilder der 2qm Anlage

Filed under: Allgemein — Tags: , — Thomas @ 12:09

img_6612_1
Gesamtansicht

img_6613_1
Bahnhof Nieder Ramstadt

img_6614_1
Tunneleingang Pendelzugstrecke

Tunneleingang der Hauptstrecke
Tunneleingang der Hauptstrecke

img_6616_1
Weiche zu den Abstellgleisen

img_6617_1
Ragiergleis hinter dem Gemüsegarten

img_6619_1
Im Pendelzugtunnel

img_6620_1
Pendelzug Brücke

img_6621_1
Signale HBf

img_6622_1
HBf mit D-Zug

img_6623_1
HBf Luftaufnahme

14.09.2016

Kategorien von Algorithmen Implementations Muster und Fehler

Filed under: Allgemein — Tags: — Thomas @ 13:09

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 bearbeitet die Probleme richtig, aber nicht fuer alle
Faelle. Es fehlen also einige Sonderfallbehandlungen.

Die Kategorie "Datenabhaenigkeit" ist sehr komplex und oft untergliedert. Fuer den vertex-collaps
Algorithmus gilt, dass ein Segment mit mehreren anderen Segmenten zusammen fallen kann. Also
eine 1-n Beziehung. Momentan wird immernur eine 1-1 Beziehung bearbeitet.
Daher ist die derzeitige Version auch in der Kategorie "nicht vollstaenig". (Gluecklicherweise
kann durch wiederholte Aufrufe des Programms das Problem umgangen werden).

Auch trifft die Kategorie "langsam - quadratisch Laufzeit" zu. Das bedeutet einfach,
dass die Berechnung statt Sekunden (mehrere) Tage dauert.
Dementsprechend gibt es noch die Kategorie "schnell - linear logarithmische Laufzeit".

Um nun den Algorithmen in die Kategorie "schnell" zu heben, gibt es einige schon ausgearbeitet
Techniken. Darum den Sweepline Algorithmus. Dieser steuert, auf einer intelligentere Art und Weise,
welche Segmente der vertex-collapse Algo in welcher Reihenfolge bearbeiten wird. Der Sweepline Algorithmen
bedient sich eines weiteren Algorithmus zum Sortieren von Daten.

Der vertex-collapse Algorithmus faellt also in weitere Kategorien.
Einmal "Datenabhaenigkeit - Reihenfolge". Dadurch entstehen weitere Sonderfaelle welche die 1-n Beziehnung noch
verkomplizieren.

Und es gibt zusaetzliche die Kategoie "Daten Redundanzen/Kopien".
Hier gibt es zwei aehnliche Faelle.

Fall 1:
Um nicht den orignal Datensatz zu veraendern, macht man in der Regel eine Kopie davon und sortiert ihn dann
mit Sweepline. Das funktioniert bei großen Datensatzen nicht mehr, da hier der RAM oft zu klein ist. (Der
Ergebnisdatensatz sollte auch noch in den RAM passen).

Eine gängige Methode um das zu umgehen ist, statt das eigentliche Datenobjekt zu sortieren (das Segment)
werden nur die IDs sortiert. Aber nicht die ID als Nummer, sondern der (speziell hierfuer angepasster) Sortier Algoritmus greift beim
sortieren ueber die ID auf das Segmente Objekt zurueck und erstellt dementsprechend eine Sortierung der IDs.

Das hat Vorteile und auch viele Nachteile.

Vorteile:
* Der Speicherverbrauch sink. Nehmen wir z.B. ein Segment mit zwei 3D Punkten und doppelter Zahlengenauigkeit.
2*3*8byte = 48byte pro Segment. Werden stattdessen nur IDs kopiert und sortiert, fallen nur 4byte pro Segment
zusaetzlich an.
* Die Geschwindigkeit steigt. Im jeder Sortieriteration werden Daten bewegt. Statt 48byte muessen nur 4byte im Ram
bewegt werden.

Nachteile:
* Nicht jeder Datencontainer kann ueber eine integer ID effizient angesprochen werden. Das funktioniert nur effizent
bei Vector Containern. Deque, Hash und Sorted Maps sind auch noch moeglich. Bei Listen funktioniert es nicht mehr.

* Nicht jeder Datencontainer kann ueberhaupt ueber eine integer ID angesprochen werden. Oft werden auch andere Typen
als ID benutzt. Zum Beispiel kurze Strings. Ein Mapping String ID -> Integer ID ist zwar moeglich, kostet aber wieder
Speicherplat und Geschwindigkeit.

* Die ID Variable enthaelt keine Informationen ueber den Datentype auf den sie verweist. Arbeitet man mit mehreren Datensaetze
z.B. Segmente und Punkte, so ist es moeglich mit einer Segment ID Variable auf den Punkt Datensatz zuzugreifen ohne
dass dieser Programmierfehler sofort bemerkt wird.

Fall 2:
Der zweite Fall bezieht sich auf Daten die der Sweepline Algoritmus zwischenspeichert. Auch hier muss wie beim Sortieren
auf die Datenobjekte zugegriffen werden und es entstehen die selben Vor und Nachteile.

Weiterhin muss auch der Sortier Algorithmus darauf hin ausgelegt sein, nicht die eigentlichen Daten zu sortieren, sondern ihre
IDs.
Dies fuehrt zu dem Problem, dass der Programmierer des Sort und auch Sweeplines mit einem unbekannten, benutzer definierten,
Datentype arbeiten muss.
Dies wurde in C und Fortran dadurch geloest, dass der Benutzer definierte Datentype nur als Pointer von Type void (also
keine Type Information), oder noch schlimmer: als Typ double, der Sortier Routine uebergeben wurde. Der Algorithmus arbeitet
also blind aus den Daten und es liegt in der Hoffnung des Programmiers, dass es auch immer funktioniert.

Noch dazu gibt es von C std lib keine Sortierfunktion die zusaetzlich auch IDs beruecksichtigt. Die Routine muss also immer
neu geschrieben werden mit allen Fehlern und Sonderfaelle. Insbesondere bei Fortran. Da es hier nicht mal eine Sortierfunktion
von der Standardlib selbst gibt.

Das Problem mit den benutzer definierten Datentypen wurde mit der Einfuehrung von C++ im Jahre 1984, und die integierte Template
Sprache, geloest.
Es koennen nun abstrakt geschrieben werden und zur Compilierzeit wird der benutzer definierten Datentype eingebaut und entsprechende
Fehler vom Compiler weise auf Probleme hin.

Um die Probleme mit den IDs anzugehen kann man als erstes Versuchen satt einer Integer ID, einen Pointer auf das Datenobjeckt zu speichern
und zu sortieren.

Vorteile:
* Es funktionieren nun alle Containertypen.
* Kein Problem mehr mit string IDs, da auf das Datenobjekt selbst zugegriffen wird.
* Keine extra Mapping sortierte ID -> container -> Datenobjekt mehr noetig
* Weiterhin Platzersparnig als wenn eine Kopie des Objekt sortiert wird

Nachteile:
* Pointer verbrauchen auf 64bit Systemen 8byte, also doppelt so viel wie integer IDs
* Pointer koennen invalid sein. Immer ein Check noetig.
* Pointer muessen immer explizit dereferenziert werden um an das Objekt zu gelanden auf das sie zeigen.

Weiterhin muss der Sortierfunktion eine Funktion uebergeben werden, die besagt, wie zwei Pointer Objeckte auf kleiner "<" verglichen werden konnen. Das ist aber schon immer in C und C++ moeglich. Nur eine Frage der kryptischen Syntax. Um auch die Nachteile der Pointer zu kompensieren, können Referenzen genutzt werden. Vorteil: * Referenzen sind immer valid. * Refreenzen muessen nicht extrea dereferenziert werden. Nachteil: * Referenzen brauchen wie Pointer 8byte. Seit C++ 2011 ist es moeglich auch Referenzen in einem Container zu speichern. Weiterhin gibt es mit Lambdas eine elegante Moeglichkeit die relations Funktion zweite Datenobjekte zu formulieren. Kein kryptischer Code mehr. Somit bietet C++ seit 2011 die fehlerfreiste und performanteste Moeglichkeit einen Algorithmus schneller durch Sortierung zu machen. Viele Worte, wenig Code. So siehts aus:

28.08.2016

Snapshots der 2qm Anlage

Filed under: Allgemein — Tags: , — Thomas @ 20:08

Grillplatz mit Teich

IMG_6435

IMG_6437

IMG_6438

Verlaufende Kuh.

IMG_6439

Man beachte die feinen Strukturen auf der Tür, welche dem Auge von Oben bisher immer unsichtbar waren.

IMG_6440

Pendelzug Lok zwischen den Pfeilen der großen Brücke zur Abfahrt bereit.

IMG_6441

IMG_6442

Der Baum ist nicht einfach nur grün. Er hat Millimeter feine Farbtupfern an den Zweigen.

IMG_6443

IMG_6444

IMG_6445

IMG_6446

IMG_6447

IMG_6448

IMG_6449

IMG_6450

IMG_6451

IMG_6452

IMG_6453

IMG_6454

IMG_6455

IMG_6456

« Newer PostsOlder Posts »

Powered by WordPress