SwingX-WS mit JXMapKit auf der SIGMOD 2010 / PAROS: Pareto Optimal Route Selection

Zusammen mit meinen Kollegen haben wir eine Demo auf einer der wichtigsten Datenbank Konferenzen eingereicht, die ich letzte Woche in Indianapolis auf der SIGMOD (ACM Special Interest Group on Management of Data) zeigen durfte. Die Demo firmiert übrigens unter dem Titel PAROS: Pareto Optimal Route Selection.

Im Wesentlichen ging es dabei darum, einen von meinen Kollegen entwickelten Skyline-Algorithmus auf Straßennetzen anzuwenden um damit Wege unter mehreren Einschränkungen zu finden. Die klassische, einfache Wegsuche ist ja zum Beispiel “finde den kürzesten oder schnellsten Weg”. Bei der Skyline-Abfrage, geht es dabei darum, alle die Wege zu finden, die unter mehreren Attributen optimal sind. Also zum Beispiel alle kürzesten und schnellsten Wege, die gleichzeitig möglichst wenig Ampeln enthalten. Es müssen also mehrere Attribute gleichzeitig optimiert werden.

Da Datenmasse in der Wissenschaft oft Mangelware ist, habe ich zusammen mit etwas studentischer Hilfe einen Konverter für OpenStreetMap-Daten geschrieben um beliebig viele Daten erhalten zu können. Visualisiert wurde das Ganze mit Hilfe der JXMapKit-Komponente aus SwingX-WS! Die Gui-Entwicklung ging dank dem NetBeans Gui-Builder wie erwartet erfreulich einfach, so dass ich mich in der knappen Zeit auf die Integration des Algorithmus und auf die Architektur konzentrieren konnte. Die Architektur sollte es ermöglichen, Model und View  möglichst so zu kapseln, dass die Entwicklung und Integration neuer Algorithmen so einfach wie möglich und möglichst Unabhängig von jeglicher GUI-Programmierung ist, so dass auch Studenten schnell und einfach neue Algorithmen entwickeln und testen können.

Ich habe zwar (wie erwartet) nicht den Best-Demo-Preis bekommen, allerdings waren wirklich viele interessierte Leute auf den Demo-Sessions. Überrascht hat mich, dass ich sehr oft gefragt wurde, ob wir die Demo online stellen würden, bzw. ob die Demo OpenSource ist. Nach Rücksprache mit den Kollegen, kamen wir zu dem Schluss, dass das eine gute Idee sei und ich das machen werde. Ich werde in den nächsten Wochen also noch etwas den Code aufräumen, dokumentieren, online stellen und hoffen, dass jemand die Demo interessant und nützlich findet – vielleicht sogar so, dass es die Basis für ein oder mehre Zitationen bringt (ist immer wichtig bei Veröffentlichungen).

UPDATE: endlich ist der – äh – unschöne Code online. Da ich auch in absehbarer Zeit nicht die Zeit habe, ihn schön sauber und dokumentiert zu machen, kann ich ihn auch gleich online stellen. zum Download gehts hier lang.

Relevante Links:

Windows 7 (64bit) Druckerfreigabe mit XP Client (Canon i250)

Szenario:
An einem Windows 7, 64 Bit, soll der angeschlossenem Drucker über das Netz freigegeben werden.
Ein Windows XP, 32Bit, soll die Freigabe in Anspruch nehmen.

Problem:
Beim Verbinden des Druckers wird auf Windows XP-Seite eine Warnung ausgegeben, dass der Server keine Treiber zur Verfügung stellt.

Lösung:
Wie erwartet war ich nicht der einzige mit dem Problem. Die Lösung fand ich dann im computerbase-Forum.
Im Prinzip muss man Windows 7 “nur” beibringen, dass es auch einen 32Bit-Treiber anbieten soll.  Das funktioniert so, dass man den Windows 32bit-Treiber vom Druckerhersteller herunterlädt und am Drucker registriert: “Geräte und Drucker – *Druckername* – Druckereigenschaften – Freigabe – Zusätzliche Treiber”.

In der Praxis kommt es dann ab und an vor, dass genau das nicht funktioniert, weil der Drucker dann nicht gefunden werden kann und man eine Meldung erhält, dass kein Treiber für <Druckername> gefunden werden konnte. Wie im computerbase-Forum beschrieben, ist hier Handarbeit nötig. Die entpackten Treiber enthalten eine .inf-Datei. Diese muss man im Texteditor öffnen und den Druckernamen so abändern, dass der Name identisch mit dem Windows7-Druckernamen ist (also genau der Name, der in der Fehlermeldung genannt ist).

Im Falle meines Canon i250 sehen die betreffenden Zeilen der .inf-Datei dann so aus:

;WindowsXP
[Canon.NTx86.5.1]
"Canon Inkjet i250" = CNMI250XP, LPTENUMCanoni250F027, Canoni250
"Canon Inkjet i250" = CNMI250XP, USBPRINTCanoni250F027, Canoni250

“Canon Inkjet i250” ist dabei der Name des Druckers in Windows 7. Datei speichern und nochmal via “Geräte und Drucker – *Druckername* – Druckereigenschaften – Freigabe – Zusätzliche Treiber” installieren. Sofern das funktioniert, kann man den Drucker dann (sofern die Freigabe richtig eingestellt wurde) von Windows XP aus nutzen.

Sinn und Unsinn von E-Mail- und Link-Disclaimern

Wieder eine Mail erhalten mit dem zweifelhaften Text

Diese E-Mail und alle angehängten Dateien enthalten streng vertrauliche Informationen und sind lediglich für den/die in der Adressleiste genannte(n) Person(en) bestimmt. Sollte diese E-Mail bzw. deren Anhänge an Dritte und/oder nicht in der Adressleiste genannte Personen gelangen,  […]

Ich hab’ diesem Disclaimern ja noch nie wirklich vertraut. Ein Artikel bei heise (Disclaimer: Unnötiger Ballast für E-Mails) bestätigt die Vermutung, dass diese Disclaimer bei uns in Deutschland nicht wirksam sind. – Ebenso wie diese widersinnigen Distanzierungen von Links:

Mit Urteil vom 12. Mai 1998 hat das Landgericht Hamburg entschieden, daß man durch die Ausbringung eines Links […]

Auch hier gibt es eigentlich diverse Seiten, die erklären, dass das Urteil vom LG Hamburg eben genau das nicht tut, was die Links versprechen: und zwar den Seitenbetreiber schützen. Mehr Informationen gibt es unter anderem auf diesen Seiten:

Wegpunkte mit JXMapKit zeichnen

Im Artikel “Erste Schritte mit JavaX JXMapKit” habe ich schon kurz beschrieben, wie man mit NetBeans und SwingX-WS schnell und einfach eine Kartendarestllung á la GoogleMaps in Java bauen kann.

Wenn man nicht nur eine Karte anzeigen sondern auch Punkte einzeichnen will, hat man die Möglichkeiten, per jXMapKit.setAddressLocation(new GeoPosition(lat, lon)); die Koordinaten setzen, zeichnen und die Karte dorthin zentrieren. Allerdings wird die Karte damit auch immer gleich zentriert und vor allem kann man nur einen einzelnen Punkt setzen.

Mehrere Wegpunkte setzt man mithilfe des WaypointPainters:

Set set = new HashSet();
WaypointPainter waypointPainter = new WaypointPainter();
waypointPainter.setWaypoints(set);
set.add(new Waypoint(47.76098, 11.55932));
jXMapKit.getMainMap().setOverlayPainter(waypointPainter);
repaint();

Das repaint() am Ende sollte immer erfolgen, wenn neue Punkte in das Set gesetzt werden, damit die Änderung auch sofort sichtbar ist. Andernfalls muss man die Karte etwas verschieben um ein repaint zu erzwingen. Will man jetzt noch die Darstellung der Wegpunkte verändern, muss man sich noch mit dem WaypointRenderer beschäftigen.

Java Heap-Implementierung / Avoid too much sorting II

Im Artikel Avoid too much sorting habe ich ja schon kurz skizziert, dass man es generell vermeiden sollte seine Daten unnötig oft zu sortieren, weil das einfach (je nachdem wie oft der entsprechende Code aufgerufen wird) ziemlich in die Rechenzeit gehen kann.

Manchmal muss man seine Daten aber eben sortiert halten. – Dann sollte man sich aber überlegen, ob man wirklich die ganzen Daten sortieren muss, oder ob es nicht einfach reicht, immer das kleinste/größte Element einer Menge zu bekommen. Ein gutes Beispiel ist zum Beispiel der altbekannte Dijkstra-Algorithmus. Dort benötigt man in jeder Iteration z.B. den Weg mit den bisher kleinsten Kosten.

Das schreit ja schon nach Sortieren. Bzw. eigentlich sollte einem da gleich die Heap-Datenstruktur einfallen, da dort alle Operaionen maximal in O(log n) erledigt sind, und nicht (wie beim Sortieren) in bis zu O(n²). Das schöne daran ist, dass es das in Java auch schon gibt, da heißt es nur nicht Heap (da man dabei vermutlich zu sehr an die Speicherverwaltung denken könnte), sondern PriorityQueue.

Wenn man jetzt aber Objekte sortieren will die nicht per se Comparable sind, benötigt man noch eine kleine Comparator-Implementierung mit einem SimpleEntry, damit man einem beliebigem Objekt auch seine Kosten zuweisen kann. Klingt jetzt recht aufwändig – ist es aber bei weitem nicht:

import java.util.AbstractMap.SimpleEntry;
import java.util.Comparator;
import java.util.PriorityQueue;

public class Test {
    public static void main(String[] args) {
        PriorityQueue<SimpleEntry> heap =
                new PriorityQueue<SimpleEntry>(10, new FooCmp());
        heap.add(new SimpleEntry(1d, new Foo(1)));
        heap.add(new SimpleEntry(5d, new Foo(2)));
        heap.add(new SimpleEntry(2d, new Foo(3)));
        while (!heap.isEmpty()) {
            System.out.println(heap.poll().getValue().i);
        }
    }
}

class FooCmp implements Comparator<SimpleEntry> {
    @Override
    public int compare(SimpleEntry o1, SimpleEntry o2) {
        return Double.compare(o1.getKey(), o2.getKey());
    }
}

class Foo {
    int i;
    Foo(int i) { this.i = i; }
}

JXMapKit: Karten schneller und gleichzeitig laden

Verschiebt man die Karte eines JXMapKit, müssen ja logischerweise Kartenteile (Kacheln) nachgeladen werden.
Per Default werden immer nur 4 Kacheln gleichzeitg geladen. Bei entsprechend schneller Verbindung macht es durchaus Sinn, diese Zahl zu erhöhen:

((AbstractTileFactory) jXMapKit.getMainMap().getTileFactory()).setThreadPoolSize(10);

Und schon wird spürbar schneller nachgeladen. Allerdings muss der Aufruf durchgeführt werden, bevor die erste Kachel geladen wird, wie die Javadoc aussagt:

/**
* Set the number of threads to use for loading the tiles. This controls the number of threads
* used by the ExecutorService returned from getService(). Note, this method should
* be called before loading the first tile. Calls after the first tile are loaded will
* have no effect by default.
* @param size
*/

Siehe auch: “Erste Schritte mit JavaX JXMapKit

PHP BibTex-Parser

Nachdem ich derzeit BibTex-Einträge verarbeiten muss darf, habe ich doch gleich mal die Komplexität von BibTex unterschätzt und bin dem NIH-Syndrom verfallen und wollte mal schnell selbst einen Parser schreiben. “Mal schnell” widerspricht dabei dem Drang nach Vollständigkeit – also: etwas Freizeit für die Erkenntnis geopfert, nächstes mal gleich länger zu suchen.

Nach einigen Missgriffen habe ich dann doch noch einen viel versprechenden Link gefunden: Bibliophile.

Der BibTex-Parser scheint doch vollständiger zu sein, als alles was ich bisher angesehen habe. Ist zwar seit 2006 nicht mehr aktualisiert, aber seither hat sich an BibTex (glaube ich) auch nichts Wesentliches getan.

Zum Download geht’s übrigens hier > bibtexParse > bibtexParse-2.2 > bibtexParse2.2.zip

PS: Mittlerweile gibt es die zugehörige MediaWiki Extension auch online 🙂