コード例 #1
0
 def __init__(self,
              natoms,
              minimiser,
              composition="default",
              labels=("X", ),
              pop_size=10,
              max_generation=10,
              selector=TournamentSelector(3),
              offspring=8,
              mutant_rate=0.1,
              remove_duplicates=False,
              mutator=MutateReplace(),
              crossover=DeavenHo()):
     #Parameters
     self.max_generation = max_generation
     self.mutant_rate = mutant_rate
     self.offspring = offspring
     self.pop_size = pop_size
     self.remove_duplicates = remove_duplicates
     self.selector = selector
     self.mutator = mutator
     self.crossover = crossover
     #Factory
     self.factory = ClusterFactory(natoms, minimiser, composition, labels)
     #PopulationList
     self.population = PopulationList(natoms, self.factory, pop_size)
     #Evolutionary progress
     self.mean_energy_series = []
     self.min_energy_series = []
     self.db = Database(db="mydatabase.sqlite")
     self.storage = self.db.minimum_adder()
コード例 #2
0
ファイル: test_population.py プロジェクト: marktoakley/PyBCGA
 def setUp(self):
     natoms=10
     minimiser=PeleMinimiser(lj.LJ())
     factory=ClusterFactory(natoms,minimiser)
     self.population=PopulationList(natoms,factory,max_size=5)
     while len(self.population) < self.population.max_size:
         self.population.append(factory.get_random_cluster())
コード例 #3
0
 def setUp(self):
     natoms = 10
     minimiser = PeleMinimiser(lj.LJ())
     factory = ClusterFactory(natoms, minimiser)
     self.population = PopulationList(natoms, factory, max_size=5)
     while len(self.population) < self.population.max_size:
         self.population.append(factory.get_random_cluster())
コード例 #4
0
 def test_cluster(self):
     natoms=3
     minimiser=PeleMinimiser(LJCluster(natoms))
     factory=ClusterFactory(natoms,minimiser)
     with open("restart.xyz",'r') as xyz_file:
         cluster=factory.read_xyz(xyz_file)
     self.assertEquals(-5.,cluster.get_energy())
コード例 #5
0
 def setUp(self):
     natoms = 10
     minimiser = PeleMinimiser(BLJCluster(natoms, 5))
     self.factory = ClusterFactory(natoms,
                                   minimiser,
                                   composition=[5, 5],
                                   labels=["A", "B"])
コード例 #6
0
ファイル: test_restart.py プロジェクト: marktoakley/PyBCGA
 def test_cluster(self):
     natoms = 3
     minimiser = PeleMinimiser(LJCluster(natoms))
     factory = ClusterFactory(natoms, minimiser)
     with open("restart.xyz", "r") as xyz_file:
         cluster = factory.read_xyz(xyz_file)
     self.assertEquals(-5.0, cluster.get_energy())
コード例 #7
0
 def test_replace(self):
     natoms=10
     minimiser=PeleMinimiser(lj.LJ())
     factory=ClusterFactory(natoms,minimiser)
     parent = factory.get_random_cluster()   
     mutator = MutateReplace()
     mutant = mutator.get_mutant(parent)
     self.assertLess(mutant.get_energy(), 0)
コード例 #8
0
ファイル: test_crossover.py プロジェクト: marktoakley/PyBCGA
 def test_mutant(self):
     natoms=10
     minimiser=PeleMinimiser(lj.LJ())
     factory=ClusterFactory(natoms,minimiser)
     parent_a = factory.get_random_cluster()   
     parent_b = factory.get_random_cluster() 
     crossover = DeavenHo()
     offspring = crossover.get_offspring(parent_a, parent_b)
     self.assertLess(offspring.get_energy(), 0)
コード例 #9
0
 def test_mutant(self):
     natoms = 10
     minimiser = PeleMinimiser(lj.LJ())
     factory = ClusterFactory(natoms, minimiser)
     parent_a = factory.get_random_cluster()
     parent_b = factory.get_random_cluster()
     crossover = DeavenHo()
     offspring = crossover.get_offspring(parent_a, parent_b)
     self.assertLess(offspring.get_energy(), 0)
コード例 #10
0
 def test_exchange(self):
     natoms=20
     minimiser=PeleMinimiser(BLJCluster(natoms,10))
     factory=ClusterFactory(natoms,minimiser,
                                 composition=[10,10],
                                 labels=["A","B"])
     cluster = factory.get_random_cluster()
     mutator = MutateExchange()
     for i in range(0,50):
         mutant=mutator.get_mutant(cluster)
         self.assertEquals(mutant.atom_types[9],0)
         self.assertEquals(mutant.atom_types[10],1)
コード例 #11
0
 def __init__(self,natoms,minimiser,
              composition="default",labels=("X",),
              pop_size=10,max_generation=10,
              selector=TournamentSelector(3),
              offspring=8,mutant_rate=0.1,remove_duplicates=False,
              mutator=MutateReplace(),
              crossover=DeavenHo()):
     #Parameters
     self.max_generation = max_generation
     self.mutant_rate = mutant_rate
     self.offspring=offspring
     self.pop_size=pop_size
     self.remove_duplicates=remove_duplicates
     self.selector=selector
     self.mutator = mutator
     self.crossover = crossover
     #Factory
     self.factory=ClusterFactory(natoms,minimiser,composition,labels)
     #PopulationList
     self.population = PopulationList(natoms,self.factory,pop_size)
     #Evolutionary progress
     self.mean_energy_series=[]
     self.min_energy_series=[]
     self.db = Database(db="mydatabase.sqlite")
     self.storage = self.db.minimum_adder()
コード例 #12
0
 def test_population(self):
     natoms=3
     minimiser=PeleMinimiser(LJCluster(natoms))
     factory=ClusterFactory(natoms,minimiser)
     with open("restart.xyz",'r') as xyz_file:
         population=PopulationList(natoms,factory)
         population.read_xyz(xyz_file)
     self.assertEquals(-5.,population[0].get_energy())
     self.assertEquals(-4.,population[1].get_energy())
コード例 #13
0
 def __init__(self,
              natoms,
              minimiser,
              composition="default",
              labels=("X", ),
              pop_size=10,
              max_generation=10,
              selector=TournamentSelector(3),
              offspring=8,
              mutant_rate=0.1,
              remove_duplicates=False,
              mass_extinction=False,
              epoch_thresh=1.e-6,
              restart=False,
              mutator=MutateReplace(),
              crossover=DeavenHo()):
     #Parameters
     self.max_generation = max_generation
     self.mutant_rate = mutant_rate
     self.offspring = offspring
     self.pop_size = pop_size
     self.remove_duplicates = remove_duplicates
     self.mass_extinction = mass_extinction
     self.epoch_thresh = epoch_thresh
     self.selector = selector
     self.mutator = mutator
     self.crossover = crossover
     #Factory
     self.factory = ClusterFactory(natoms, minimiser, composition, labels)
     #PopulationList
     self.population = PopulationList(natoms, self.factory, pop_size)
     if restart is False:
         while len(self.population) < self.population.max_size:
             self.population.append(self.factory.get_random_cluster())
         self.population.sort_energy()
     else:
         with open("restart.xyz", 'r') as xyz_file:
             self.population.read_xyz(xyz_file)
     #Evolutionary progress
     self.mean_energy_series = []
     self.mean_energy_series.append(self.population.get_mean_energy())
     self.min_energy_series = []
     self.min_energy_series.append(self.population.get_lowest_energy())
コード例 #14
0
class BinaryFactoryTest(unittest.TestCase):
    def setUp(self):
        natoms=10
        minimiser=PeleMinimiser(BLJCluster(natoms,5))
        self.factory=ClusterFactory(natoms,minimiser,
                                    composition=[5,5],
                                    labels=["A","B"])
        
    def test_label(self):
        cluster = self.factory.get_random_cluster()
        self.assertEquals(cluster.get_label(0),"A")
        self.assertEquals(cluster.get_label(5),"B")
コード例 #15
0
class BinaryFactoryTest(unittest.TestCase):
    def setUp(self):
        natoms = 10
        minimiser = PeleMinimiser(BLJCluster(natoms, 5))
        self.factory = ClusterFactory(natoms,
                                      minimiser,
                                      composition=[5, 5],
                                      labels=["A", "B"])

    def test_label(self):
        cluster = self.factory.get_random_cluster()
        self.assertEquals(cluster.get_label(0), "A")
        self.assertEquals(cluster.get_label(5), "B")
コード例 #16
0
 def __init__(self,natoms,minimiser,
              composition="default",labels=("X",),
              pop_size=10,max_generation=10,
              selector=TournamentSelector(3),
              offspring=8,mutant_rate=0.1,remove_duplicates=False,
              mass_extinction=False,epoch_thresh=1.e-6,
              restart=False,
              mutator=MutateReplace(),
              crossover=DeavenHo()):
     #Parameters
     self.max_generation = max_generation
     self.mutant_rate = mutant_rate
     self.offspring=offspring
     self.pop_size=pop_size
     self.remove_duplicates=remove_duplicates
     self.mass_extinction=mass_extinction
     self.epoch_thresh=epoch_thresh
     self.selector=selector
     self.mutator = mutator
     self.crossover = crossover
     #Factory
     self.factory=ClusterFactory(natoms,minimiser,composition,labels)
     #PopulationList
     self.population = PopulationList(natoms,self.factory,pop_size)
     if restart is False:
         while len(self.population) < self.population.max_size:
             self.population.append(self.factory.get_random_cluster())
         self.population.sort_energy()
     else:
         with open("restart.xyz",'r') as xyz_file:
             self.population.read_xyz(xyz_file)
     #Evolutionary progress
     self.mean_energy_series=[]
     self.mean_energy_series.append(self.population.get_mean_energy())
     self.min_energy_series=[]
     self.min_energy_series.append(self.population.get_lowest_energy())
コード例 #17
0
 def setUp(self):
     natoms=10
     minimiser=PeleMinimiser(BLJCluster(natoms,5))
     self.factory=ClusterFactory(natoms,minimiser,
                                 composition=[5,5],
                                 labels=["A","B"])
コード例 #18
0
class BatchGeneticAlgorithm(object):
    '''The Birmingham Cluster Genetic Algorithm.
    A new parallel version of the BCGA. The population is stored in a pele database and can be accessed by several processes simultaneously.
    Parameters:
    natoms- Number of atoms in cluster
    minimiser- See bcga.gpaw_interface
    Optional parameters:
    composition- A list containing the number of atoms of each type
    labels- A tuple orblist containing the names of each atom type (e.g. ["Au","Ag"]
    pop_size- Number of clusters in population
    max_generation- Number of generations to run GA
    selector- Selection method for choosing parents (see bcga.selector)
    offspring- Number of crossover operations in each generation
    mutant_rate- Probability of any cluster producing a mutant
    remove_duplicates- Remove identical clusters from population to prevent stagnation
    restart- Read population from restart.xyz and continue a search
    '''
    def __init__(self,
                 natoms,
                 minimiser,
                 composition="default",
                 labels=("X", ),
                 pop_size=10,
                 max_generation=10,
                 selector=TournamentSelector(3),
                 offspring=8,
                 mutant_rate=0.1,
                 remove_duplicates=False,
                 mutator=MutateReplace(),
                 crossover=DeavenHo()):
        #Parameters
        self.max_generation = max_generation
        self.mutant_rate = mutant_rate
        self.offspring = offspring
        self.pop_size = pop_size
        self.remove_duplicates = remove_duplicates
        self.selector = selector
        self.mutator = mutator
        self.crossover = crossover
        #Factory
        self.factory = ClusterFactory(natoms, minimiser, composition, labels)
        #PopulationList
        self.population = PopulationList(natoms, self.factory, pop_size)
        #Evolutionary progress
        self.mean_energy_series = []
        self.min_energy_series = []
        self.db = Database(db="mydatabase.sqlite")
        self.storage = self.db.minimum_adder()

    def write_xyz(self, file_name="cluster.xyz"):
        '''Open an xyz file and write the current population to it (non-blocking).'''
        try:
            with open(file_name, 'w') as xyz_file:
                self.population.write_xyz(xyz_file)
        except IOError as err:
            print("File error: " + str(err))

    def read_xyz(self, file_name="restart.xyz"):
        '''Read population from an xyz file (non-blocking for now).'''
        self.population.mass_extinction(0)
        try:
            with open(file_name) as xyz_file:
                self.population.read_xyz(xyz_file)
        except:
            print("No restart file available.")

    def run(self):
        '''Run the GA.'''
        for generation in range(1, self.max_generation + 1):
            print("Generation " + str(generation))
            if self.db.number_of_minima() < self.population.max_size:
                cluster = self.factory.get_random_cluster()
                print("Filling population with random structure.")
            else:
                self.population.read_db(self.db)
                if np.random < self.mutant_rate:
                    index = np.random.randint(0, len(self.population))
                    cluster = self.mutator.get_mutant(self.population[index])
                    print("Generating mutant of cluster " + str(index))
                else:
                    indices = self.selector.select(self.population)
                    cluster = self.crossover.get_offspring(
                        self.population[indices[0]],
                        self.population[indices[1]])
                    print("Generating offpsring of clusters " +
                          str(indices[0]) + " and " + str(indices[1]))
            cluster.minimise()
            #self.read_xyz("restart.xyz")
            #self.population.append(cluster)
            self.storage(cluster.energy, cluster._coords.flatten())
コード例 #19
0
class BatchGeneticAlgorithm(object):
    '''The Birmingham Cluster Genetic Algorithm.
    A new parallel version of the BCGA. The population is stored in a pele database and can be accessed by several processes simultaneously.
    Parameters:
    natoms- Number of atoms in cluster
    minimiser- See bcga.gpaw_interface
    Optional parameters:
    composition- A list containing the number of atoms of each type
    labels- A tuple orblist containing the names of each atom type (e.g. ["Au","Ag"]
    pop_size- Number of clusters in population
    max_generation- Number of generations to run GA
    selector- Selection method for choosing parents (see bcga.selector)
    offspring- Number of crossover operations in each generation
    mutant_rate- Probability of any cluster producing a mutant
    remove_duplicates- Remove identical clusters from population to prevent stagnation
    restart- Read population from restart.xyz and continue a search
    '''
    def __init__(self,natoms,minimiser,
                 composition="default",labels=("X",),
                 pop_size=10,max_generation=10,
                 selector=TournamentSelector(3),
                 offspring=8,mutant_rate=0.1,remove_duplicates=False,
                 mutator=MutateReplace(),
                 crossover=DeavenHo()):
        #Parameters
        self.max_generation = max_generation
        self.mutant_rate = mutant_rate
        self.offspring=offspring
        self.pop_size=pop_size
        self.remove_duplicates=remove_duplicates
        self.selector=selector
        self.mutator = mutator
        self.crossover = crossover
        #Factory
        self.factory=ClusterFactory(natoms,minimiser,composition,labels)
        #PopulationList
        self.population = PopulationList(natoms,self.factory,pop_size)
        #Evolutionary progress
        self.mean_energy_series=[]
        self.min_energy_series=[]
        self.db = Database(db="mydatabase.sqlite")
        self.storage = self.db.minimum_adder()

    def write_xyz(self,file_name="cluster.xyz"):
        '''Open an xyz file and write the current population to it (non-blocking).'''
        try:
            with open(file_name,'w') as xyz_file:
                self.population.write_xyz(xyz_file)
        except IOError as err:
            print("File error: "+str(err))
            
    def read_xyz(self,file_name="restart.xyz"):
        '''Read population from an xyz file (non-blocking for now).'''
        self.population.mass_extinction(0)
        try:
            with open(file_name) as xyz_file:
                self.population.read_xyz(xyz_file)
        except:
            print("No restart file available.")

    def run(self):
        '''Run the GA.'''
        for generation in range(1,self.max_generation+1):
            print ("Generation "+str(generation))
            if self.db.number_of_minima() < self.population.max_size:
                cluster=self.factory.get_random_cluster()
                print("Filling population with random structure.")
            else:
                self.population.read_db(self.db)
                if np.random < self.mutant_rate:
                    index=np.random.randint(0,len(self.population))
                    cluster=self.mutator.get_mutant(self.population[index])
                    print("Generating mutant of cluster "+str(index))
                else:
                    indices = self.selector.select(self.population)
                    cluster=self.crossover.get_offspring(self.population[indices[0]],
                                                       self.population[indices[1]])
                    print("Generating offpsring of clusters "+str(indices[0])+" and "+str(indices[1]))
            cluster.minimise()
            #self.read_xyz("restart.xyz")
            #self.population.append(cluster)
            self.storage(cluster.energy,cluster._coords.flatten())
コード例 #20
0
class GeneticAlgorithm(object):
    '''The Birmingham Cluster Genetic Algorithm.
    This is based on the original serial version of the BCGA.
    Parameters:
    natoms- Number of atoms in cluster
    minimiser- See bcga.gpaw_interface
    Optional parameters:
    composition- A tuple or list containing the number of atoms of each type (e.g. ["Au","Ag"])
    labels- A list containing the names of each atom type
    pop_size- Number of clusters in population
    max_generation- Number of generations to run GA
    selector- Selection method for choosing parents (see bcga.selector)
    offspring- Number of crossover operations in each generation
    mutant_rate- Probability of any cluster producing a mutant
    remove_duplicates- Remove identical clusters from population to prevent stagnation
    mass_extinction- Re-set population if population stagnates
    epoch_threshold- Mean population energy change that initiates mass extinction
    restart- Read population from restart.xyz and continue a search
    '''
    def __init__(self,natoms,minimiser,
                 composition="default",labels=("X",),
                 pop_size=10,max_generation=10,
                 selector=TournamentSelector(3),
                 offspring=8,mutant_rate=0.1,remove_duplicates=False,
                 mass_extinction=False,epoch_thresh=1.e-6,
                 restart=False,
                 mutator=MutateReplace(),
                 crossover=DeavenHo()):
        #Parameters
        self.max_generation = max_generation
        self.mutant_rate = mutant_rate
        self.offspring=offspring
        self.pop_size=pop_size
        self.remove_duplicates=remove_duplicates
        self.mass_extinction=mass_extinction
        self.epoch_thresh=epoch_thresh
        self.selector=selector
        self.mutator = mutator
        self.crossover = crossover
        #Factory
        self.factory=ClusterFactory(natoms,minimiser,composition,labels)
        #PopulationList
        self.population = PopulationList(natoms,self.factory,pop_size)
        if restart is False:
            while len(self.population) < self.population.max_size:
                self.population.append(self.factory.get_random_cluster())
            self.population.sort_energy()
        else:
            with open("restart.xyz",'r') as xyz_file:
                self.population.read_xyz(xyz_file)
        #Evolutionary progress
        self.mean_energy_series=[]
        self.mean_energy_series.append(self.population.get_mean_energy())
        self.min_energy_series=[]
        self.min_energy_series.append(self.population.get_lowest_energy())

    def make_offspring(self):
        '''Add offspring clusters to population'''
        for i in range(0, self.offspring):
            indices = self.selector.select(self.population)
            mycluster=self.crossover.get_offspring(self.population[indices[0]],
                                                 self.population[indices[1]])
            self.population.append(mycluster)

    def make_mutants(self):
        '''Add mutant clusters to population'''
        for mycluster in self.population:
            if np.random.uniform(0, 1) < self.mutant_rate:
                self.population.append(self.mutator.get_mutant(mycluster))
                
    def write_xyz(self,filename="cluster.xyz"):
        '''Open an xyz file and write the current population to it'''
        try:
            with open(filename,'w') as xyz_file:
                self.population.write_xyz(xyz_file)
        except IOError as err:
            print("File error: "+str(err))

    def run(self):
        '''Run the GA.'''
        for generation in range(1,self.max_generation+1):
            print ("Generation "+str(generation))
            self.make_offspring()
            self.make_mutants()
            if self.remove_duplicates:
                self.population.remove_duplicates()
            self.population.truncate()
            #Update time series
            self.mean_energy_series.append(self.population.get_mean_energy())
            self.min_energy_series.append(self.population.get_lowest_energy())
            print("Lowest energy: "+str(self.population.get_lowest_energy())+" Mean energy: "+str(self.population.get_mean_energy()))
            if self.mass_extinction:
                diff = self.mean_energy_series[-2]-self.mean_energy_series[-1]
                if 0 < diff < self.epoch_thresh:
                    print("New epoch. Energy change = "+str(diff))
                    self.population.mass_extinction()
                    while len(self.population) < self.population.max_size:
                        self.population.append(self.factory.get_random_cluster())
            self.population.sort_energy()
            self.write_xyz("restart.xyz")
コード例 #21
0
class GeneticAlgorithm(object):
    '''The Birmingham Cluster Genetic Algorithm.
    This is based on the original serial version of the BCGA.
    Parameters:
    natoms- Number of atoms in cluster
    minimiser- See bcga.gpaw_interface
    Optional parameters:
    composition- A tuple or list containing the number of atoms of each type (e.g. ["Au","Ag"])
    labels- A list containing the names of each atom type
    pop_size- Number of clusters in population
    max_generation- Number of generations to run GA
    selector- Selection method for choosing parents (see bcga.selector)
    offspring- Number of crossover operations in each generation
    mutant_rate- Probability of any cluster producing a mutant
    remove_duplicates- Remove identical clusters from population to prevent stagnation
    mass_extinction- Re-set population if population stagnates
    epoch_threshold- Mean population energy change that initiates mass extinction
    restart- Read population from restart.xyz and continue a search
    '''
    def __init__(self,
                 natoms,
                 minimiser,
                 composition="default",
                 labels=("X", ),
                 pop_size=10,
                 max_generation=10,
                 selector=TournamentSelector(3),
                 offspring=8,
                 mutant_rate=0.1,
                 remove_duplicates=False,
                 mass_extinction=False,
                 epoch_thresh=1.e-6,
                 restart=False,
                 mutator=MutateReplace(),
                 crossover=DeavenHo()):
        #Parameters
        self.max_generation = max_generation
        self.mutant_rate = mutant_rate
        self.offspring = offspring
        self.pop_size = pop_size
        self.remove_duplicates = remove_duplicates
        self.mass_extinction = mass_extinction
        self.epoch_thresh = epoch_thresh
        self.selector = selector
        self.mutator = mutator
        self.crossover = crossover
        #Factory
        self.factory = ClusterFactory(natoms, minimiser, composition, labels)
        #PopulationList
        self.population = PopulationList(natoms, self.factory, pop_size)
        if restart is False:
            while len(self.population) < self.population.max_size:
                self.population.append(self.factory.get_random_cluster())
            self.population.sort_energy()
        else:
            with open("restart.xyz", 'r') as xyz_file:
                self.population.read_xyz(xyz_file)
        #Evolutionary progress
        self.mean_energy_series = []
        self.mean_energy_series.append(self.population.get_mean_energy())
        self.min_energy_series = []
        self.min_energy_series.append(self.population.get_lowest_energy())

    def make_offspring(self):
        '''Add offspring clusters to population'''
        for i in range(0, self.offspring):
            indices = self.selector.select(self.population)
            mycluster = self.crossover.get_offspring(
                self.population[indices[0]], self.population[indices[1]])
            self.population.append(mycluster)

    def make_mutants(self):
        '''Add mutant clusters to population'''
        for mycluster in self.population:
            if np.random.uniform(0, 1) < self.mutant_rate:
                self.population.append(self.mutator.get_mutant(mycluster))

    def write_xyz(self, filename="cluster.xyz"):
        '''Open an xyz file and write the current population to it'''
        try:
            with open(filename, 'w') as xyz_file:
                self.population.write_xyz(xyz_file)
        except IOError as err:
            print("File error: " + str(err))

    def run(self):
        '''Run the GA.'''
        for generation in range(1, self.max_generation + 1):
            print("Generation " + str(generation))
            self.make_offspring()
            self.make_mutants()
            if self.remove_duplicates:
                self.population.remove_duplicates()
            self.population.truncate()
            #Update time series
            self.mean_energy_series.append(self.population.get_mean_energy())
            self.min_energy_series.append(self.population.get_lowest_energy())
            print("Lowest energy: " +
                  str(self.population.get_lowest_energy()) + " Mean energy: " +
                  str(self.population.get_mean_energy()))
            if self.mass_extinction:
                diff = self.mean_energy_series[-2] - self.mean_energy_series[-1]
                if 0 < diff < self.epoch_thresh:
                    print("New epoch. Energy change = " + str(diff))
                    self.population.mass_extinction()
                    while len(self.population) < self.population.max_size:
                        self.population.append(
                            self.factory.get_random_cluster())
            self.population.sort_energy()
            self.write_xyz("restart.xyz")
コード例 #22
0
 def setUp(self):
     natoms = 10
     minimiser = PeleMinimiser(lj.LJ())
     self.factory = ClusterFactory(natoms, minimiser)