2016-09-01 2 views
0

Ich habe ein Diagramm in cytoscape.js eingerichtet. Einige Knoten haben ein Datenfeld "feature = true". Für einen Knoten, den ich auswähle, möchte ich den nächsten verbundenen Knoten finden, der "feature = true" hat.cytoscape.js verbundenen Knoten mit Datenfeld Wert finden

Ich habe die verschiedenen Algorithmen durchgesehen, aber wenn sie Selektoren akzeptieren, die zu mehreren Knoten validieren, verhalten sie sich anscheinend nicht so, als würden sie den kürzesten Pfad zu einem Knoten zurückgeben, der mit dem Selektor übereinstimmt. Zum Beispiel, wenn ich bin auf der Suche nach dem nächsten Knoten zu #start der Funktion = true in seinem Datenfeld hat:

var closestFeatureSearch = cytoGraph.elements().aStar({ \t \t 
 
    root: '#start', 
 
    goal: 'node[?feature]', 
 
    directed : false 
 
});

Es scheint immer den gleichen abschließenden Knoten wählen ... Das erste Element auf der Liste wurde zurückgegeben, wenn Sie cytoGraph.filter ('[? feature]') ausgeführt haben, egal, welchen Knoten ich in root eingefügt habe, auch wenn andere Knoten mit "feature = true" näher sind.

Fehle ich etwas offensichtlich hier? Ich habe die Dokumente konsultiert und kann für dieses spezifische Problem nichts finden, nur bestimmte Anwendungsfälle von Knoten zu Knoten. Vielen Dank!

Antwort

0

Mein Verständnis ist, dass A * ist, wenn Sie den genauen Knoten kennen, die Sie das Ziel sein möchten. Daher wird nur ein Knoten als Ziel akzeptiert. Wenn Sie eine Sammlung mit einer Größe von mehr als 1 angeben, kann nur die erste verwendet werden.

Ich habe den Algorithmus vor kurzem nicht angeschaut, aber meine Intuition ist, dass Ihre Änderung möglicherweise nicht für alle Fälle funktioniert - besonders in Verbindung mit der Heuristik.

Es ist wahrscheinlich besser für Sie, Djikstra zu verwenden. Nach dem Ausführen können Sie sich die Entfernung anzeigen lassen, die für jeden [? Feature] -Knoten gefunden wird - verwenden Sie den kleinsten und erhalten Sie seinen Pfad.

0

Ok, ich konnte einen Fall hinzufügen, um diese Funktionalität zu handhaben. Going the un-minimierte aktuelle Version aus (2.7.8) um ​​die Linie 390 sollten Sie ein bedingter wie so sehen:

if(cMin.id() == target.id()){ 
 
    var rPath = reconstructPath(source.id(), target.id(), cameFrom, []); 
 
    rPath.reverse(); 
 
    return { 
 
    found: true, 
 
    distance: gScore[ cMin.id() ], 
 
    path: eles.spawn(rPath), 
 
    steps: steps 
 
    }; 
 
}

Ich habe einen separaten Fall für den Umgang mit in Filter durchströmt, die mehrere übereinstimmen danach folgenden Einträge sofort:

//if there was a filter passed in, check the array of ids matching that to see if cMin.id() is in there 
 
if (is.string(options.goal) && this.filter(options.goal).map(function(item){return item.id()}).indexOf(cMin.id()) > -1) { 
 
    var rPath = reconstructPath(source.id(), cMin.id(), cameFrom, []); 
 
    rPath.reverse(); 
 
    return { 
 
    found: true, 
 
    distance: gScore[ cMin.id() ], 
 
    path: eles.spawn(rPath), 
 
    steps: steps 
 
    }; 
 
}

Die zwei wichtigsten Änderungen sind die if-Bedingung (offensichtlich) und dass rPath die aktuelle cMin.id() als Ziel anstelle von target.id() verwendet.

Wie auch immer, es funktioniert für meinen Anwendungsfall! Ich hoffe, es ist nützlich für jemand anderen.

Verwandte Themen