//--------------------------------------------------------------------- //This function returns the neighbor node that has the best proximity value private int FindBestNode(ref MeshEnvironment env, ref List <int> fragment_route, ref List <int> current_route, int current_node, int node2) { List <int> neighboors = env.world[current_node].neighboors; List <Double> proximities = new List <Double>(); for (int i = 0; i < neighboors.Count; i++) { int neigh_node = neighboors[i]; Double proximity; if (!fragment_route.Contains(neigh_node) && !current_route.Contains(neigh_node) && !env.obstacles.Contains(neigh_node)) { proximity = env.CalculateProximity(current_node, neigh_node, node2); } else { proximity = -1; } proximities.Add(proximity); } Double max_proximity = proximities.Max(); if (max_proximity != -1) { int index_max1 = proximities.IndexOf(max_proximity); return(neighboors[index_max1]); } else { return(-1); } }
//--------------------------------------------------------------------- private List <int> ConnectNodes(ref MeshEnvironment env, ref List <int> current_route, int node1, int node2) { List <int> fragment_route = new List <int>(); fragment_route.Add(node1); int current_node = node1; while (current_node != node2) { int next_node = FindBestNode(ref env, ref fragment_route, ref current_route, current_node, node2); if (next_node != -1) { fragment_route.Add(next_node); current_node = next_node; } else { break; } } if (current_node != node2) { fragment_route = new List <int>(); } return(fragment_route); }
//------------------------------------------------------------------- //Evaporation Function public void Evaporation(ref MeshEnvironment env) { for (int i = 0; i < env.edges.Count; i++) { env.edges[i].pheromone_amount = env.edges[i].pheromone_amount * (1 - evaporation_factor); } }
//--------------------------------------------------------------------- public static void StoreVariables_RW1(string mesh_type, ref MeshEnvironment env, ref RandomWalkv1 rw1) { string separator = " "; string line = mesh_type + separator; line += rw1.num_random_walks + separator; line += rw1.random_movements + separator; line += rw1.evaporation_factor + separator; line += rw1.best_cost + separator; line += rw1.execution_time; string path = @"data_sets/results/acov0_rw1/" + mesh_type + "/"; string variables_file = "info_rw1" + "_" + mesh_type + "_" + env.size + "x" + env.size + ".txt"; using (StreamWriter file = File.AppendText(path + variables_file)) { file.WriteLine(line); } string path2 = @"data_sets/results/acov0_rw1/"; string variables_file2 = "info_rw1" + "_" + mesh_type + ".txt"; using (StreamWriter file = File.AppendText(path2 + variables_file2)) { file.WriteLine(line); } }
//------------------------------------------------------------------------------- //This function takes one node and change it randomly by other node randomly public void Mutation(ref MeshEnvironment env, int len_cut, Double mutation_prob) { Double random_prob = random.NextDouble(); if (random_prob < mutation_prob) { //Elijo el nodo que voy a cambiar int random_cut1 = random.Next(1, path.Count() - 2 - len_cut); int random_cut2 = random.Next(random_cut1 + 1, random_cut1 + 1 + len_cut); //Realizo los dos cortes de la ruta List <int> fragment1 = path.GetRange(0, random_cut1); List <int> fragment2 = path.GetRange(random_cut2, path.Count - random_cut2); //Uno las dos partes y reparo la ruta si los nodos no estan directamente conectados List <int> join_path; if (fragment1[fragment1.Count - 1] == fragment2[0]) { fragment2.RemoveAt(0); join_path = fragment1.Concat(fragment2).ToList(); } else { join_path = JoinGenes(ref fragment1, ref fragment2, ref env); } path = join_path; SetExtraParameters(ref env); SetFitness(ref env); } }
//-------------------------------------------------------------- //Funcion para calcular el fitness de todos los individuos de una generación public void MeasureFitness(ref MeshEnvironment env) { foreach (var individual in population) { individual.SetFitness(ref env); } }
//-------------------------------------------------------------------------------- //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 static void StoreVariable_AStar(string mesh_type, ref MeshEnvironment env, ref AStarAlgorithm ast1, ref AStarAlgorithm ast2) { string separator = " "; string size = "" + env.size; string method = "astar"; string line = mesh_type + separator; line += env.size + separator; line += ast1.final_best_cost + separator; line += ast1.execution_time + separator; line += ast2.final_best_cost + separator; line += ast2.execution_time; string path = @"data_sets/results/several_methods/" + mesh_type + "/"; string variables_file = method + "_" + mesh_type + "_" + env.size + "x" + env.size + ".txt"; using (StreamWriter file = File.AppendText(path + variables_file)) { file.WriteLine(line); } string path2 = @"data_sets/results/several_methods/"; string variables_file2 = method + "_" + mesh_type + ".txt"; using (StreamWriter file = File.AppendText(path2 + variables_file2)) { file.WriteLine(line); } }
//------------------------------------------------------------------- private List <int> FindRoute(ref MeshEnvironment env) { //Pseudo ruta List <int> pseudo_route = GetPseudoRoute(ref env); //Variable para almacenar la nueva ruta List <int> route = new List <int>(); route.Add(env.start_node); for (int i = 0; i < pseudo_route.Count - 1; i++) { int node1 = pseudo_route[i]; int node2 = pseudo_route[i + 1]; List <int> fragment_route = ConnectNodes(ref env, ref route, node1, node2); if (fragment_route.Count != 0) { fragment_route.RemoveAt(0); route = route.Concat(fragment_route).ToList(); } else { route = new List <int>(); break; } } return(route); }
//-------------------------------------------------------------------\ private List <int> GetPseudoRoute(ref MeshEnvironment env) { //Pseudo ruta //Random Process List <int> pseudo_route = new List <int>(); pseudo_route.Add(env.start_node); int i = 0; int random_idx = -1; Double current_proximity = env.CalculateProximity(env.start_node); while (i < num_random_nodes && random_idx != env.final_node - 1) { random_idx = random.Next(pseudo_route[pseudo_route.Count - 1], env.final_node); Double next_proximity = env.CalculateProximity(random_idx); if (!env.obstacles.Contains(random_idx) && !pseudo_route.Contains(random_idx) && next_proximity < current_proximity) { pseudo_route.Add(random_idx); i++; current_proximity = next_proximity; } } pseudo_route.Add(env.final_node); return(pseudo_route); }
//--------------------------------------------------------------------- //This function takes two nodes, and tries to connect then following the best proximity in each step private List <int> ConnectNodes(ref MeshEnvironment env, ref List <int> current_route, int node1, int node2) { //Init the fragment route with the node1 List <int> fragment_route = new List <int>(); fragment_route.Add(node1); //Init the loop from the node1 to the node2 int current_node = node1; while (current_node != node2) { //In each step I select the node that has the best proximity value int next_node = FindBestNode(ref env, ref fragment_route, ref current_route, current_node, node2); if (next_node != -1) { //If the node is not null add to the fragment list fragment_route.Add(next_node); current_node = next_node; } else { //If there is an stuck condition, the algorithm breaks the loop break; } } //If there is an stuck condition, return a empty fragment if (current_node != node2) { fragment_route = new List <int>(); } return(fragment_route); }
//-------------------------------------------------------------------\ private List <int> GetPseudoRoute(ref MeshEnvironment env) { //Pseudo route //Random Process List <int> pseudo_route = new List <int>(); pseudo_route.Add(env.start_node); int i = 0; int random_idx = -1; Double current_proximity = env.CalculateProximity(env.start_node); //Init the loop from the initial node and chose a node randomly while (i < num_random_nodes && random_idx != env.final_node - 1) { //In each step, I verify that the new random node is farther than the previous one, checking the proximity value of that node. random_idx = random.Next(pseudo_route[pseudo_route.Count - 1], env.final_node); Double next_proximity = env.CalculateProximity(random_idx); if (!env.obstacles.Contains(random_idx) && !pseudo_route.Contains(random_idx) && next_proximity < current_proximity) { //Only add the a new random node that it is further that the previous one pseudo_route.Add(random_idx); i++; current_proximity = next_proximity; } } //At the end, add the final node pseudo_route.Add(env.final_node); return(pseudo_route); }
//------------------------------------------------------------------- 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; } }
// . . . . . . . . . . . . . . . . . . . . . . constructor public AgentSystem(List <Point3d> positions, MeshEnvironment ME) { this.ME = ME; Agents = new List <Agent>(); for (int i = 0; i < positions.Count; i++) { Agents.Add(new Agent(this, positions[i], RandomVectorOnMesh(ME.M, positions[i], i) * 1.5)); } }
//------------------------------------------------------------------- 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; } }
// . . . . . . . . . . . . . . . . . . . . . . constructor public ParticleSystem(List <Point3d> positions, MeshEnvironment ME) { this.ME = ME; Particles = new List <Particle>(); for (int i = 0; i < positions.Count; i++) { Particles.Add(new Particle(this, positions[i], RandomVectorOnMesh(ME.M, positions[i], i) * 1.5)); } }
public static void Test_Genetic(string mesh_type) { int[] sizes_mesh = new int[21] { 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50 }; int[] final_positions = new int[21] { 99, 143, 195, 255, 323, 399, 483, 575, 675, 783, 899, 1023, 1155, 1295, 1443, 1599, 1763, 1935, 2115, 2303, 2499 }; for (int i = 0; i < sizes_mesh.Length; i++) { string size = "_" + sizes_mesh[i] + "x" + sizes_mesh[i] + ".txt"; string file_name = mesh_type + size; Console.WriteLine("Init Execution -> " + file_name); //------------------------------------------------------------------- //Create the mesh environment MeshEnvironment env = new MeshEnvironment(_start: 0, _final: final_positions[i], _file_name: file_name, sizes_mesh[i]); env.InitEnviroment(type_mesh: mesh_type); //------------------------------------------------------------------- for (int j = 0; j < num_test; j++) { env.FillDistanceMatrix(); DijkstraAlgorithm dk1 = new DijkstraAlgorithm(); dk1.Execute(ref env); GeneticAlgorithm gn1 = new GeneticAlgorithm(); gn1.Execute(ref env); //Insert the obstacle in a middle zone of the current optimal solution InsertSeveralObstacle(ref env, num_obstacle: 2, num_routes: 2); env.FillDistanceMatrix(); DijkstraAlgorithm dk2 = new DijkstraAlgorithm(); dk2.Execute(ref env); GeneticAlgorithm gn2 = new GeneticAlgorithm(); gn2.Execute(ref env); ////Store variables in a txt Console.WriteLine("Execution {0} of " + file_name, j); StoreVariable_Genetic(mesh_type, ref env, ref dk1, ref gn1, ref dk2, ref gn2); env.ClearObstacles(); } Console.WriteLine("End Execution -> " + file_name); Console.WriteLine("---------------------------------------------"); } }
//------------------------------------------------------------------- public void CreateRandomIndividual(ref MeshEnvironment env) { List <int> route = FindRoute(ref env); while (route.Count == 0) { route = FindRoute(ref env); } path = route; SetExtraParameters(ref env); }
public static void InsertSeveralObstacle(ref MeshEnvironment env, int num_obstacle, int num_routes) { for (int i = 0; i < num_routes; i++) { env.FillDistanceMatrix(); DijkstraAlgorithm dk = new DijkstraAlgorithm(); dk.Execute(ref env); //Ver bien como poner esto env.InsertObstacle(ref dk.final_best_path, num_obstacle); } }
//------------------------------------------------------------------------------- public Double MeasureHeuristic(int node1, ref MeshEnvironment env) { //Djisktra Double heuristic_value = 0; //A-star, we can use different heuristic criteria //Double heuristic_value = env.world[node1].distance_to_final; //int idx = env.world[node1].neighboors.IndexOf(node2); //Double heuristic_value = env.CalculateProximity(node1); return(heuristic_value); }
//------------------------------------------------------------------------------- // Get the posible nodes where the ant can move public List <int> GetPosibleNodes(int current_position, ref MeshEnvironment env) { //Obtengo los posibles nodos a los cuales me puedo mover //Primer filtro solo los que vertices conectados List <int> list_posible_nodes = new List <int>(env.world[current_position].neighboors); //Filtrar obstaculos list_posible_nodes = list_posible_nodes.Except(env.obstacles).ToList(); //Filtrar nodos que ya se han visitado //posible_nodes = posible_nodes.Except(posible_nodes.Intersect(current_path)).ToList(); return(list_posible_nodes); }
//--------------------------------------------------------------------- public static void StoreVariable_RW1_and_ACOv0(string mesh_type, ref MeshEnvironment env, ref AntColonyOptimizationv0 aco, ref RandomWalkv1 rw1) { env.FillDistanceMatrix(); DijkstraJustCost dijkstra = new DijkstraJustCost(); Double best_cost = dijkstra.DijkstraAlgo(graph: env.distances, source: env.start_node, verticesCount: env.final_node + 1); Double percentage_learning = MeasureFunctions.CalculatePercentageLearning(ref env); string separator = " "; string line = mesh_type + separator; line += env.world.Count + separator; line += env.edges.Count + separator; line += best_cost + separator; line += aco.max_ants + separator; line += aco.alpha + separator; line += aco.beta + separator; line += aco.tau_0 + separator; line += aco.evaporation_factor + separator; line += aco.percentage_convergence + separator; line += aco.episode_counter + separator; line += aco.execution_time + separator; line += aco.stuck_roads + separator; line += MeasureFunctions.GetVisitedNodes(ref env) + separator; line += MeasureFunctions.GetVisitedEdges(ref env) + separator; line += Math.Round(aco.best_cost, 2) + separator; line += percentage_learning + separator; line += rw1.num_random_walks + separator; line += rw1.random_movements + separator; line += rw1.evaporation_factor + separator; line += rw1.best_cost + separator; line += rw1.execution_time; string path = @"data_sets/results/acov0_rw1/" + mesh_type + "/"; string variables_file = "variablesarw1" + "_" + mesh_type + "_" + env.size + "x" + env.size + ".txt"; using (StreamWriter file = File.AppendText(path + variables_file)) { file.WriteLine(line); } string path2 = @"data_sets/results/acov0_rw1/"; string variables_file2 = "variablesrw1" + "_" + mesh_type + ".txt"; using (StreamWriter file = File.AppendText(path2 + variables_file2)) { file.WriteLine(line); } }
//------------------------------------------------------------------- public void Reinforcement(ref MeshEnvironment env, ref List <int> route) { for (int i = 0; i < route.Count - 1; i++) { int node1_idx = route[i]; int node2_idx = route[i + 1]; int index = env.world[node1_idx].neighboors.IndexOf(node2_idx); int edge_idx = env.world[node1_idx].edges[index]; DeltaTau(ref env, ref route); env.edges[edge_idx].pheromone_amount += delta_tau; } }
//-------------------------------------------------------------------- public static int GetVisitedEdges(ref MeshEnvironment env) { int visited_edges = 0; foreach (var edge in env.edges) { if (edge.visited) { visited_edges++; } } return(visited_edges); }
//-------------------------------------------------------------------- public static int GetVisitedNodes(ref MeshEnvironment env) { int visited_nodes = 0; foreach (var node in env.world) { if (node.visited) { visited_nodes++; } } return(visited_nodes); }
//------------------------------------------------------------------- public bool CheckConvergence(ref List <Antv0> colony, ref MeshEnvironment env) { int num_convergence = (int)Math.Round(max_ants * percentage_convergence); Double best_cost_ant = Double.MaxValue; int best_ant = -1; for (int k = 0; k < colony.Count; k++) { Double current_cost = colony[k].current_cost; if (current_cost < best_cost_ant) { best_cost_ant = current_cost; best_ant = k; } } List <int> best_route_ant = colony[best_ant].current_route; int i = 0, j = 0; while (i < num_convergence && j < max_ants) { if (colony[j].current_route.SequenceEqual(best_route_ant)) { i++; } j++; } if (best_route_ant.Count != 0) { if (i == num_convergence) { best_cost = best_cost_ant; best_route = best_route_ant; return(true); } else { return(false); } } else { return(false); } }
//------------------------------------------------------------------- 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); }
//--------------------------------------------------------------------------- //Function for creating the initial random population public void CreateInitialPopulation(ref MeshEnvironment env) { population = new List <Individual>(); for (int i = 0; i < num_individuals; i++) { Individual ind = new Individual(random, num_random_nodes, coef_node_obs, coef_edge_obs); ind.CreateRandomIndividual(ref env); while (population.Contains(ind)) { ind = new Individual(random, num_random_nodes, coef_node_obs, coef_edge_obs); ind.CreateRandomIndividual(ref env); } population.Add(ind); } }
//------------------------------------------------------------------------------- public Double MeasureHeuristic(int current_node, int node1, ref MeshEnvironment env) { Double heuristic_value; if (current_node == env.start_node && node1 == env.start_node) { heuristic_value = env.world[node1].distance_to_final; } else { //heuristic_value = 1 / env.CalculateProximity(current_node, node1); int idx = env.world[current_node].neighboors.IndexOf(node1); heuristic_value = 1 / env.world[current_node].proximities[idx]; } return(heuristic_value); }
//------------------------------------------------------------------ public static Double GetCostJoinRW_KN(ref List <int> path, ref MeshEnvironment env) { Double cost = 0; for (int i = 0; i < path.Count - 1; i++) { int node1_idx = path[i]; int node2_idx = path[i + 1]; int index = env.world[node1_idx].neighboors.IndexOf(node2_idx); int edge_idx = env.world[node1_idx].edges[index]; cost += env.edges.Find(e => e.id == edge_idx).distance; } return(cost); }