Ich möchte ein einfaches Programm schreiben, das eine Reihe von Fenstern (Breite + Höhe) und die Bildschirmauflösung akzeptiert und eine Anordnung dieser Fenster auf dem Bildschirm ausgibt, so dass die Fenster den größten Platz beanspruchen. Daher ist es möglich, die Größe eines Fensters unter Beibehaltung output size >= initial size
des Seitenverhältnisses zu ändern . Also für Fenster , würde ich den Algorithmus wie ein Tupel zurück .( x , y , w i d t h , h e i g h t )
Ich glaube, dies könnte eine Variante von 2D Knapsack sein. Ich habe versucht, die Ergebnisse im Web durchzusehen, aber die meisten hatten viel Hintergrundwissen (und keine Implementierung), was es mir schwer machte, zu folgen.
Ich interessiere mich weniger für den schnellstmöglichen Algorithmus, sondern mehr für etwas, das für meine spezifischen Bedürfnisse praktisch ist.
quelle
Antworten:
Obwohl Ihre Frage es nicht sagt, gehe ich davon aus, dass Sie nicht möchten, dass sich Fenster überlappen.
Ein Ansatz für dieses Problem ist die Verwendung eines Constraint-Lösers wie Choco . Man schreibt einfach die Einschränkungen auf, die Ihr Problem codieren, stimmt den Löser so ab, dass er intelligent agiert, und lässt ihn dann laufen. Dies bedeutet, dass Sie nur überlegen müssen, wie Sie das Problem gut codieren können, statt einen Algorithmus zu entwickeln und die Programmierung und Abstimmung vorzunehmen. Hier ist eine Teilantwort, um Ihnen den Einstieg zu erleichtern.
Angenommen, die Bildschirmgröße ist .xm a x× ym a x
Für jedes Fenster haben Sie eine Reihe von Variablen und Einschränkungenx i , y i , h i , w iWich xich, yich, hich, wich
Nun müssen Sie auf die Fensterüberlappung achten. Für jedes Fensterpaar , in dem , generieren Sie Einschränkungen wie die folgenden, die erfassen, dass in keine Ecke von erscheint . für die Einschränkung: i ≠ j W j W i ( x , y ) ∈ { ( x j , y j ) , ( x j + w j , y j ) , ( x j , y j + h j ) , ( x j + w j , y j + h jWich, Wj ich ≠ j Wj Wich ( x , y) ∈ { ( xj, yj) , ( xj+ wj, yj) , ( xj, yj+ hj) , ( xj+ wj, yj+ hj) }
Die bisher angegebenen Einschränkungen beschreiben nur nicht überlappende Fenster, die nicht über die Seiten des Bildschirms verlaufen, die einige minimale Größenbeschränkungen erfüllen und deren Seitenverhältnis beibehalten.
Um eine gute Anpassung zu erhalten, müssen Sie eine Metrik angeben, die erfasst, was es heißt, ein gutes Layout zu sein. Eine Möglichkeit besteht darin anzunehmen, dass Sie die Fenster ungefähr gleich groß halten und / oder den "Leerraum" minimieren möchten. Ich glaube nicht, dass dies mit Choco spezifiziert werden kann, aber es kann mit einer anderen Einschränkung gelöst werden (jemand anderes könnte hier helfen).
Mit Choco kann man die Anzahl auf eine Zielfunktion maximieren, die als einzelne Variable angegeben ist. Basierend auf dieser Idee können Sie Folgendes maximieren:
indem Sie eine Bedingung und Choco , zu maximieren .c o s tc o s t = ∑ich( hich+ wich) c o s t
quelle
Ich habe angefangen, einen Prototyp für eine Brute-Force-Lösung zu schreiben, der hoffentlich so weit optimiert werden kann, dass er praktisch ist.
Zunächst einige Definitionen: Sei die Menge aller Fenster. Jedes Fenster setzt sich aus für die x-, y-Koordinaten und die Breite und Höhe zusammen. Ein Fenster wird mit einer minimalen Breite und Höhe initialisiert.w x w , y w , w w , h wW w xw, yw, ww, hw
Die Eingabe des Algorithmus ist der Bildschirm , der eine Breite und Höhe und eine Liste von Fenstern aufweist.S
Es funktioniert ungefähr so:
Es gibt einige Dinge, die verbessert werden sollten:
S.coordinates()
ist gerade sehr langsam. Es iteriert alle PunkteS.width x S.height
und prüft, ob sich jeder in einem der Fenster von S befindet.S.put()
prüft, ob sich sein Parameter mit den übrigen Fenstern von S überschneidet, indem der in Daves Antwort erwähnte Test durchgeführt wird. Vielleicht kann dies durch die Verwendung von Intervallbäumen verbessert werden ?S.score()
Derzeit wird was einfach der Bereich aller Fenster ist. Es muss andere Variablen berücksichtigen, um bessere Layouts zu erstellen.Die obige Funktion muss alle Permutationen von ausprobieren , um das bestmögliche Ergebnis zu erzielen.W
Ich versuche gerade, eine geeignete Datenstruktur zu finden, um den Bildschirm und seine Fenster darzustellen. Diese Abfragen müssen unterstützt werden:
quelle