private void NextGeneration(int parentID) { Node parent = new Node(); parent = Stations[parentID]; List <Node> children = new List <Node>(); children = MetroNetwork.GenChildren(parent); // generates list of neighbouring nodes int index; // nondeterministic element: Shuffle(children); // mixes up children so that different ones are selected first each time foreach (var child in children) { index = child.StationId; child.Score = Stations[index].Score; if (child.UpdateScore(parent, OriginStationId)) // returns true only if it is a valid forwards step { Stations[index].CopyLineBranchIndexFrom(child); // must only edit location when sure new route is faster Stations[index].Score = child.Score; // assign new score Enqueue(index); // adds this stationId onto list of stations to visit } } }
// basic methods internal void RewindUntilOrigin(List <Node> stations) // retraces steps from destination to origin { Path.AddLast(stations[DestinationId]); int index; bool ongoing = true; int parentCount; Random rand = new Random(); List <Node> neighbours = new List <Node>(); List <int> validParentIds = new List <int>(); do { neighbours = MetroNetwork.GenChildren(Path.First()); foreach (Node n in neighbours) { index = n.StationId; if (Path.First().ValidRewind(stations[index], OriginId)) { validParentIds.Add(index); } } parentCount = validParentIds.Count(); if (parentCount > 0) { index = validParentIds[rand.Next(parentCount)]; // goes down a random path AddOn(stations[index]); if (index == OriginId) // terminates when reached origin { ongoing = false; } } else // there are no valid ancestors >> no route exists (disconnected graph) { ongoing = false; } validParentIds.Clear(); neighbours.Clear(); } while (ongoing); }