Wie finde ich isolierte Raumgruppen, wenn ich eine Liste von Räumen habe, die miteinander verbunden sind?

9

Ich versuche ein kleines Roguelike zu kreieren und bin so weit gegangen, dass ich zufällig Räume und Korridore generiere. Jeder Raum ist ein instanziiertes Objekt und enthält eine Arrayliste der anderen Räume, die durch einen Korridor verbunden sind.

Ich kann nicht verbundene Räume herausgreifen, aber wie kann ich die Räume kennen, die nur miteinander verbunden sind, aber nicht mit den meisten anderen, die eine Insel bilden?

Um dies besser zu veranschaulichen, ist das Problem hier ein Bild von der Konsole auf einer festgefahrenen Ebene. Die Räume 5 und 6 sind nur miteinander verbunden. Welchen Algorithmus kann ich verwenden, um das zu erkennen?

Geben Sie hier die Bildbeschreibung ein

petervaz
quelle
Problem mit der Verwendung des Bildes? Dieser Pastebin-Link wird nur einen Monat dauern.
Michael
Ja, ich habe zuerst nicht ganz verstanden, was du hier gemacht hast. Entschuldigung, ich habe Ihr Wechselgeld zurückgesetzt.
Petervaz
1
Warum baust du es nicht so, dass es überhaupt keine separaten Räume geben kann ? Oder möchten Sie, dass es isolierte Sets gibt?
AlbeyAmakiir
@AlbeyAmakiir Wie ich in einem anderen Kommentar unten sagte, generiere ich die Räume separat durch Versuch und Irrtum, bis ich die Karte fülle. Erst dann führe ich eine Routine zum Verbinden aus und führe dann eine andere aus, um diese Inseln zu verbinden. Ich weiß, dass es wahrscheinlich zu kompliziert ist, aber ich könnte keinen anderen Weg finden.
Petervaz

Antworten:

14

Beginnen Sie mit einer vollständigen Liste der Zimmer. Wähle einen Startraum. Navigieren Sie von diesem Raum zu allen verbundenen Räumen. Entfernen Sie es für jeden Raum, den Sie besuchen, aus der Liste der Räume und fügen Sie es einer Liste A hinzu . Sobald Sie alle Ihre Verbindungen besucht haben, sind alle auf der Liste verbleibenden Räume nicht mehr mit dem Startraum oder einem der Räume auf Liste A verbunden .

Sie können dann fortfahren, indem Sie einen Raum aus den Resten der vollständigen Liste auswählen und erneut navigieren. Diesmal zur Liste B hinzufügen . Setzen Sie diesen Vorgang fort, bis Sie keine Räume mehr auf der ursprünglichen Liste haben. Sie haben jetzt Listen aller verbundenen Raumsets.

Probleme wie dieses lassen sich leicht an graphentheoretische Probleme anpassen. Das oben beschriebene Problem bezieht sich beispielsweise direkt auf die Konnektivität .

MichaelHouse
quelle
1
Jeder Suchbaumalgorithmus sollte funktionieren. Das oder Sie könnten Ihren Generierungsalgorithmus ändern, um dieses Problem zu vermeiden. Wenn Sie Ihren Generierungsalgorithmus ändern, generieren Sie einfach eine zufällige Anzahl von Räumen, die an Ihren Startraum angehängt sind, und eine zufällige Anzahl von Räumen, die an jeden der folgenden Räume angehängt sind. Dann können Sie einige zufällige Verbindungen zwischen vorhandenen Räumen hinzufügen, um die Dinge mit Verknüpfungen ein wenig aufzupeppen und derartige. Persönlich würde ich aber nur einen Suchbaumalgorithmus machen.
Benjamin Danger Johnson
Das ist sehr logisch. Ich muss müde sein Danke für Ihre Hilfe. Wird akzeptieren, sobald es erlaubt.
Petervaz
@BenjaminDangerJohnson Ihr Kommentar scheint eher für die Frage und nicht für diese Antwort geeignet zu sein.
MichaelHouse
@petervaz Kein Problem. Ich denke, mein CS-Abschluss hat schließlich seine Verwendung.
MichaelHouse
@BenjaminDangerJohnson Mein Generierungsalgorithmus platziert nur zufällige Räume, bis der Raum gefüllt ist, und sucht später nach Verbindungen. = P Versucht, die Verbindungen zu reparieren, bevor die Erstellung geändert wird.
Petervaz
9

Ihre Raumsammlung ist im Wesentlichen ein Diagramm, und Ihr Problem besteht darin, verbundene Komponenten ("Inseln") in diesem Diagramm zu finden.

Eine einfache Möglichkeit, verbundene Komponenten zu finden, besteht darin, BFS (Breitensuche) von jedem Scheitelpunkt aus durchzuführen. Wenn Sie BFS von einem Scheitelpunkt A aus ausführen, erhalten Sie alle Scheitelpunkte in der verbundenen Komponente, zu der Scheitelpunkt A gehört.

Im Grunde genommen beginnen Sie mit einem beliebigen Scheitelpunkt, führen ein BFS durch und markieren jeden angetroffenen Scheitelpunkt als Mitglied der 1. "Insel". Dann fahren Sie mit dem nächsten nicht markierten Scheitelpunkt fort und führen erneut ein BFS durch. Diesmal kennzeichnen Sie angetroffene Scheitelpunkte als Mitglieder der 2. "Insel" und so weiter.


quelle
4

Sie können die Räume als Eckpunkte in einem gerichteten Diagramm darstellen . Auf diese Weise können Sie bekannte Algorithmen anwenden, um Ihr Problem zu lösen.

Der Dijkstra-Algorithmus erzeugt beispielsweise einen kürzesten Pfadbaum für einen bestimmten Startscheitelpunkt in einem Diagramm. Dieser Baum enthält alle erreichbaren Eckpunkte vom Startpunkt aus. Sie können dann ableiten, dass die im Baum nicht vorhandenen Eckpunkte Teil anderer Inseln sind. Sie können den Algorithmus auf diese Eckpunkte anwenden, um Bäume zu erhalten, die jede Insel darstellen.

Asakeron
quelle
1
Sogar ein ungerichteter Graph würde es tun ... außer Sie haben nur Einwegrouten.
Aron_dc
@Aron_dc, Sie haben Recht, Sie können die Räume als Eckpunkte in einem ungerichteten Diagramm darstellen und mit dem Kruskal-Algorithmus ähnliche Ergebnisse erzielen. Ich habe nur vorgeschlagen, es als gerichtete Diagramme darzustellen, da Petervaz die Verbindungen darstellt - dh Raum 1> 3
Asakeron