def _do(self, problem, pop, parents, **kwargs): # get the X of parents and count the matings X = pop.get("X")[parents.T] _, n_matings, n_var = X.shape # start point of crossover r = np.row_stack([random.perm(n_var-1) + 1 for _ in range(n_matings)])[:, :self.n_points] r.sort(axis=1) r = np.column_stack([r, np.full(n_matings, n_var)]) # the mask do to the crossover M = np.full((n_matings, n_var), False) # create for each individual the crossover range for i in range(n_matings): j = 0 while j < r.shape[1] - 1: a, b = r[i, j], r[i, j + 1] M[i, a:b] = True j += 2 _X = crossover_mask(X, M) return pop.new("X", _X)
def _do(self, problem, pop, parents, **kwargs): # get the X of parents and count the matings X = pop.get("X")[parents.T] _, n_matings, n_var = X.shape # the mask do to the crossover M = np.full((n_matings, n_var), False) # start point of crossover n = random.randint(0, n_var, size=len(pop)) # the probabilities are calculated beforehand r = random.random((n_matings, n_var)) < self.prob # create for each individual the crossover range for i in range(n_matings): # the actual index where we start start = n[i] for j in range(problem.n_var): # the current position where we are pointing to current = (start + j) % problem.n_var # replace only if random value keeps being smaller than CR if r[i, current]: M[i, current] = True else: break _X = crossover_mask(X, M) return pop.new("X", _X)
def _do(self, problem, X, **kwargs): _, n_matings, n_var = X.shape # random matrix to do the crossover M = np.random.random((n_matings, n_var)) < self.prob_uniform _X = crossover_mask(X, M) return _X
def _do(self, problem, xs, **kwargs): # Single-point crossover over all jobs. n_parents, n_matings, _ = xs.shape n_jobs = len(problem.jobs) points = np.random.randint(n_jobs, size=n_matings) mask = np.arange(n_jobs) < np.expand_dims(points, -1) ys = crossover_mask(xs.reshape(n_parents, n_matings, n_jobs, -1), mask) return ys.reshape(n_parents, n_matings, -1)
def _crossover(self, states, **kwargs): states = states.reshape(*states.shape[:2], *self._base_state.shape) n_parents, n_matings, n_jobs, n_nodes = states.shape # Single-point crossover over jobs for all parent states. points = np.random.randint(n_jobs, size=(n_matings, 1)) result = crossover_mask(states, np.arange(n_jobs) < points) # Set cluster sizes uniformly at random between each pair of parents. min_nodes, max_nodes = np.sort(self._get_cluster_sizes(states), axis=0) num_nodes = np.random.randint(np.iinfo(np.int16).max, size=(n_parents, n_matings)) num_nodes = min_nodes + num_nodes % (max_nodes - min_nodes + 1) mask = np.arange(n_nodes) >= np.expand_dims(num_nodes, (2, 3)) result[np.broadcast_to(mask, result.shape)] = 0 return result.reshape(n_parents, n_matings, -1)
def _do(self, _, X, **kwargs): _, n_matings, n_var = X.shape # the mask do to the crossover M = np.full((n_matings, n_var), False) not_equal = X[0] != X[1] # create for each individual the crossover range for i in range(n_matings): I = np.where(not_equal[i])[0] n = math.ceil(len(I) / 2) if n > 0: _I = I[np.random.permutation(len(I))[:n]] M[i, _I] = True _X = crossover_mask(X, M) return _X
def _do(self, problem, pop, parents, **kwargs): # get the X of parents and count the matings X = pop.get("X")[parents.T] _, n_matings, n_var = X.shape # start point of crossover r = np.row_stack([ random.perm(n_var - 1) + 1 for _ in range(n_matings) ])[:, :self.n_points] r.sort(axis=1) r = np.column_stack([r, np.full(n_matings, n_var)]) # genome defines a gene as (op, source), so we need to crossover on even values only # otherwise, we get op from 1 parent and source from the other r = r // 2 * 2 # the mask do to the crossover M = np.full((n_matings, n_var), False) # create for each individual the crossover range for i in range(n_matings): j = 0 while j < r.shape[1] - 1: a, b = r[i, j], r[i, j + 1] M[i, a:b] = True j += 2 _X = crossover_mask(X, M) new_pop = pop.new("X", _X) # print(new_pop) for i, ind in enumerate(new_pop): ind.parents = pop.get("id")[parents][i // 2] # for ind in new_pop: # print(ind.parents) return new_pop
def _do(self, problem, pop, parents, **kwargs): # get the X of parents and count the matings X = pop.get("X")[parents.T] _, n_matings, n_var = X.shape # the mask do to the crossover M = np.full((n_matings, n_var), False) not_equal = X[0] != X[1] # create for each individual the crossover range for i in range(n_matings): I = np.where(not_equal[i])[0] n = math.ceil(len(I) / 2) if n > 0: _I = I[random.perm(len(I))[:n]] M[i, _I] = True _X = crossover_mask(X, M) return pop.new("X", _X)
def _do(self, _, X, **kwargs): _, n_matings, n_var = X.shape M = mut_exp(n_matings, n_var, self.prob_exp, at_least_once=True) _X = crossover_mask(X, M) return _X
def _do(self, problem, X, **kwargs): _, n_matings, n_var = X.shape M = np.random.random((n_matings, n_var)) < 0.5 _X = crossover_mask(X, M) return _X