protected List <Node> GetNeighbours(AlgorithmData data, Node current) { List <Node> neighbours = new List <Node>(); foreach (var edge in data.allEdges) { if (edge.nodeFrom == current) { neighbours.Add(edge.nodeTo); } else if (edge.nodeTo == current) { neighbours.Add(edge.nodeFrom); } } return(neighbours); }
public AlgorithmData ConvertVisualsToData() { AlgorithmData data = new AlgorithmData(); var visualNodes = FindObjectsOfType <VisualNode>(); data.allNodes = new List <Node>(); foreach (var visualNode in visualNodes) { Node newNode = new Node(); data.allNodes.Add(newNode); if (visualNode.isStartNode) { data.startNode = newNode; } if (visualNode.isEndNode) { data.endNode = newNode; } visualNodeToNodeDict[visualNode] = newNode; nodeToVisualNodeDict[newNode] = visualNode; } var visualEdges = FindObjectOfType <EdgeMaker>().visualEdges; data.allEdges = new List <Edge>(); foreach (var visualEdge in visualEdges) { Edge newEdge = new Edge(); data.allEdges.Add(newEdge); newEdge.nodeFrom = visualNodeToNodeDict[visualEdge.nodeFrom]; newEdge.nodeTo = visualNodeToNodeDict[visualEdge.nodeTo]; visualEdgeToEdgeDict[visualEdge] = newEdge; edgeToVisualEdgeDict[newEdge] = visualEdge; } return(data); }
protected override IEnumerator PerformAlgorithmCO(AlgorithmData data) { bool result = false; Queue <Node> queue = new Queue <Node>(); List <Node> visitedNodes = new List <Node>(); queue.Enqueue(data.startNode); visitedNodes.Add(data.startNode); while (queue.Count > 0) { Node current = queue.Dequeue(); converter.SelectNode(current); yield return(new WaitForSeconds(0.05f)); if (current == data.endNode) { Debug.Log("WE FOUND THE END NODE!"); result = true; break; } List <Node> neighbours = GetNeighbours(data, current); foreach (var neighbour in neighbours) { if (!visitedNodes.Contains(neighbour)) { queue.Enqueue(neighbour); visitedNodes.Add(neighbour); } } } if (result == false) { Debug.Log("We could not find a path to the end node."); } }
protected override IEnumerator PerformAlgorithmCO(AlgorithmData data) { List <Node> unvisitedNodes = new List <Node>(); // nodes we need to check // Initialise all nodes to infinity and put them in the unvisited list foreach (var node in data.allNodes) { unvisitedNodes.Add(node); node.pathWeight = Mathf.Infinity; } // Initialise the start node Node current = data.startNode; data.startNode.pathWeight = 0; converter.SelectNode(current); while (true) { List <Node> neighbours = GetNeighbours(data, current); foreach (var neighbour in neighbours) { if (unvisitedNodes.Contains(neighbour)) { float tentativeWeight = current.pathWeight + 1; // 1 is the weight of the segment connecting the two nodes // we compare the tentative weight with the one we already set for that neighbour if (tentativeWeight < neighbour.pathWeight) { neighbour.pathWeight = tentativeWeight; } } } // we remove the visited node unvisitedNodes.Remove(current); // let's check whether we finished the path if (current == data.endNode) { Debug.Log("WE FOUND THE SHORTEST PATH " + current.pathWeight); break; } // let's choose the node with the minimum weight float minWeight = Mathf.Infinity; foreach (var node in unvisitedNodes) { if (node.pathWeight < minWeight) { minWeight = node.pathWeight; current = node; } } converter.SelectNode(current, new Color(current.pathWeight / 15f, 1 - current.pathWeight / 15f, 0)); yield return(new WaitForSeconds(0.05f)); } // Find the shortest path List <Node> shortestPath = new List <Node>(); shortestPath.Add(data.endNode); current = data.endNode; converter.SelectNode(current, new Color(0f, 0f, 1f)); while (true) { // Find the lowest weight neighbour (which is the one that will take me to the start node at minimum cost) float minWeight = Mathf.Infinity; Node minNeighbour = null; foreach (var neighbour in GetNeighbours(data, current)) { if (neighbour.pathWeight < minWeight) { minWeight = neighbour.pathWeight; minNeighbour = neighbour; } } shortestPath.Add(minNeighbour); current = minNeighbour; converter.SelectNode(current, new Color(0f, 0f, 1f)); yield return(new WaitForSeconds(0.05f)); if (current == data.startNode) { break; } } }
protected abstract IEnumerator PerformAlgorithmCO(AlgorithmData data);
protected override IEnumerator PerformAlgorithmCO(AlgorithmData data) { List <Node> unvisitedNodes = new List <Node>(); // nodes we need to check // Initialise all nodes to infinity and put them in the unvisited list foreach (var node in data.allNodes) { unvisitedNodes.Add(node); node.pathWeight = Mathf.Infinity; node.tentativeWeight = Mathf.Infinity; } // Initialise the start node Node current = data.startNode; data.startNode.pathWeight = 0; converter.SelectNode(current); while (true) { List <Node> neighbours = GetNeighbours(data, current); foreach (var neighbour in neighbours) { if (unvisitedNodes.Contains(neighbour)) { float pathWeight = current.pathWeight + segmentWeight; // segmentWeight is the weight of the segment connecting the two nodes // A* magic here! // we also add a heuristic "h" estimate of the remaining cost // we use distance as an heuristic float distance = (converter.nodeToVisualNodeDict[neighbour].transform.position - converter.nodeToVisualNodeDict[data.endNode].transform.position).sqrMagnitude; float heuristicWeight = distance * heuristicFactor; float tentativeWeight = pathWeight + heuristicWeight; Debug.Log("Tot: " + tentativeWeight + " Path: " + pathWeight + " Heur: " + heuristicWeight); // we compare the tentative weight with the one we already set for that neighbour if (tentativeWeight < neighbour.tentativeWeight) { neighbour.tentativeWeight = tentativeWeight; } if (pathWeight < neighbour.pathWeight) { neighbour.pathWeight = pathWeight; } } } // we remove the visited node unvisitedNodes.Remove(current); // let's check whether we finished the path if (current == data.endNode) { Debug.Log("WE FOUND THE SHORTEST PATH " + current.pathWeight); break; } // let's choose the node with the minimum weight float minWeight = Mathf.Infinity; foreach (var node in unvisitedNodes) { if (node.tentativeWeight < minWeight) { minWeight = node.tentativeWeight; current = node; } } converter.SelectNode(current, new Color(current.tentativeWeight / 15f, 1 - current.tentativeWeight / 15f, 0)); yield return(new WaitForSeconds(0.05f)); } // Find the shortest path List <Node> shortestPath = new List <Node>(); shortestPath.Add(data.endNode); current = data.endNode; converter.SelectNode(current, new Color(0f, 0f, 1f)); while (true) { // Find the lowest weight neighbour (which is the one that will take me to the start node at minimum cost) float minWeight = Mathf.Infinity; Node minNeighbour = null; foreach (var neighbour in GetNeighbours(data, current)) { if (neighbour.pathWeight < minWeight) { minWeight = neighbour.pathWeight; minNeighbour = neighbour; } } shortestPath.Add(minNeighbour); current = minNeighbour; converter.SelectNode(current, new Color(0f, 0f, 1f)); yield return(new WaitForSeconds(0.05f)); if (current == data.startNode) { break; } } }