//-------------------------------------------------------------------------------- //This functions only works in a feasible path. It takes one random node and checks if //its neighboors can have a better cost with other conexion of the commons neighboors public void Improve(ref MeshEnvironment env) { if (is_feasible) { int random_idx = random.Next(1, path.Count - 1); //Get the previous and next node of that obstacle in the path int previous_node = path[random_idx - 1]; int next_node = path[random_idx + 1]; List <int> neigh_previous = env.world[previous_node].neighboors; List <int> neigh_next = env.world[next_node].neighboors; List <int> intersection = neigh_previous.Intersect(neigh_next).ToList(); intersection.Remove(path[random_idx]); if (intersection.Count != 0 && !env.obstacles.Contains(intersection[0])) { List <int> tmp_path = new List <int>(path); tmp_path[random_idx] = intersection[0]; Double tmp_cost = ExtraTools.GetCost(ref tmp_path, ref env); if (tmp_cost < best_cost) { best_cost = tmp_cost; path = new List <int>(tmp_path); SetExtraParameters(ref env); SetFitness(ref env); } } } }
//------------------------------------------------------------------- public void DeltaTau(ref MeshEnvironment env, ref List <int> route) { if (best_cost != Double.MaxValue) { Double current_cost = ExtraTools.GetCost(ref route, ref env); delta_tau = best_cost / current_cost; } }
//------------------------------------------------------------------- public void CheckAndSetBestCost(ref MeshEnvironment env, ref List <int> route) { Double current_cost = ExtraTools.GetCost(ref route, ref env); if (current_cost < best_cost) { best_cost = current_cost; } }
//------------------------------------------------------------------- public List <int> FindRoute(ref MeshEnvironment env) { //List to store the new route List <int> route = new List <int>(); route.Add(env.start_node); //Include the initial node //Variable to detect if the ant finds a route bool found_route = false; //Init the loop from the initial node int current_node = env.start_node; while (!found_route) { int next_node = SelectNextNode(ref env, current_node); if (next_node != -1) { //Add the new node and change the current node route.Add(next_node); current_node = next_node; } else { //If there is a stuck condition break the loop break; } //Configuro mi variable si he encontrado el objetivo found_route = current_node == env.final_node; } //If the ant found a route if (found_route) { //Set the current route, the current cost and the current counter current_route = route; current_cost = ExtraTools.GetCost(ref current_route, ref env); counter_route++; } else { route = new List <int>(); } return(route); }
//------------------------------------------------------------------------- //Funcion fitness puede variar de acuerdo al requerimiento del algoritmo public void SetFitness(ref MeshEnvironment env) { //Costo general por la distancia del camino Double cost = ExtraTools.GetCost(ref path, ref env); //Costo extra por aristas obstaculos if (edges_obstacles.Count != 0) { foreach (var idx_edge in edges_obstacles) { cost += env.edges[idx_edge].distance * coef_edge_obs; } } //Costo extra por nodos obstaculos cost += num_infeasible_nodes * coef_node_obs; fitness = 1 / cost; best_cost = cost; }
//------------------------------------------------------------------------------- public void Execute(ref MeshEnvironment env) { //Fill distances to objective env.FillDistancesToFinal(); //Init the node tags list; int size = env.size * env.size; InitNodeTags(size); //Get the distance between node. Adjacency Matrix env.FillDistanceMatrix(); Double[,] distances_matrix = env.distances; //Get initial and final nodes int initial_position = env.start_node; int final_position = env.final_node; //Get world of the env List <Node> world = env.world; //Init the values of the initial node and its tag node_tags[initial_position].local_goal = 0.0; node_tags[initial_position].global_goal = MeasureHeuristic(initial_position, ref env); //Fijar la posicion actual Tag current_position = node_tags[initial_position]; //Nodos que seran testeados List <Tag> tested_nodes_list = new List <Tag>(); tested_nodes_list.Add(node_tags[initial_position]); //Time variable var watch = System.Diagnostics.Stopwatch.StartNew(); while (tested_nodes_list.Count != 0) // && current_position.node_id != env.final_node) { //Ordenar la lista de acuerdo al objetivo global en orden ascendente tested_nodes_list = tested_nodes_list.OrderBy(tag => tag.global_goal).ToList(); //Remover de la lista si el nodo analizado ya ha sido visitado while (tested_nodes_list.Count != 0 && tested_nodes_list[0].visited) { tested_nodes_list.RemoveAt(0); } //Si la lista es vacia salimos del bucle if (tested_nodes_list.Count == 0) { break; } //Inicializamos nuestra posicion actual current_position = tested_nodes_list[0]; current_position.visited = true; tested_nodes_list[0] = current_position; node_tags[current_position.node_id] = current_position; //Obtengo los posibles nodos a los cuales me puedo mover List <int> list_posible_nodes = GetPosibleNodes(current_position.node_id, ref env); //Itero por los posibles nodos foreach (var neighbour_id in list_posible_nodes) { int current_id = current_position.node_id; Double possible_lower_goal = current_position.local_goal + distances_matrix[current_id, neighbour_id]; if (possible_lower_goal < node_tags[neighbour_id].local_goal && !node_tags[neighbour_id].visited) { Tag new_tag = node_tags[neighbour_id]; new_tag.parent = current_id; new_tag.local_goal = possible_lower_goal; new_tag.global_goal = new_tag.local_goal + MeasureHeuristic(neighbour_id, ref env); node_tags[neighbour_id] = new_tag; if (tested_nodes_list.Contains(new_tag)) { int idx = tested_nodes_list.IndexOf(new_tag); tested_nodes_list[idx] = new_tag; } } //Si los nodos analizados aun no han sido marcados como visitados //Los añadimos a lista de testeo if (!node_tags[neighbour_id].visited && !tested_nodes_list.Contains(node_tags[neighbour_id])) { tested_nodes_list.Add(node_tags[neighbour_id]); } } } List <int> optimal_path = GetPath(final_position, initial_position); Double optimal_cost = ExtraTools.GetCost(ref optimal_path, ref env); final_best_path = optimal_path; final_best_path.Reverse(); final_best_cost = optimal_cost; //Execution Time watch.Stop(); execution_time = watch.ElapsedMilliseconds; }
//-------------------------------------------------------------- public bool CheckPopulation(ref MeshEnvironment env) { int num_convergence = (int)Math.Round(num_individuals * percentage_convergence); Double best_cost_individual = Double.MaxValue; int best_individual = -1; for (int k = 0; k < population.Count; k++) { Double current_cost = population[k].best_cost; if (current_cost < best_cost_individual) { best_cost_individual = current_cost; best_individual = k; } } List <int> best_route_individual = population[best_individual].path; int i = 0, j = 0; while (i < num_convergence && j < num_individuals) { //if (population[j].path.SequenceEqual(best_route_individual)) if (Math.Round(population[j].best_cost, 4) == Math.Round(best_cost_individual, 4)) { i++; } j++; } bool converge = false; if (best_route_individual.Count != 0) { if (i == num_convergence) { final_best_path = population[0].path; final_best_cost = ExtraTools.GetCost(ref final_best_path, ref env); converge = true; } } //Probemos con el segundo mejor if (converge == false) { best_cost_individual = Double.MaxValue; best_individual = -1; for (int k = 1; k < population.Count; k++) { Double current_cost = population[k].best_cost; if (current_cost < best_cost_individual) { best_cost_individual = current_cost; best_individual = k; } } best_route_individual = population[best_individual].path; i = 0; j = 0; while (i < (num_convergence - 1) && j < num_individuals) { if (Math.Round(population[j].best_cost, 4) == Math.Round(best_cost_individual, 4)) { i++; } j++; } if (best_route_individual.Count != 0) { if (i == num_convergence - 1) { final_best_path = population[0].path; final_best_cost = ExtraTools.GetCost(ref final_best_path, ref env); converge = true; } } } return(converge); }