Ich versuche, die Schnittpunkte von zwei Rechtecken zu erhalten. Ich habe eine Methode, die funktioniert, aber wenn ich es mit einem Algorithmus für 40000 Rechtecke teste, erhalte ich einen OutOfMemory-Fehler. Die Anzahl der Male, die ich auf Kreuzungen überprüfe, ist perfekt O (n²), aber die Zeit, die es braucht, ist nicht. Ich denke, der nicht genügend Speicher ist nur, weil es zu viele Objekte gibt, aber die Zeit, die es braucht, ist nicht O (n²) (getestet mit einem Verdoppelungstest) macht keinen Sinn für mich, und ich kann nicht herausfinden, warum Es macht das.Get Schnittpunkte von Rechtecken Nicht O (n²) und OutOfMemory
Dies ist mein Code für die Kreuzung immer
public void getIntersections(Rectangle r, Collection<double[]> c) {
x1 = Math.max(this.getLowerLeftX(), r.getLowerLeftX());
y1 = Math.max(this.getLowerLeftY(), r.getLowerLeftY());
x2 = Math.min(this.getUpperRightX(), r.getUpperRightX());
y2 = Math.min(this.getUpperRightY(), r.getUpperRightY());
if(this.contains(x1,y1) && r.contains(x1,y1)) {
inter[0] = x1;
inter[1] = y1;
c.add(inter.clone());
}
if(this.contains(x1,y2) && r.contains(x1,y2)){
inter[0] = x1;
inter[1] = y2;
c.add(inter.clone());
}
if(this.contains(x2,y1) && r.contains(x2,y1)){
inter[0] = x2;
inter[1] = y1;
c.add(inter.clone());
}
if(this.contains(x2,y2) && r.contains(x2,y2)){
inter[0] = x2;
inter[1] = y2;
c.add(inter.clone());
}
}
Ich habe versucht, dies als Speicher und CPU effizienter zu machen, aber immer noch ist es nicht funktioniert wie es sollte. Jede Hilfe wird sehr geschätzt.
EDIT: Der Algorithmus, der diese Funktion aufruft:
public void execute() {
List<Rectangle> rectangles = this.getRectangles();
Queue<Rectangle> q = new LinkedList<Rectangle>();
q.addAll(rectangles);
System.out.println(q.size());
while(!q.isEmpty()){
Rectangle check_rect = q.poll();
for (Rectangle rect: q) {
check_rect.getIntersections(rect, this.getIntersections());
}
}
}
Hilfsfunktionen:
public boolean contains(double x, double y){
return ((x == this.getLowerLeftX() || x == this.getUpperRightX()) ||
(y == this.getLowerLeftY() || y == this.getUpperRightY())) &&
x >= this.getLowerLeftX() && x <= this.getUpperRightX() &&
y >= this.getLowerLeftY() && y <= this.getUpperRightY();
}
Für die Sammlung von Kreuzungen i verwenden:
this.intersections = new ArrayDeque<>();
Die outOfMemory Ausnahme immer passiert, wenn es versucht, das ArrayDequezu vergrößern>(), speichert nur die Schnittpunkte in double [2]. Es scheint also, dass es zu viele Schnittpunkte zwischen den 40000 Rechtecken gibt. Ein weiteres Problem scheint zu sein, dass die Iteration, bevor es nicht genügend Arbeitsspeicher hat, es wirklich verlangsamt, ist dies wegen des Swappings oder anderer Speicherverwaltung?
Haben Sie die Dynamik der Leistungsdegradation (1000, 5000, 10000 Rechtecke) untersucht? Außerdem sollten Sie den Code angeben, der diese Methode aufruft, da das Problem möglicherweise vorhanden ist. Auch Ihre Methode arbeitet an Nebenwirkungen, die als schlechte Praxis angesehen werden. Normalerweise möchten Sie ein neues Schnittpunktobjekt und keine Eingabe- und globalen Variablen bearbeiten. – user3707125
Können Sie Implementierungen aller hier verwendeten Methoden bereitstellen? Das bedeutet alle Methoden "getLowerRight", "getUpperLeft" usw. und die Methode 'contains'. Fügen Sie bitte zusätzlich die Deklaration von 'inter'array ein –
Ich habe weitere Informationen hinzugefügt, damit Sie sehen können, was ich mache. – Midasso