def crossover(self, mother, father): """ Do crossover onece. """ child1 = REntity(self.mutation_rate, self.mutation_parameter, self.settings, self.employees, self.sdate, self.length, mother.gene) child2 = REntity(self.mutation_rate, self.mutation_parameter, self.settings, self.employees, self.sdate, self.length, father.gene) if not flip(self.crossover_rate): return () for i in range(self.length): if flip(self.crossover_parameter): mother, father = father, mother for (md, fd, c1d, c2d) in zip(mother.gene.works_at(i), father.gene.works_at(i), child1.gene.works_at(i), child2.gene.works_at(i)): c1d.work = md.work c1d.locked = md.locked c2d.work = fd.work c2d.locked = fd.locked return (child1, child2)
def mutation(self): """ 突然変異として、固定されていなシフトが二つ以上あった場合これを交換する """ if not flip(self.mutation_rate): return for works in self.gene.works_on_days: unlocked_positions = [i for i, d in enumerate(works) if not d.locked] if len(unlocked_positions) > 1 and flip(self.mutation_parameter): a = choice(unlocked_positions) b = self.assignable_index(works, a) if b == -1: continue works[a].work, works[b].work = works[b].work, works[a].work
def test_flip(self): res = [] for i in range(100): res.append(flip(0.1)) l = len([x for x in res if x]) self.assertTrue(l < 15) for i in range(100): self.assertTrue(5 <= rand(10, 5) < 10)