def alghorithm(self, matrix, start): vertNo = int(matrix.shape[0] / 2) #start = random.randint(0, vertNo * 2 - 1) visited = [] visited.append(start) next_min = find_min(matrix, visited, start) visited.append(next_min) for _ in range(0, vertNo - 2): temp_visited = visited.copy() temp_visited2 = visited.copy() best_key, best_key2, best_vert_for_edges = self.find_two_best_verts( matrix, visited ) # find two best vert which distance to visited egdes is min temp_visited = np.insert( np.array(temp_visited), best_key[1], best_vert_for_edges[best_key]) # add first best temp_visited = np.insert( np.array(temp_visited), best_key2[1], best_vert_for_edges[best_key2]) # add second next best cost1 = count_distance(matrix, temp_visited) # calculate cost temp_visited2 = np.insert( np.array(temp_visited2), best_key2[1], best_vert_for_edges[best_key2]) # add first second best temp_visited2 = np.insert( np.array(temp_visited2), best_key[1], best_vert_for_edges[best_key]) # add second first best cost2 = count_distance(matrix, temp_visited2) # calculate cost if cost1 > cost2: # insert value with visited = np.insert(np.array(visited), best_key[1], best_vert_for_edges[best_key]) else: visited = np.insert(np.array(visited), best_key2[1], best_vert_for_edges[best_key2]) distanceSum = count_distance(matrix, visited) return distanceSum, visited
def alghorithm1(self, matrix, start, not_start): visited = start not_visited = not_start cost = count_distance(matrix, start) found_better = True while found_better: best_visited1, best_not_visited, min_cost1 = self.find_better_vert( visited, not_visited, cost, matrix) best_visited2, min_cost2 = self.change_2_verts( visited, cost, matrix) if min_cost1 < cost and min_cost2 < cost: if min_cost1 < min_cost2: cost = min_cost1 visited = best_visited1 not_visited = best_not_visited else: cost = min_cost2 visited = best_visited2 elif min_cost1 < cost: cost = min_cost1 visited = best_visited1 not_visited = best_not_visited elif min_cost2 < cost: cost = min_cost2 visited = best_visited2 else: found_better = False return cost, visited
def change_2_edges(self, visited, cost, matrix): min_cost = cost best_visited = [] cycle = np.append(visited, visited[0]) for i in range(0, len(visited) - 2): for j in range(i + 3, len(visited) - 1): cycle_copy = cycle.copy() if i == 0 and len(cycle) - 3 > j: chunk = cycle[i + 1:j + 1] chunk = chunk[::-1] cycle_copy[i + 1:j + 1] = chunk elif i == 1 and len(cycle) - 2 > j: chunk = cycle[i + 1:j + 1] chunk = chunk[::-1] cycle_copy[i + 1:j + 1] = chunk elif i != 0 and i != 1: chunk = cycle[i + 1:j + 1] chunk = chunk[::-1] cycle_copy[i + 1:j + 1] = chunk cost_now = count_distance(matrix, cycle_copy[:-1]) if cost_now < min_cost: min_cost = cost_now best_visited = cycle_copy[:-1] if len(best_visited) > 0: return best_visited, min_cost else: return visited, cost
def alghorithm(self, matrix, start, not_start): visited = start not_visited = not_start cost = count_distance(matrix, start) found_better = True while found_better: idx = random.randint(0, len(visited)) random_visited = list(visited[idx:]) + list(visited[:idx]) best_visited1, best_not_visited, min_cost1 = self.find_better_vert( random_visited, not_visited, cost, matrix) idx = random.randint(0, len(visited)) random_visited = list(visited[idx:]) + list(visited[:idx]) best_visited2, min_cost2 = self.change_2_edges( random_visited, cost, matrix) if min_cost1 < cost and min_cost2 < cost: if min_cost1 < min_cost2: cost = min_cost1 visited = best_visited1 not_visited = best_not_visited else: cost = min_cost2 visited = best_visited2 elif min_cost1 < cost: cost = min_cost1 visited = best_visited1 not_visited = best_not_visited elif min_cost2 < cost: cost = min_cost2 visited = best_visited2 else: found_better = False return cost, visited, not_visited
def algorithm(self, matrix, start): vertNo = int(matrix.shape[0] / 2) #start = random.randint(0, vertNo * 2 - 1) visited = [] visited.append(start) next_min = find_min(matrix, visited, start) visited.append(next_min) # for 48 verts for _ in range(0, vertNo - 2): lowest_cost_for_edges = {} best_vert_for_edges = {} to_check = list(set(range(len(matrix))) - set(visited)) # all vert not visited # for all edges check distances to all free verts and get min cost for j in range(len(visited) - 1): new_vert_cost = {} for v in to_check: # check all not visited vert new_vert_cost[v] = cost(visited[j], visited[j + 1], v, matrix) # method cost calculate distance between new vert and egdes from visited [j] &[j+1] min_cost_key = int(min(new_vert_cost, key=new_vert_cost.get)) # minimum distance lowest_cost_for_edges[(j, j + 1)] = new_vert_cost[min_cost_key] # minimum distance for all edges best_vert_for_edges[(j, j + 1)] = min_cost_key # vert # final edge cost (last in list and first) new_vert_cost = {} for v in to_check: new_vert_cost[v] = cost(visited[-1], visited[0], v, matrix) # check last and first vert(one edges) from visited min_cost_key = int(min(new_vert_cost, key=new_vert_cost.get)) lowest_cost_for_edges[(len(visited) - 1, 0)] = new_vert_cost[min_cost_key] best_vert_for_edges[(len(visited) - 1, 0)] = min_cost_key # get best vert to add best_key = min(lowest_cost_for_edges, key=lowest_cost_for_edges.get) # add it to solution visited = np.insert(np.array(visited), best_key[1], best_vert_for_edges[best_key]) distanceSum = count_distance(matrix, visited) return distanceSum, visited
def init_random_population(self): i = 0 while i < self.population_size: visited = list(self.start_solution()) if visited not in self.population: self.population.append(visited) self.population_costs.append( count_distance(self.matrix, visited)) i += 1
def change_2_verts(self, visited, cost, matrix): min_cost = cost for idx in range(len(visited)): for idx2 in range(idx + 1, len(visited)): vis_copy = visited.copy() vis_copy[idx] = vis_copy[idx2] vis_copy[idx2] = visited[idx] new_cost = count_distance(matrix, vis_copy) if new_cost < min_cost: min_cost = new_cost best_visited = vis_copy return best_visited, min_cost return visited, cost
def find_better_vert(self, visited, not_visited, cost, matrix): min_cost = cost for idx, vert in enumerate(visited): for idx2, vert2 in enumerate(not_visited): vis_copy = visited.copy() vis_copy[idx] = vert2 new_cost = count_distance(matrix, vis_copy) if new_cost < min_cost: min_cost = new_cost best_visited = vis_copy best_n_vis = not_visited.copy() best_n_vis[idx2] = vert return best_visited, best_n_vis, min_cost return visited, not_visited, cost