Source code for stk.ea.crossover.crossers.compound.random

"""
Random Crosser
==============

"""


import numpy as np


[docs]class RandomCrosser: """ Use some other crosser at random. Examples -------- *Use One of Several Crossers at Random* .. testcode:: use-one-of-several-crossers-at-random import stk def get_functional_group_type(building_block): fg, = building_block.get_functional_groups(0) return type(fg) def get_num_functional_groups(building_block): return building_block.get_num_functional_groups() crosser = stk.RandomCrosser( crossers=( stk.GeneticRecombination(get_functional_group_type), stk.GeneticRecombination(get_num_functional_groups), ), random_seed=12, ) record1 = stk.MoleculeRecord( topology_graph=stk.cage.FourPlusSix( building_blocks=( stk.BuildingBlock( smiles='O=CC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ), stk.BuildingBlock( smiles='NCCN', functional_groups=[stk.PrimaryAminoFactory()], ), ), ), ) record2 = stk.MoleculeRecord( topology_graph=stk.cage.FourPlusSix( building_blocks=( stk.BuildingBlock( smiles='O=CNC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ), stk.BuildingBlock( smiles='NCNCN', functional_groups=[stk.PrimaryAminoFactory()], ), ), ), ) # Use one of the component crossers at random. crossover_records1 = tuple(crosser.cross((record1, record2))) # A different crosser may get selected at random the second, # third, etc, time. crossover_records2 = tuple(crosser.cross((record1, record2))) .. testcode:: use-one-of-several-crossers-at-random :hide: _expected_results = ( stk.ConstructedMolecule( topology_graph=stk.cage.FourPlusSix( building_blocks=( stk.BuildingBlock( smiles='O=CNC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ), stk.BuildingBlock( smiles='NCNCN', functional_groups=[ stk.PrimaryAminoFactory(), ], ), ), ), ), stk.ConstructedMolecule( topology_graph=stk.cage.FourPlusSix( building_blocks=( stk.BuildingBlock( smiles='O=CC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ), stk.BuildingBlock( smiles='NCCN', functional_groups=[ stk.PrimaryAminoFactory(), ], ), ), ), ), stk.ConstructedMolecule( topology_graph=stk.cage.FourPlusSix( building_blocks=( stk.BuildingBlock( smiles='O=CNC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ), stk.BuildingBlock( smiles='NCCN', functional_groups=[ stk.PrimaryAminoFactory(), ], ), ), ), ), stk.ConstructedMolecule( topology_graph=stk.cage.FourPlusSix( building_blocks=( stk.BuildingBlock( smiles='O=CC(C=O)CC=O', functional_groups=[stk.AldehydeFactory()], ), stk.BuildingBlock( smiles='NCNCN', functional_groups=[ stk.PrimaryAminoFactory(), ], ), ), ), ), ) def _get_smiles(item): if isinstance(item, stk.ConstructedMolecule): return stk.Smiles().get_key(item) return stk.Smiles().get_key( molecule=item.get_molecule_record().get_molecule(), ) _expected_smiles = set(map(_get_smiles, _expected_results)) _crossover_smiles1 = set(map(_get_smiles, crossover_records1)) _crossover_smiles2 = set(map(_get_smiles, crossover_records2)) assert _expected_smiles == _crossover_smiles1 assert _expected_smiles == _crossover_smiles2 """
[docs] def __init__(self, crossers, weights=None, random_seed=None): """ Initialize a :class:`.RandomCrosser` instance. Parameters ---------- crossers : :class:`tuple` Holds instances which have :meth:`.cross` method. The :meth:`.cross` method must return an instance of :class:`.CrossoverRecord`. weights : :class:`tuple` of :class:`float`, optional For each crosser, the probability that it will be chosen whenever :meth:`.cross` is called. If ``None`` all `crossers` will have equal chance of being selected. random_seed : :class:`int`, optional The random seed to use. """ self._crossers = crossers self._weights = weights self._generator = np.random.RandomState(random_seed)
[docs] def cross(self, records): """ Cross `records`. Parameters ---------- records : :class:`iterable` of :class:`.MoleculeRecord` The molecule records on which a crossover operation is performed. Yields ------ :class:`.CrossoverRecord` A record of a crossover operation. """ crosser = self._generator.choice( a=self._crossers, p=self._weights, ) return crosser.cross(records)