Пример #1
0
    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
Пример #2
0
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
Пример #4
0
    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
Пример #5
0
    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
Пример #6
0
    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    
Пример #7
0
    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
Пример #8
0
    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
Пример #9
0
    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
Пример #10
0
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
Пример #11
0
    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
Пример #12
0
    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
Пример #13
0
    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
Пример #15
0
    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()
Пример #17
0
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
Пример #18
0
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