2016-07-06 5 views
1

folgendes Bild Betrachten, ist es ein Array von Elementen:Wie finden Sie die Verbindungen oder Beziehungen zwischen Elementen in einem Array?

enter image description here

Die Elemente in dem Array durch ein Attribut sortiert werden genannt id (die Zahl in den schwarzen Kreis)

Das Attribut id ist einzigartig.

Jedes Element hat zwei zusätzliche Attribute (in Klammern innerhalb des Kreises): from und to

Jeder Artikel ist verbunden oder zum anderen durch die from und to Attribute verwandt. Beispiel (nicht im obigen Bild):

Using kind of python syntax: 

{id:1, from:a, to:b} --> {id:2, from:b,to:c} --> {id:3, from:c, to:a} 

Denken Sie an das obige Beispiel als eine kreisförmige verkettete Liste.

Es kann Elemente geben, die nicht mit anderen verknüpft sind (z. B. das Element mit id = 3-).

Die Eingabe ist die id eines beliebigen Elements innerhalb des Arrays.

Der Algorithmus sollte eine der folgenden Ergebnisse ab:

  • ein Array von Arrays.
  • Eine Reihe von kreisförmigen verknüpften Listen.

Basierend auf dem angezeigten Bild, wobei Beispiele die erwartete Ausgabe sind:

1.- die id = 7 Gegeben ist das erwartete Ergebnis:

An array containing this single array (or its equivalent circular linked list). 
That is, the items connected by the blue line. 
If the items in the inner array are rotated by N, it's ok. 

output = [ 
    [ 
     {id:7, from:m, to:k}, 
     {id:8, from:k, to:i}, 
     {id:10, from:i, to:b}, 
     {id:2, from:b, to:e}, 
     {id:4, from:e, to:h}, 
     {id:1, from:h, to:l}, 
     {id:6, from:l, to:m} 
    ] 
] 

2.- die id = 2 Angesichts der erwartetes Ergebnis ist:

An array containing two arrays (or their equivalent circular linked list). 
That is, the two collections of items connected by the red and the blue line. 
If the items in the inner arrays are rotated by N, it's ok. 

output = [ 
    [ 
     {id:2, from:b, to:e}, 
     {id:5, from:e, to:g},   
     {id:9, from:g, to:i}, 
     {id:10, from:i, to:b} 
    ], 
    [   
     {id:2, from:b, to:e}, 
     {id:4, from:e, to:h}, 
     {id:1, from:h, to:l}, 
     {id:6, from:l, to:m}, 
     {id:7, from:m, to:k}, 
     {id:8, from:k, to:i}, 
     {id:10, from:i, to:b} 
    ] 
] 

Also, die Fragen sind:

Was könnte der mögliche Algorithmus und die Datenstruktur sein, um dieses Problem zu lösen?

+0

Dies sieht verdächtig wie Hausaufgaben oder eine Codierung Herausforderung. Können Sie die Motivation hinter dem Versuch erklären, diese Lösung zu lösen? Es kann helfen, Ihren Algorithmus und Ihre Datenstruktur zu bestimmen. –

+0

Hey @ karnesJ.R, nein, das sind keine Hausaufgaben, und ja ... das hört sich nach einer Kodierungsherausforderung an, aber auch nicht. Ich habe eine App, wo Leute über Orte schreiben, wo sie leben und wohin sie wollen. Also könnte dieser Algorithmus ihnen helfen, diese Orte zu finden. –

+0

Nun, das erste, was Sie tun müssen, ist Ihre Datenstruktur zu verstehen. Was Sie haben, ist ein gerichteter Graph. Es gibt ein fantastisches Werkzeug zur Zykluserkennung in SAGES Grafikbibliothek und SAGE arbeitet mit Digraphen. Vielleicht möchten Sie beginnen, indem Sie dort suchen. Wenn es eine praktische Anwendung ist, die echte Dinge tut, gibt es keinen Grund, das Rad neu zu erfinden. –

Antwort

0

Was ich versuche zu erreichen ist, alle Zyklen durch einen gegebenen Eckpunkt in einem gerichteten Graphen zu finden.

Die Modifikation des Johnson-Algorithmus ist die richtige Lösung für das Problem. Weitere Informationen here.

0

Hier ist nur eine strukturelle Art und Weise eines rekursiven Algorithmus, um das Problem zu lösen:

  • Start mit dem angegebenen Punkt (zB 7)
  • Suche alle anderen Elemente für eine Verbindung (zB 7,8)
  • bauen Sie eine Kette auf diese Weise. Speichere alle genommenen Elemente, um zu verhindern, dass ein Gegenstand zweimal genommen wird. (z. B. 7,8,10,2)
  • Irgendwann wird kein Element mehr gefunden (z. B. 7,8,10,2,5,9)
  • dann löschen Sie das letzte Element aus der Kette und suchen Sie wenn das vorherige Element eine andere Verbindung hat. (z.B.7,8,10,2)
  • Abnahme und erhöhen die Kette, bis Sie den Startpunkt erreichen (zB 7,8,10,2,4,1,6,7)
1

Hier ist ein Beispiel In Javascript ist die Beschreibung des Algorithmus in den Kommentaren, Sie können es in der Konsole in Chrome testen:

Es ist randomisiert, so dass Sie mehrere Tests ausführen können. Wenn kein Pfad gefunden wird, wird ein Fehler ausgelöst.

/* First part to populate example data */ 
 
// \t The universo of people 
 
var people = []; 
 
// \t The single person item 
 
var person = {}; 
 
var count; 
 
// \t The lenth of the array 
 
var len = 250; 
 

 
// \t We're gonna create an array with the format 
 
// \t [ 
 
// \t \t { 
 
// \t \t \t "id": 1, 
 
// \t \t \t "origin": "a", 
 
// \t \t \t "destination": "b" 
 
// \t \t }, 
 
// \t \t ... 
 
// \t ] 
 
for (count = 1; count <= len; count ++) { 
 
\t 
 
\t var rnd = Math.ceil(Math.random() * 25); 
 
\t rnd = String.fromCharCode(97 + rnd) 
 
\t 
 
\t person = {}; 
 
\t person.id = count; 
 
\t person.origin = rnd; 
 
\t 
 
\t rnd = Math.ceil(Math.random() * 25); 
 
\t rnd = String.fromCharCode(97 + rnd) 
 
\t person.destination = rnd; 
 
\t 
 
\t people.push(person); \t 
 
} 
 

 
// \t Here people is the universe of data 
 
console.log (people); 
 

 
// \t Here we get a random person in people 
 
// \t this person for run the test 
 
rnd = Math.ceil(Math.random() * len); 
 
person = people[rnd]; 
 
console.log(person); 
 

 
// \t Next is the actual algorith 
 
// \t The path is the array to return, obviously starting with person 
 
path = [person]; 
 
// \t Route will the actual route of change to move the people and get where they want 
 
// \t we call findMyPath a recursive function 
 
route = findMyPath(person, person, path, people); 
 
console.log('Done'); 
 
console.log(route); 
 

 
/** 
 
* \t This recursive function actually implements the algorithm 
 
*/ 
 
function findMyPath(source, currentItem, path, universe) { 
 
\t 
 
\t // \t The algorithm is: 
 
\t // \t Reverse query: 
 
\t // \t Instead of find the people that is where I want to go, 
 
\t // \t find the people that want to go where I am 
 
\t // \t if at least one is where I want to go, then I'm done 
 
\t // \t if not, then repeat recursively for every finding 
 
\t 
 
\t // \t Holds the people that wanto to go where I am 
 
\t var findings = []; 
 

 
\t // \t Loop the universe 
 
\t for (i = 0; i< universe.length; i++) { 
 
\t \t // \t tmp is the current item in the universe 
 
\t \t var tmp = universe[i]; \t 
 
\t \t // \t If he/she want to go where I am 
 
\t \t if (currentItem.origin == tmp.destination) { 
 
\t \t \t // \t It's a finding! 
 
\t \t \t findings.push(tmp); 
 
\t \t \t // \t If he/she is where I want to go \t \t \t 
 
\t \t \t if (source.destination == tmp.origin) { 
 
\t \t \t \t // \t It's a change complete, I'm done now 
 
\t \t \t \t console.log('Found the route of changes!'); \t \t \t \t 
 
\t \t \t \t path.push(tmp); 
 
\t \t \t \t return path; 
 
\t \t \t } \t \t \t 
 
\t \t } 
 
\t } 
 
\t 
 
\t // \t If we get here, we don't find a trade course yet, 
 
\t // \t the repeat recursively for all findinds 
 
\t for (i = 0; i < findings.length; i++) { 
 
\t \t path.push(findings[0]); 
 
\t \t return findMyPath(source, findings[0], path, universe); 
 
\t } // end for 
 
} // end function findMyPath

Die Ergebnisse:

WICHTIG Die Probe nimmt Zufallszahlen, das ist nur ein Lauf ist, für jeden Lauf, andere Ergebnisse finden, aber der Algorithmus ist der gleiche

250 Elemente im Array

[{"id":1,"origin":"h","destination":"p"},{"id":2,"origin":"s","destination":"e"},... 

komplette json in http://desarrollo.espino.info/sampledata/20160707/results.json

Die Person, für die Sie den Pfad zu finden: id 221 von "q" bis "c" Der komplette Weg der Handelsplätze

[ 
    {"id":221,"origin":"q","destination":"c"}, 
    {"id":26,"origin":"o","destination":"q"}, 
    {"id":28,"origin":"j","destination":"o"}, 
    {"id":31,"origin":"c","destination":"j"} 
] 
+0

Probieren Sie es aus ... Danke @ espino316 –

+0

Sieht ganz gut aus. Es gibt jedoch bestimmte Fälle, in denen ein maximaler Call-Stack-Fehler auftritt. Überprüfen Sie es hier: https://jsbin.com/sibitijego/edit?js,console –

+0

Diese Fälle sind "keine Lösung", gibt es keinen Pfad zurückgeben. Also musst du das Universum vergrößern, in der realen Welt wirst du mehr Kunden brauchen. – espino316