Beispiel #1
0
    def onePointCrossover(self, parent1, parent2, crossoverRate):
        """ Create two new child candidates by crossing over parent genes.
        Parent genes are splitted by one point and then concatenate to generate child genes
        
        Parameters:
            - parent1 (Candidate): First parent to crossover
            - parent2 (Candidate): Second parent to crossover
            - crossoverRate (float): Ratio defines if these parents are crossover or not
        
        Return:
            Tuple of two child generate from the crossover process
        """

        child1 = Candidate()
        child2 = Candidate()

        # Make a copy of the parent genes.
        grid1 = npCopy(parent1.gene)
        grid2 = npCopy(parent2.gene)

        gridSize = len(parent1.gene)

        r = random.random()
        if r < crossoverRate:
            # Get a ranom crossover point to split parent genes
            crossPoint = random.randint(1, gridSize - 2)
            child1.gene = npConcatenate(
                (grid1[:crossPoint], grid2[crossPoint:]), axis=0)
            child2.gene = npConcatenate(
                (grid2[:crossPoint], grid1[crossPoint:]), axis=0)
        else:
            child1.gene = grid1
            child2.gene = grid2

        return child1, child2
Beispiel #2
0
    def choiceCrossover(self, parent1, parent2, crossoverRate):
        """ Create two new child candidates by crossing over parent genes.
        The child will randomly choose each sub grid from first parent or second parent 
        
        Parameters:
            - parent1 (Candidate): First parent to crossover
            - parent2 (Candidate): Second parent to crossover
            - crossoverRate (float): Ratio defines if these parents are crossover or not
        
        Return:
            Tuple of two child generate from the crossover process
        """

        child1 = Candidate()
        child2 = Candidate()

        # Make a copy of the parent genes.
        grid1 = parent1.gene
        grid2 = parent2.gene

        gridSize = len(parent1.gene)
        r = random.random()
        if r < crossoverRate:
            for i in range(gridSize):
                # Randomly select sub-block from two parents to generate new child
                blocks = [grid1[i], grid2[i]]
                child1.gene[i] = npCopy(random.choice(blocks))
                child2.gene[i] = npCopy(random.choice(blocks))
        else:
            child1.gene = npCopy(grid1)
            child2.gene = npCopy(grid2)

        return child1, child2
Beispiel #3
0
    def uniformCrossover(self, parent1, parent2, crossoverRate):
        """ Create two new child candidates by crossing over parent genes. 
        Parent genes will swap 2 consecutive sub-blocks to generate child genes
        
        Parameters:
            - parent1 (Candidate): First parent to crossover
            - parent2 (Candidate): Second parent to crossover
            - crossoverRate (float): Ratio defines if these parents are crossover or not
        
        Return:
            Tuple of two child generate from the crossover process
        """

        child1 = Candidate()
        child2 = Candidate()

        # Make a copy of the parent genes.
        grid1 = npCopy(parent1.gene)
        grid2 = npCopy(parent2.gene)

        gridSize = len(parent1.gene)
        r = random.random()
        if r < crossoverRate:
            # Select a sub-block and swap them between two parents
            crossPoint = random.randint(0, gridSize - 1)
            tmp = grid1[crossPoint]
            grid1[crossPoint] = grid2[crossPoint]
            grid2[crossPoint] = tmp
            child1.gene = grid1
            child2.gene = grid2
        else:
            child1.gene = grid1
            child2.gene = grid2

        return child1, child2
 def localSearch(self, coef, given):
     candidateList = []
     for _ in range(coef):
         candidate = Candidate()
         candidate.gene = npCopy(self.gene)
         candidate.localSearchMethod(self, given)
         candidateList.append(candidate)
     
     return candidateList
Beispiel #5
0
    def twoPointcrossover(self, parent1, parent2, crossoverRate):
        """ Create two new child candidates by crossing over parent genes.
        Parent genes are splitted by two point and then concatenate to generate child genes 
        
        Parameters:
            - parent1 (Candidate): First parent to crossover
            - parent2 (Candidate): Second parent to crossover
            - crossoverRate (float): Ratio defines if these parents are crossover or not
        
        Return:
            Tuple of two child generate from the crossover process
        """

        child1 = Candidate()
        child2 = Candidate()

        # Make a copy of the parent genes.
        grid1 = npCopy(parent1.gene)
        grid2 = npCopy(parent2.gene)

        gridSize = len(parent1.gene)
        r = random.random()
        if r < crossoverRate:
            # Select two crossover point
            crossPoint1 = random.randint(1, gridSize - 2)
            crossPoint2 = random.randint(crossPoint1 + 1, gridSize - 1)
            # Swap all sub-blocks between two crossover points to generate new child
            child1.gene = npConcatenate(
                (grid1[:crossPoint1], grid2[crossPoint1:crossPoint2],
                 grid1[crossPoint2:]),
                axis=0)
            child2.gene = npConcatenate(
                (grid2[:crossPoint1], grid1[crossPoint1:crossPoint2],
                 grid2[crossPoint2:]),
                axis=0)
        else:
            child1.gene = grid1
            child2.gene = grid2

        return child1, child2
Beispiel #6
0
    def rowColCrossover(self, parent1, parent2, crossoverRate):
        """ Create two new child candidates by crossing over parent genes.
            When two child individuals are generated from two parents, scores are obtained 
            for each of the three rows that constitute the sub-blocks of the parents, 
            and a child inherits the ones with the highest scores. Then the columns are 
            compared in the same way and the other child inherits the ones with the highest scores. 
        
        Parameters:
            - parent1 (Candidate): First parent to crossover
            - parent2 (Candidate): Second parent to crossover
            - crossoverRate (float): Ratio defines if these parents are crossover or not
        
        Return:
            Tuple of two child generate from the crossover process
        """

        child1 = Candidate()
        child2 = Candidate()

        # Make a copy of the parent genes.
        grid1 = parent1.gene
        grid2 = parent2.gene

        r = random.random()
        if r < crossoverRate:
            rowScore1 = parent1.fitnessMatrix[0]
            rowScore2 = parent2.fitnessMatrix[0]

            colScore1 = parent1.fitnessMatrix[1]
            colScore2 = parent2.fitnessMatrix[1]

            for i in range(3):
                # For each row of sub-block, the first child will inherit the row
                # with the highest fitness score between two parents
                if rowScore1[i] > rowScore2[i]:
                    child1.gene[3 * i:3 * (i + 1)] = npCopy(grid1[3 * i:3 *
                                                                  (i + 1)])
                else:
                    child1.gene[3 * i:3 * (i + 1)] = npCopy(grid2[3 * i:3 *
                                                                  (i + 1)])

                # For each col of sub-block, the first child will inherit the col
                # with the highest fitness score between two parents
                if colScore1[i] > colScore2[i]:
                    for j in range(3):
                        child2.gene[j * 3 + i] = npCopy(grid1[j * 3 + i])
                else:
                    for j in range(3):
                        child2.gene[j * 3 + i] = npCopy(grid2[j * 3 + i])
        else:
            child1.gene = npCopy(grid1)
            child2.gene = npCopy(grid2)

        return child1, child2
Beispiel #7
0
    def nextGen(self, given, tracker):
        """ 
        Find the next generation of the population".

        Parameters:
            - given (array): The given chromosome of the Sudoku problem, helps in mutation process of candidates
            - tracker (array): Helper array to help evaluate candidates' fitness
        """
        elites = []
        numElite = self.elitism

        # Extract top candidate from population. These elite candidates will
        # go to the next generation without any change
        for i in range(numElite):
            elite = Candidate()
            elite.gene = npCopy(self.candidates[i].gene)
            elites.append(elite)

        selectCandidates = selection.call(self.candidates,
                                          self.populationSize - numElite)

        newPopulation = []
        for _ in range(0, self.populationSize - numElite, 2):
            # Select 2 parents
            parents = [selectCandidates.pop(), selectCandidates.pop()]
            # parents = selection.call(self.candidates, 2)

            # Crossover them to generate new child for next generation with a crossover rate
            child1, child2 = crossover.call(parents[0], parents[1],
                                            self.crossoverRate)

            # Add child to the next genration population
            newPopulation.append(child1)
            newPopulation.append(child2)

        self.candidates = newPopulation
        # Mutate candidates in the next generation with a mutation rate
        list(map(lambda x: x.mutate(self.mutationRate, given),
                 self.candidates))
        self.candidates.extend(elites)

        # Evaluate fitness for the next generation
        self.evaluate(tracker)