def build_solution(self): """ Builds a mastermind guess based on the configured encoding """ # empty linear solution solution_representation = [] size = self._encoding.size data = self._encoding.encoding_data # if elements can be repeated if self._encoding.can_repeat_elements: for _ in range(0, size): solution_representation.append( choice( data ) ) solution = LinearSolution(representation = solution_representation, encoding_rule = self._encoding_rule) return solution # if elements cannot be repeated else: encoding_data_temp = deepcopy( data ) for _ in range(0, size): element = choice( encoding_data_temp ) solution_representation.append( element ) encoding_data_temp.remove( element ) solution = LinearSolution(representation = solution_representation, encoding_rule = self._encoding_rule) return solution
def cycle_crossover(problem, solution1, solution2): # get the representation (list) of both solutions solution_1 = solution1.representation solution_2 = solution2.representation cycles = [] considered = [] # find the cycles while len(considered) < len(solution_1): i = 0 while i in considered: i += 1 cycle = [] full_cycle = False while full_cycle == False: cycle.append(i) considered.append(i) i = solution_1.index(solution_2[i]) if i in considered: full_cycle = True cycles.append(cycle) # create empty children child1 = [None] * len(solution_1) child2 = [None] * len(solution_1) # getting the children for i, cycle in enumerate(cycles): # note that here cycle 1 is the cycle with index 0 if i % 2 == 0: for j in cycle: child1[j] = solution_1[j] child2[j] = solution_2[j] else: for j in cycle: child1[j] = solution_2[j] child2[j] = solution_1[j] # save the children as LinearSolution objects child_1 = LinearSolution(child1, solution1.encoding_rule) child_2 = LinearSolution(child2, solution2.encoding_rule) return child_1, child_2
def tsp_get_neighbors_np(self, solution, problem, neighborhood_size=0, n_changes=3): initial_sol = np.asarray( solution.representation) # change to numpy array for performance neighbors_np = [initial_sol] # list of numpy arrays for performance def n_change(list_solutions): neighbors = [] for k in list_solutions: # find all neighbors for l in range(0, len(k)): for j in range((l + 1), len(k)): neighbor = np.copy(k) neighbor[l], neighbor[j] = neighbor[j], neighbor[l] neighbors.append(neighbor) return neighbors for i in range(0, n_changes): # How many swaps to allow, neighbors_np = n_change( neighbors_np ) # This escalates fast!!! one should be more than enough # convert back to linear solution for evaluation neighbors_final = [] for sol in neighbors_np: sol = sol.tolist() solution = LinearSolution(representation=sol, encoding_rule=self._encoding_rule) neighbors_final.append(solution) return neighbors_final # return a list of solutions
def fast_solution_copy( self, representation, feedback=None ): # << This method does not need to be extended, it already automated solutions evaluation, for Single-Objective and for Multi-Objective encoding_data = self._encoding.encoding_data solution_copy = LinearSolution(representation=copy(representation), encoding_rule=self._encoding_rule) return solution_copy
def build_solution(self): """ """ solution_representation = sample(self._encoding.encoding_data, self._encoding.size) solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self): # empty linear solution solution_representation = [] # size = self._encoding.size data = self._encoding.encoding_data max = data[-1] min = data[0] solution_representation.append( randint( min, max) ) solution = LinearSolution(representation = solution_representation, encoding_rule = self._encoding_rule) return solution
def build_solution(self): """ """ solution_representation = [] for i in range(0, self._encoding.size): solution_representation.append(i) random.shuffle(solution_representation) solution_representation.append(solution_representation[0]) solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self): """ Builds a linear solution based on min and max values """ solution_representation = [] encoding_data = self._encoding.encoding_data for iGene in range(0, self._encoding.size): solution_representation.append( randint(encoding_data["min"][iGene], encoding_data["max"][iGene])) solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self): """ """ solution_representation = [] encoding_data = deepcopy(self._encoding.encoding_data) while len(solution_representation) < self._encoding.size: new_city = choice(encoding_data) encoding_data.remove(new_city) solution_representation.append(new_city) solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def tsp_bitflip_get_neighbors(solution, problem, neighborhood_size=0): neighborhood = [] # if the neighborhood size is -1 we get all neighbors if neighborhood_size == -1: for i in range(0, len(solution.representation)): for j in range(0, len(solution.representation)): if i != j: # swap two different cities neighbor = solution.representation[:] neighbor[i] = solution.representation[j] neighbor[j] = solution.representation[i] # check if this neighbor is not repeated if neighbor not in neighborhood: neighborhood.append(neighbor) else: while len(neighborhood) < neighborhood_size: # swap two different random cities i = randint(0, len(solution.representation) - 1) j = randint(0, len(solution.representation) - 1) while i == j: j = randint(0, len(solution.representation) - 1) # deep copy of solution neighbor = solution.representation[:] neighbor[i] = solution.representation[j] neighbor[j] = solution.representation[i] # check if this neighbor is not repeated if neighbor not in neighborhood: neighborhood.append(neighbor) neighbors = [] # create LinearSolution objects for neighbor in neighborhood: neigh = LinearSolution(neighbor, solution.encoding_rule) neighbors.append(neigh) return neighbors
def build_solution(self): """ Builds a linear solution for Knapsack with same size of decision variables with 0s and 1s. Where: 0 indicate that item IS NOT in the knapsack 1 indicate that item IS in the knapsack """ solution_representation = [] encoding_data = self._encoding.encoding_data for _ in range(0, self._encoding.size): solution_representation.append(choice(encoding_data)) #print(solution_representation) solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self): """ Builds a linear solution for TSP with a specific order of cities """ solution_representation = [] encoding_data = self._encoding.encoding_data # Choose an initial random city solution_representation.append(randint(1, len(encoding_data))) # Build a solution by always appending the closest next city for i in range(len(encoding_data)): dists = [ x for x in self._distances[solution_representation[-1] - 1] ] sorDist = sorted(dists) for j in sorDist: if (dists.index(j) + 1) not in solution_representation: solution_representation.append(dists.index(j) + 1) break solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self): """ Builds a linear solution for TSP that is an ordered list of numbers, with no repetitions Where: each number i corresponds to the city of index i in the distance matrix """ solution_representation = [] encoding_data = self._encoding.encoding_data[:] for _ in range(0, self._encoding.size): # choose a random city city = choice(encoding_data) solution_representation.append(city) # remove it from the list of possibilities encoding_data.remove(city) # create a LinearSolution object solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self): """ To build the solution we pick 32 stocks from the list as par Fisher and laurie (1970) """ solution_representation = [] #calculate portfolio investment def cal_total_investment(portfolio): total_investment = 0 for i in range(0, len(portfolio)): if portfolio[i] >= 1: #print(i, 'printing i') total_investment += float(self._prices[i]) * portfolio[i] return total_investment solution_representation = [0] * self._encoding_rule['Size'] solution_investment = 0 tolerance = 0.20 #limit before reaching the full investment stock_counter = self._optimum_stocks for i in takewhile( lambda i: i < stock_counter and solution_investment < self. _max_investment * (1 - tolerance), count()): n = choice(self._encoding_rule['Data']) solution_representation[randint(0, len(solution_representation) - 1)] = n solution_investment += cal_total_investment( solution_representation) i += 1 solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) #print(f'Build Solution: total stocks picked in {sum(solution.representation)}, at cost: {solution_investment}') return solution
def build_solution(self): """ Builds a linear solution for PIP with same size of decision variables integers. Where: This integer represents the number of stocks we bought for that asset """ solution_representation = [] encoding_data = self._encoding.encoding_data randoms = [] # assign random numbers between 0 and 1 to each asset for _ in range(0, self._encoding.size): randoms.append(uniform(0, 1)) weights = [] # get the investment weights for each asset based on the random numbers for random in randoms: weights.append(random / sum(randoms)) prices = self._prices budget = self._budget # calculate how much that investment weight costs related to our budget for i in range(0, len(weights)): investment = weights[i] * budget # divide the money we're investing by the price of the stocks to find out how many we can buy solution_representation.append(round(investment / prices[i])) # create a LinearSolution object solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution
def build_solution(self, method='Random'): """ Creates a initial solution and returns it according to the encoding rule and the chosen method from the following available methods: - 'Hill Climbing' - 'Random' (default method) - 'Greedy' """ if method == 'Random': # shuffles the list and then instantiates it as a Linear Solution encoding_data = self._encoding.encoding_data solution_representation = encoding_data.copy() np.random.shuffle(solution_representation) # inplace shuffle solution = LinearSolution(representation=solution_representation, encoding_rule=self._encoding_rule) return solution elif method == 'Hill Climbing': solution = HillClimbing( problem_instance=self, neighborhood_function=self.tsp_get_neighbors_np).search() #TODO: allow changes in params for Hill Climbing return solution #elif method == 'Simulated Annealing': TODO: build SA initialization # return solution elif method == 'Greedy': # get a random solution where we will keep the first element initial_solution = np.array( self.build_solution(method='Random').representation) copy = initial_solution.copy() element = initial_solution[0] # i can not reach the last position because there is no more cities to evaluate for i in range(1, (len(initial_solution) - 1)): distance_array = np.array( heapq.nsmallest(len(initial_solution), self._distances[element])) # get the index (item name) of the second smallest distance between element in index i and all the other cities closest_city = np.argwhere( self._distances[element] == distance_array[1])[0][0] if closest_city == 0: # the closest city can not be our first city on the matrix closest_city = np.argwhere( self._distances[element] == distance_array[2])[0][0] n = 2 # let us to go through the distance ascending list # while the closest city is already in the changed slice of the initial_solution, we have to keep looking while closest_city in initial_solution[0:i]: # get the next closest city in the distance ascending list with the element evaluated closest_city = np.argwhere( self._distances[element] == distance_array[n])[0][0] if closest_city == 0: # the closest city can not be our first city on the matrix closest_city = np.argwhere(self._distances[element] == distance_array[n + 1])[0][0] n += 1 # if it is not a valid closest city the n should be plus one than the usual n += 1 # change the current position in initial_solution with the closest_city initial_solution[i] = closest_city # get the next element to evaluate the closest city element = initial_solution[i] # change the last index with the missing element initial_solution[-1] = np.setdiff1d(copy, initial_solution[0:-1], assume_unique=True)[0] #print('greedy solutions: ', list(initial_solution)) solution = LinearSolution(representation=list(initial_solution), encoding_rule=self._encoding_rule) return solution else: print( 'Please choose one of these methods: Hill Climbing, Greedy, Random or Multiple. It will use the Random method' ) return self.build_solution()
def pmx_crossover(problem, solution1, solution2): # get the representation (list) of both solutions solution_1 = solution1.representation solution_2 = solution2.representation # choose two different random points in the solutions point1 = randint(0, len(solution_1) - 1) point2 = point1 while point1 == point2: point2 = randint(0, len(solution_1) - 1) # make sure that the fist crossover point is the smallest and vice versa firstCrossPoint = min(point1, point2) secondCrossPoint = max(point1, point2) # select the middle section of each parent parent1MiddleCross = solution_1[firstCrossPoint:secondCrossPoint] parent2MiddleCross = solution_2[firstCrossPoint:secondCrossPoint] # create children that are equal to the respective parent minus the middle section child1 = solution_1[:firstCrossPoint] + parent2MiddleCross + solution_1[ secondCrossPoint:] child2 = solution_2[:firstCrossPoint] + parent1MiddleCross + solution_2[ secondCrossPoint:] # save the relations in the middle section relations = [] for i in range(len(parent1MiddleCross)): relations.append([parent2MiddleCross[i], parent1MiddleCross[i]]) # check if any of the children have repeated elements in them counts1 = [child1.count(i) for i in child1] counts2 = [child2.count(i) for i in child2] # while there are repeated elements in child 1 while len([x for x in counts1 if x > 1]) > 0: # check the part before the middle section for i in child1[:firstCrossPoint]: for j in parent2MiddleCross: if i == j: # replace the repeated element OUTSIDE of the middle section using the relations we defined index_j = parent2MiddleCross.index(j) relation = relations[index_j] index_i = child1.index(i) child1[index_i] = relation[1] # check the part after the middle section for i in child1[secondCrossPoint:]: for j in parent2MiddleCross: if i == j: # replace the repeated element OUTSIDE of the middle section using the relations we defined index_j = parent2MiddleCross.index(j) relation = relations[index_j] index_i = child1.index(i, secondCrossPoint) child1[index_i] = relation[1] # check again if there are repeated elements in child 1 counts1 = [child1.count(i) for i in child1] # while there are repeated elements in child 1 while len([x for x in counts2 if x > 1]) > 0: # check the part before the middle section for i in child2[:firstCrossPoint]: for j in parent1MiddleCross: if i == j: # replace the repeated element OUTSIDE of the middle section using the relations we defined index_j = parent1MiddleCross.index(j) relation = relations[index_j] index_i = child2.index(i) child2[index_i] = relation[0] # check the part after the middle section for i in child2[secondCrossPoint:]: for j in parent1MiddleCross: if i == j: # replace the repeated element OUTSIDE of the middle section using the relations we defined index_j = parent1MiddleCross.index(j) relation = relations[index_j] index_i = child2.index(i, secondCrossPoint) child2[index_i] = relation[0] # check again if there are repeated elements in child 1 counts2 = [child2.count(i) for i in child2] # create LinearSolution objects child_1 = LinearSolution(child1, solution1.encoding_rule) child_2 = LinearSolution(child2, solution2.encoding_rule) return child_1, child_2
def order_1_crossover(problem, solution1, solution2): # get the representation (list) of both solutions solution_1 = solution1.representation solution_2 = solution2.representation # choose two different random points in the solutions point1 = randint(0, len(solution_1) - 1) point2 = point1 while point1 == point2: point2 = randint(0, len(solution_1) - 1) # make sure that the first crossover point is the smallest and vice versa firstCrossPoint = min(point1, point2) secondCrossPoint = max(point1, point2) # save the middle section of each parent parent1MiddleCross = solution_1[firstCrossPoint:secondCrossPoint] parent2MiddleCross = solution_2[firstCrossPoint:secondCrossPoint] order_1 = [] # we start saving the sequence after the middle section for i in solution_2[secondCrossPoint:]: # make sure we don't have repeated elements if i not in parent1MiddleCross: order_1.append(i) # then we go from the beginning up to where we started for i in solution_2[:secondCrossPoint]: # make sure we don't have repeated elements if i not in parent1MiddleCross: order_1.append(i) order_2 = [] # we start saving the sequence after the middle section for i in solution_1[secondCrossPoint:]: # make sure we don't have repeated elements if i not in parent2MiddleCross: order_2.append(i) # then we go from the beginning up to where we started for i in solution_1[:secondCrossPoint]: # make sure we don't have repeated elements if i not in parent2MiddleCross: order_2.append(i) # create two empty children child1 = [None] * len(solution_1) child2 = [None] * len(solution_1) # first save the middle section for i in range(firstCrossPoint, secondCrossPoint): child1[i] = solution_1[i] child2[i] = solution_2[i] # then we start filling in from the end of the middle section j = 0 for i in range(secondCrossPoint, len(solution_1)): child1[i] = order_1[j] child2[i] = order_2[j] j += 1 # and then we fill in from the beginning up to the beginning of the middle section for i in range(0, firstCrossPoint): child1[i] = order_1[j] child2[i] = order_2[j] j += 1 # save the children as LinearSolution objects child_1 = LinearSolution(child1, solution1.encoding_rule) child_2 = LinearSolution(child2, solution1.encoding_rule) return child_1, child_2