예제 #1
0
    def test_association(self):
        problem = C1DTLZ3(n_var=12, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        off_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'offspring.x'))
        off = Population.create(off_x)
        self.evaluator.eval(problem, off)

        true_assoc = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'feasible_rank0.txt'))
        true_niche = true_assoc[:, 1]
        true_id = true_assoc[:, 0]
        sorted_id = np.argsort(true_id)

        survival = CADASurvival(self.ref_dirs)
        mixed = CA.merge(off)
        survival.ideal_point = np.min(np.vstack((DA.get("F"), mixed.get("F"))), axis=0)

        fronts = NonDominatedSorting().do(mixed.get("F"), n_stop_if_ranked=len(self.ref_dirs))
        I = np.concatenate(fronts)
        niche, _ = survival._associate(mixed[I])
        sorted_I = np.argsort(I)

        assert (niche[sorted_I] == true_niche[sorted_id]).all()
예제 #2
0
    def _next(self):

        # all the elements in the interval
        a, left, right, b = self.pop

        # the golden ratio (precomputed constant)
        R = self.R

        # if the left solution is better than the right
        if left.F[0] < right.F[0]:

            # make the right to be the new right bound and the left becomes the right
            a, b = a, right
            right = left

            # create a new left individual and evaluate
            left = Individual(X=b.X - R * (b.X - a.X))
            self.evaluator.eval(self.problem, Population.create(left), algorithm=self)

        # if the right solution is better than the left
        else:

            # make the left to be the new left bound and the right becomes the left
            a, b = left, b
            left = right

            # create a new right individual and evaluate
            right = Individual(X=a.X + R * (b.X - a.X))
            self.evaluator.eval(self.problem, Population.create(right), algorithm=self)

        # update the population with all the four individuals
        self.pop = Population.create(a, left, right, b)
예제 #3
0
파일: so_pso.py 프로젝트: abfarr/moo2020
    def _step(self):
        pop = self.pop
        X, F, V = pop.get("X", "F", "V")

        # get the personal best of each particle
        pbest = Population.create(*pop.get("pbest"))
        P_X, P_F = pbest.get("X", "F")

        # get the global best solution
        best = self.opt.repeat(len(pop))
        G_X = best.get("X")

        # perform the pso equation
        inerta = self.w * V

        # calculate random values for the updates
        r1 = np.random.random((len(pop), self.problem.n_var))
        r2 = np.random.random((len(pop), self.problem.n_var))

        cognitive = self.c1 * r1 * (P_X - X)
        social = self.c2 * r2 * (G_X - X)

        # calculate the velocity vector
        _V = inerta + cognitive + social
        _V = repair_out_of_bounds_manually(_V, -self.V_max, self.V_max)

        # update the values of each particle
        _X = X + _V
        _X = repair_out_of_bounds(self.problem, _X)

        # evaluate the offspring population
        off = Population(len(pop)).set("X", _X, "V", _V, "pbest", pbest)
        self.evaluator.eval(self.problem, off, algorithm=self)

        # check whether a solution has improved or not - also consider constraints here
        has_improved = ImprovementReplacement().do(self.problem,
                                                   pbest,
                                                   off,
                                                   return_indices=True)

        # replace the personal best of each particle if it has improved
        off[has_improved].set("pbest", off[has_improved])
        off.set("best", best)
        pop = off

        # try to improve the current best with a pertubation
        if self.pertube_best:
            opt = FitnessSurvival().do(self.problem,
                                       Population.create(*pop.get("pbest")), 1)
            eta = int(np.random.uniform(5, 30))
            mutant = PolynomialMutation(eta).do(self.problem, opt)
            self.evaluator.eval(self.problem, mutant, algorithm=self)
            if ImprovementReplacement().do(self.problem,
                                           opt,
                                           mutant,
                                           return_indices=True)[0]:
                k = [i for i, e in enumerate(pop.get("pbest")) if e == opt][0]
                pop[k].set("pbest", mutant)

        self.pop = pop
예제 #4
0
    def test_restricted_mating_selection(self):
        np.random.seed(200)
        selection = RestrictedMating(func_comp=comp_by_cv_dom_then_random)

        problem = C3DTLZ4(n_var=12, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        Hm = CA.merge(DA)
        n_pop = len(CA)

        _, rank = NonDominatedSorting().do(Hm.get('F'), return_rank=True)

        Pc = (rank[:n_pop] == 0).sum()/len(Hm)
        Pd = (rank[n_pop:] == 0).sum()/len(Hm)

        P = selection.do(Hm, len(CA))

        assert P.shape == (91, 2)
        if Pc > Pd:
            assert (P[:, 0] < n_pop).all()
        else:
            assert (P[:, 0] >= n_pop).all()
        assert (P[:, 1] >= n_pop).any()
        assert (P[:, 1] < n_pop).any()
예제 #5
0
    def test_update_da(self):
        problem = C1DTLZ3(n_var=12, n_obj=3)
        for i in range(2):
            ca_x = np.loadtxt(
                path_to_test_resources('ctaea', 'c1dtlz3', f'case{i+1}',
                                       'preCA.x'))
            CA = Population.create(ca_x)
            self.evaluator.eval(problem, CA)

            da_x = np.loadtxt(
                path_to_test_resources('ctaea', 'c1dtlz3', f'case{i+1}',
                                       'preDA.x'))
            DA = Population.create(da_x)
            self.evaluator.eval(problem, DA)

            off_x = np.loadtxt(
                path_to_test_resources('ctaea', 'c1dtlz3', f'case{i+1}',
                                       'offspring.x'))
            off = Population.create(off_x)
            self.evaluator.eval(problem, off)

            survival = CADASurvival(self.ref_dirs)
            mixed = Population.merge(CA, off)
            survival.ideal_point = np.min(np.vstack(
                (DA.get("F"), mixed.get("F"))),
                                          axis=0)

            post_ca_x = np.loadtxt(
                path_to_test_resources('ctaea', 'c1dtlz3', f'case{i+1}',
                                       'postCA.x'))
            CA = Population.create(post_ca_x)
            self.evaluator.eval(problem, CA)

            Hd = Population.merge(DA, off)
            pDA = survival._updateDA(CA, Hd, 91)

            true_S1 = [
                151, 35, 6, 63, 67, 24, 178, 106, 134, 172, 148, 159, 41, 173,
                145, 77, 62, 40, 127, 61, 130, 27, 171, 115, 52, 176, 22, 75,
                55, 87, 36, 149, 154, 47, 78, 170, 90, 15, 53, 175, 179, 165,
                56, 89, 132, 82, 141, 39, 32, 25, 131, 14, 72, 65, 177, 140,
                66, 143, 34, 81, 103, 99, 147, 168, 51, 26, 70, 94, 54, 97,
                158, 107, 29, 120, 50, 108, 157, 11, 85, 174, 80, 0, 95, 13,
                142, 101, 156, 19, 8, 98, 20
            ]

            true_S2 = [
                78, 173, 59, 21, 101, 52, 36, 94, 17, 20, 37, 96, 90, 129, 150,
                136, 162, 70, 146, 75, 138, 154, 65, 179, 98, 32, 97, 11, 26,
                107, 12, 128, 95, 170, 24, 171, 40, 180, 14, 44, 49, 43, 130,
                23, 60, 79, 148, 62, 87, 56, 157, 73, 104, 45, 177, 74, 15,
                152, 164, 28, 80, 113, 41, 33, 158, 57, 77, 34, 114, 118, 18,
                54, 53, 145, 93, 115, 121, 174, 142, 39, 13, 105, 10, 69, 120,
                55, 6, 153, 91, 137, 46
            ]
            if i == 0:
                assert np.all(pDA == Hd[true_S1])
            else:
                assert np.all(pDA == Hd[true_S2])
예제 #6
0
    def _step(self):
        pop = self.pop
        X, F, V = pop.get("X", "F", "V")

        # get the personal best of each particle
        pbest = Population.create(*pop.get("pbest"))
        P_X, P_F = pbest.get("X", "F")

        # get the GLOBAL best solution - other variants such as local best can be implemented here too
        best = self.opt.repeat(len(pop))
        G_X = best.get("X")

        # get the inertia weight of the individual
        inerta = self.w * V

        # calculate random values for the updates
        r1 = np.random.random((len(pop), self.problem.n_var))
        r2 = np.random.random((len(pop), self.problem.n_var))

        cognitive = self.c1 * r1 * (P_X - X)
        social = self.c2 * r2 * (G_X - X)

        # calculate the velocity vector
        _V = inerta + cognitive + social
        _V = set_to_bounds_if_outside(_V, - self.V_max, self.V_max)

        # update the values of each particle
        _X = X + _V
        _X = InversePenaltyOutOfBoundsRepair().do(self.problem, _X, P=X)

        # evaluate the offspring population
        off = Population(len(pop)).set("X", _X, "V", _V, "pbest", pbest)
        self.evaluator.eval(self.problem, off, algorithm=self)

        # check whether a solution has improved or not - also consider constraints here
        has_improved = ImprovementReplacement().do(self.problem, pbest, off, return_indices=True)

        # replace the personal best of each particle if it has improved
        off[has_improved].set("pbest", off[has_improved])
        off.set("best", best)
        pop = off

        # try to improve the current best with a pertubation
        if self.pertube_best:
            pbest = Population.create(*pop.get("pbest"))
            k = FitnessSurvival().do(self.problem, pbest, 1, return_indices=True)[0]
            eta = int(np.random.uniform(5, 30))
            mutant = PolynomialMutation(eta).do(self.problem, pbest[[k]])[0]
            self.evaluator.eval(self.problem, mutant, algorithm=self)

            # if the mutant is in fact better - replace the personal best
            if is_better(mutant, pop[k]):
                pop[k].set("pbest", mutant)

        self.pop = pop
예제 #7
0
    def do(self, problem, *args, **kwargs):
        if type(args[0]) is Population:
            pop, parents = args
        else:
            pop = Population.create(*args)
            parents = np.array([np.arange(len(args))])

        if self.n_parents != parents.shape[1]:
            raise ValueError(
                'Exception during crossover: Number of parents differs from defined at crossover.'
            )

        # get the design space matrix form the population and parents
        X = pop.get("X")[parents.T].copy()

        # now apply the crossover probability
        do_crossover = np.random.random(len(parents)) < self.prob

        # execute the crossover
        _X = self._do(problem, X, **kwargs)

        X[:, do_crossover, :] = _X[:, do_crossover, :]

        # flatten the array to become a 2d-array
        X = X.reshape(-1, X.shape[-1])

        # create a population object
        off = pop.new("X", X)

        return off
예제 #8
0
    def _do(self, problem, pop, n_offsprings, parents=None, **kwargs):
        rnd = np.random.random(n_offsprings)
        n_neighbors = (rnd <= self.bias).sum()

        other = super()._do(problem, pop, n_offsprings - n_neighbors, parents,
                            **kwargs)

        N = []

        cand = TournamentSelection(comp_by_rank).do(pop,
                                                    n_neighbors,
                                                    n_parents=1)[:, 0]
        for k in cand:
            N.append(pop[k])

            n_cand_neighbors = pop[k].get("neighbors")
            rnd = np.random.permutation(
                len(n_cand_neighbors))[:self.crossover.n_parents - 1]
            [N.append(e) for e in n_cand_neighbors[rnd]]

        parents = np.reshape(np.arange(len(N)), (-1, self.crossover.n_parents))
        N = Population.create(*N)

        bias = super()._do(problem, N, n_neighbors, parents, **kwargs)

        return Population.merge(bias, other)
예제 #9
0
    def _next(self):

        # make a step and create the offsprings
        self.off = self._step()

        # evaluate the offsprings
        self.evaluator.eval(self.problem, self.off, algorithm=self)

        survivors = []

        for k in range(self.pop_size):
            parent, off = self.pop[k], self.off[k]

            rel = get_relation(parent, off)

            if rel == 0:
                survivors.extend([parent, off])
            elif rel == -1:
                survivors.append(off)
            else:
                survivors.append(parent)

        survivors = Population.create(*survivors)

        if len(survivors) > self.pop_size:
            survivors = RankAndCrowdingSurvival().do(self.problem, survivors,
                                                     self.pop_size)

        self.pop = survivors
예제 #10
0
 def _update(self):
     D = self.D
     ind = Individual(X=np.copy(D["X"]),
                      F=np.copy(D["F"]),
                      G=np.copy(-D["G"]))
     pop = Population.merge(self.pop, Population.create(ind))
     set_cv(pop)
     self.pop = pop
예제 #11
0
    def _step(self):
        pop = self.pop
        X, F, V = pop.get("X", "F", "V")

        # get the personal best of each particle
        pbest = Population.create(*pop.get("pbest"))
        P_X, P_F = pbest.get("X", "F")

        # get the best for each solution - could be global or local or something else - (here: Global)
        best = self._social_best()
        G_X = best.get("X")

        # get the inertia weight of the individual
        inerta = self.w * V

        # calculate random values for the updates
        r1 = np.random.random((len(pop), self.problem.n_var))
        r2 = np.random.random((len(pop), self.problem.n_var))

        cognitive = self.c1 * r1 * (P_X - X)
        social = self.c2 * r2 * (G_X - X)

        # calculate the velocity vector
        _V = inerta + cognitive + social
        _V = set_to_bounds_if_outside(_V, -self.V_max, self.V_max)

        # update the values of each particle
        _X = X + _V
        _X = InversePenaltyOutOfBoundsRepair().do(self.problem, _X, P=X)

        # evaluate the offspring population
        off = Population(len(pop)).set("X", _X, "V", _V, "pbest", pbest,
                                       "best", best)

        # try to improve the current best with a pertubation
        if self.pertube_best:
            pbest = Population.create(*pop.get("pbest"))
            k = FitnessSurvival().do(self.problem,
                                     pbest,
                                     1,
                                     return_indices=True)[0]
            eta = int(np.random.uniform(20, 30))
            mutant = PolynomialMutation(eta).do(self.problem, pbest[[k]])[0]
            off[k].set("X", mutant.X)

        return off
예제 #12
0
    def do(self,
           problem,
           pop,
           off,
           return_indices=False,
           inplace=False,
           **kwargs):
        pop = Population.create(pop) if isinstance(pop, Individual) else pop
        off = Population.create(off) if isinstance(off, Individual) else off

        I = self._do(problem, pop, off, **kwargs)

        if return_indices:
            return I
        else:
            if not inplace:
                pop = pop.copy()
            pop[I] = off[I]
            return pop
예제 #13
0
    def test_update(self):
        problem = C3DTLZ4(n_var=12, n_obj=3)
        ca_x = np.loadtxt(
            path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(
            path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        off_x = np.loadtxt(
            path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'offspring.x'))
        off = Population.create(off_x)
        self.evaluator.eval(problem, off)

        post_ca_x = np.loadtxt(
            path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'postCA.x'))
        true_pCA = Population.create(post_ca_x)
        self.evaluator.eval(problem, true_pCA)

        post_da_x = np.loadtxt(
            path_to_test_resources('ctaea', 'c3dtlz4', 'case2', 'postDA.x'))
        true_pDA = Population.create(post_da_x)
        self.evaluator.eval(problem, true_pDA)

        survival = CADASurvival(self.ref_dirs)
        mixed = Population.merge(CA, off)
        survival.ideal_point = np.array([0., 0., 0.])

        pCA, pDA = survival.do(problem, mixed, DA, len(self.ref_dirs))

        pCA_X = set([tuple(x) for x in pCA.get("X")])
        tpCA_X = set([tuple(x) for x in true_pCA.get("X")])

        pDA_X = set([tuple(x) for x in pDA.get("X")])
        tpDA_X = set([tuple(x) for x in true_pDA.get("X")])

        assert pCA_X == tpCA_X
        assert pDA_X == tpDA_X
예제 #14
0
    def _do(self, problem, evaluator, algorithm):
        pop = algorithm.pop
        algorithm.pop = Population.create(*algorithm.pop.get("pbest"))
        super()._do(problem, evaluator, algorithm)
        algorithm.pop = pop

        if algorithm.adaptive:
            self.output.append("f", algorithm.f if algorithm.f is not None else "-", width=8)
            self.output.append("S", algorithm.strategy if algorithm.strategy is not None else "-", width=6)
            self.output.append("w", algorithm.w, width=6)
            self.output.append("c1", algorithm.c1, width=8)
            self.output.append("c2", algorithm.c2, width=8)
예제 #15
0
    def _adapt(self):
        pop = self.pop

        X, F, best = pop.get("X", "F", "best")
        best = Population.create(*best)
        w, c1, c2, = self.w, self.c1, self.c2

        # get the average distance from one to another for normalization
        D = norm_eucl_dist(self.problem, X, X)
        mD = D.sum(axis=1) / (len(pop) - 1)
        _min, _max = mD.min(), mD.max()

        # get the average distance to the global best
        g_D = norm_euclidean_distance(self.problem)(best.get("X"), X).mean()
        f = (g_D - _min) / (_max - _min + 1e-32)

        S = np.array([
            S1_exploration(f),
            S2_exploitation(f),
            S3_convergence(f),
            S4_jumping_out(f)
        ])
        strategy = S.argmax() + 1

        delta = 0.05 + (np.random.random() * 0.05)

        if strategy == 1:
            c1 += delta
            c2 -= delta
        elif strategy == 2:
            c1 += 0.5 * delta
            c2 -= 0.5 * delta
        elif strategy == 3:
            c1 += 0.5 * delta
            c2 += 0.5 * delta
        elif strategy == 4:
            c1 -= delta
            c2 += delta

        c1 = max(1.5, min(2.5, c1))
        c2 = max(1.5, min(2.5, c2))

        if c1 + c2 > 4.0:
            c1 = 4.0 * (c1 / (c1 + c2))
            c2 = 4.0 * (c2 / (c1 + c2))

        w = 1 / (1 + 1.5 * np.exp(-2.6 * f))

        self.f = f
        self.strategy = strategy
        self.c1 = c1
        self.c2 = c2
        self.w = w
예제 #16
0
    def _next(self):
        a, left, right, b = self.pop
        R = self.R

        if left.F[0] < right.F[0]:

            a, b = a, right
            right = left

            left = Individual(X=b.X - R * (b.X - a.X))
            self.evaluator.eval(self.problem, Population.create(left), algorithm=self)

        else:

            a, b = left, b
            left = right

            right = Individual(X=a.X + R * (b.X - a.X))
            self.evaluator.eval(self.problem, Population.create(right), algorithm=self)

        self.pop = Population.create(a, left, right, b)
예제 #17
0
    def _initialize(self):
        xl, xu = self.problem.bounds()
        R = self.R
        d = R * (xu - xl)

        a = Individual(X=xl)
        b = Individual(X=xu)

        left = Individual(X=xu - d)
        right = Individual(X=xl + d)

        pop = Population.create(a, left, right, b)

        self.evaluator.eval(self.problem, pop, algorithm=self)
        self.pop = pop
예제 #18
0
파일: so_direct.py 프로젝트: abfarr/moo2020
    def _next(self):
        # the offspring population to finally evaluate and attach to the population
        off = Population()

        # find the potential optimal solution in the current population
        potential_optimal = self._potential_optimal()

        # for each of those solutions execute the division move
        for current in potential_optimal:

            # find the largest dimension the solution has not been evaluated yet
            nxl, nxu = norm_bounds(current, problem)
            k = np.argmax(nxu - nxl)

            # the delta value to be used to get left and right - this is one sixth of the range
            xl, xu = current.get("xl"), current.get("xu")

            delta = (xu[k] - xl[k]) / 6

            # print(current.X, delta, k, xl, xu)

            # create the left individual
            left_x = np.copy(current.X)
            left_x[k] = xl[k] + delta
            left = Individual(X=left_x)

            # create the right individual
            right_x = np.copy(current.X)
            right_x[k] = xu[k] - delta
            right = Individual(X=right_x)

            # update the boundaries for all the points accordingly
            for ind in [current, left, right]:
                update_bounds(ind, xl, xu, k, delta)

            # create the offspring population, evaluate and attach to current population
            _off = Population.create(left, right)
            _off.set("depth", current.get("depth") + 1)

            off = Population.merge(off, _off)

        # evaluate the offsprings
        self.evaluator.eval(self.problem, off, algorithm=self)

        # print(off.get("X"))

        # add the offsprings to the population
        self.pop = Population.merge(self.pop, off)
예제 #19
0
    def do(self, problem, algorithm):
        import matplotlib.pyplot as plt

        if problem.n_var != 2 or problem.n_obj != 1:
            raise Exception(
                "This visualization can only be used for problems with two variables and one objective!")

        # draw the problem surface
        FitnessLandscape(problem,
                         _type="contour",
                         kwargs_contour=dict(alpha=0.3),
                         n_samples=self.n_samples_for_surface,
                         close_on_destroy=False).do()

        # get the population
        off = algorithm.pop
        pop = algorithm.pop if self.last_pop is None else self.last_pop
        pbest = Population.create(*off.get("pbest"))

        for i in range(len(pop)):
            plt.plot([off[i].X[0], pop[i].X[0]], [off[i].X[1], pop[i].X[1]], color="blue", alpha=0.5)
            plt.plot([pbest[i].X[0], pop[i].X[0]], [pbest[i].X[1], pop[i].X[1]], color="red", alpha=0.5)
            plt.plot([pbest[i].X[0], off[i].X[0]], [pbest[i].X[1], off[i].X[1]], color="red", alpha=0.5)

        X, F, CV = pbest.get("X", "F", "CV")
        plt.scatter(X[:, 0], X[:, 1], edgecolors="red", marker="*", s=70, facecolors='none', label="pbest")

        X, F, CV = off.get("X", "F", "CV")
        plt.scatter(X[:, 0], X[:, 1], color="blue", marker="o", s=30, label="particle")

        X, F, CV = pop.get("X", "F", "CV")
        plt.scatter(X[:, 0], X[:, 1], color="blue", marker="o", s=30, alpha=0.5)

        opt = algorithm.opt
        X, F, CV = opt.get("X", "F", "CV")
        plt.scatter(X[:, 0], X[:, 1], color="black", marker="x", s=100, label="gbest")

        xl, xu = problem.bounds()
        plt.xlim(xl[0], xu[0])
        plt.ylim(xl[1], xu[1])

        plt.title(f"Generation: %s \nf: %.5E" % (algorithm.n_gen, opt[0].F[0]))
        plt.legend()

        self.last_pop = off.copy(deep=True)
예제 #20
0
    def result(self, only_optimum=True, return_values_of="auto"):

        if return_values_of == "auto":
            return_values_of = ["X", "F"]
            if self.problem.n_constr > 0:
                return_values_of.append("CV")

        if only_optimum:
            self.algorithm.finalize()
            pop, opt = self.algorithm.pop, self.algorithm.opt
            res = filter_optimum(pop.copy()) if opt is None else opt.copy()

            if isinstance(res, Individual):
                res = Population.create(res)

        else:
            res = self.algorithm.pop

        return res.get(*return_values_of)
예제 #21
0
    def _initialize(self):

        # the boundaries of the problem for initialization
        xl, xu = self.problem.bounds()

        # the golden ratio (precomputed constant)
        R = self.R

        # a and b always represents the boundaries
        a, b = Individual(X=xl), Individual(X=xu)

        # create the left and right in the interval itself
        left, right = Individual(X=xu - R * (xu - xl)), Individual(X=xl + R * (xu - xl))

        # create a population with all four individuals
        pop = Population.create(a, left, right, b)

        # evaluate all the points
        self.evaluator.eval(self.problem, pop, algorithm=self)
        self.pop = pop
예제 #22
0
    def do(self, individual, **kwargs):
        prob = self.problem
        n_var, n_obj, n_constr = prob.n_var, prob.n_obj, prob.n_constr
        individual = Individual(X=individual.X)
        self.evaluator.eval(self.problem, Population.create(individual))

        dF = np.zeros((n_obj, n_var))
        dG = np.zeros((n_constr, n_var))

        for i in range(n_var):
            x = np.copy(individual.X)
            x[i] += self.epsilon

            eps_F, _, eps_G = self.evaluator.eval(prob, x)
            dF[:, i] = (eps_F - individual.F) / self.epsilon

            if n_constr > 0 and eps_G is not None:
                dG[:, i] = (eps_G - individual.G) / self.epsilon

        return dF, dG
예제 #23
0
    def _next(self):

        # get the offspring solutions and evaluate them
        off = self._step()
        self.evaluator.eval(self.problem, off, algorithm=self)

        # the the personal bests of the current population
        pbest = Population.create(*self.pop.get("pbest"))

        # if an offspring has improved the personal store that index
        has_improved = ImprovementReplacement().do(self.problem,
                                                   pbest,
                                                   off,
                                                   return_indices=True)

        # replace the personal best of each particle if it has improved
        off[has_improved].set("pbest", off[has_improved])
        pop = off

        self.off = off
        self.pop = pop

        if self.adaptive:
            self._adapt()
예제 #24
0
    def eval(self, problem, X, algorithm=None, **kwargs):

        pop = pop_from_array_or_individual(X)
        pop.set("algorithm", [algorithm] * len(pop))

        if self.history is None:
            self.history = pop
        else:
            self.history = Population.create(self.history, pop)

        before = self.n_eval
        ret = super().eval(problem, X, **kwargs)
        after = self.n_eval

        if algorithm is not None:
            if algorithm not in self.algorithms:
                self.algorithms[algorithm] = 0

            self.algorithms[algorithm] += after - before

        if self.opt is None or pop.get("F").min() < self.opt[0].F.min():
            self.opt = pop[[pop.get("F").argmin()]]

        return ret
예제 #25
0
    def _next(self):
        problem, evaluator = self.problem, self.evaluator

        # add the box constraints defined in the problem
        bounds = None
        if self.use_bounds:

            xl, xu = self.problem.bounds()
            if self.with_bounds:
                bounds = np.column_stack([xl, xu])
            else:
                if xl is not None or xu is not None:
                    raise Exception(f"Error: Boundary constraints can not be handled by {self.method}")

        # define the actual constraints if supported by the algorithm
        constr = []
        if self.use_constr:

            constr = [LinearConstraint(np.eye(self.problem.n_var), xl, xu)]

            if problem.has_constraints():

                if self.with_constr:
                    def fun_constr(x):
                        g, cv = problem.evaluate(x, return_values_of=["G", "CV"])
                        return cv[0]

                    non_lin_constr = NonlinearConstraint(fun_constr, -float("inf"), 0)

                    constr.append(non_lin_constr)

                else:
                    raise Exception(f"Error: Constraint handling is not supported by {self.method}")

        # the objective function to be optimized and add gradients if available
        if self.estm_gradients:
            jac = None

            def fun_obj(x):
                f = problem.evaluate(x, return_values_of=["F"])[0]
                evaluator.n_eval += 1
                return f

        else:
            jac = True

            def fun_obj(x):
                f, df = problem.evaluate(x, return_values_of=["F", "dF"])

                if df is None:
                    raise Exception("If the gradient shall not be estimate, please set out['dF'] in _evaluate. ")

                evaluator.n_eval += 1
                return f[0], df[0]

        # the arguments to be used
        kwargs = dict(args=(), method=self.method, bounds=bounds, constraints=constr, jac=jac, options=self.options)

        # the starting solution found by sampling beforehand
        x0 = self.opt[0].X

        # actually run the optimization
        if not self.show_warnings:
            warnings.simplefilter("ignore")
        res = scipy_minimize(fun_obj, x0, **kwargs)

        opt = Population.create(Individual(X=res.x))
        self.evaluator.eval(self.problem, opt, algorithm=self)

        self.pop = opt

        self.termination.force_termination = True

        if hasattr("res", "nit"):
            self.n_gen = res.nit + 1
예제 #26
0
    def test_update_ca(self):
        problem = C1DTLZ3(n_var=12, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        off_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'offspring.x'))
        off = Population.create(off_x)
        self.evaluator.eval(problem, off)

        post_ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz3', 'case3', 'postCA.x'))
        true_pCA = Population.create(post_ca_x)
        self.evaluator.eval(problem, true_pCA)

        survival = CADASurvival(self.ref_dirs)
        mixed = CA.merge(off)
        survival.ideal_point = np.min(np.vstack((DA.get("F"), mixed.get("F"))), axis=0)

        pCA = survival._updateCA(mixed, len(self.ref_dirs))

        pX = set([tuple(x) for x in pCA.get("X")])
        tpX = set([tuple(x) for x in true_pCA.get("X")])
        assert pX == tpX

        problem = C1DTLZ1(n_var=9, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz1', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz1', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        off_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz1', 'offspring.x'))
        off = Population.create(off_x)
        self.evaluator.eval(problem, off)

        post_ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c1dtlz1', 'postCA.x'))
        true_pCA = Population.create(post_ca_x)
        self.evaluator.eval(problem, true_pCA)

        survival = CADASurvival(self.ref_dirs)
        mixed = CA.merge(off)
        survival.ideal_point = np.min(np.vstack((DA.get("F"), mixed.get("F"))), axis=0)

        pCA = survival._updateCA(mixed, len(self.ref_dirs))

        pX = set([tuple(x) for x in pCA.get("X")])
        tpX = set([tuple(x) for x in true_pCA.get("X")])
        assert pX == tpX

        problem = C3DTLZ4(n_var=12, n_obj=3)
        ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case1', 'preCA.x'))
        CA = Population.create(ca_x)
        self.evaluator.eval(problem, CA)

        da_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case1', 'preDA.x'))
        DA = Population.create(da_x)
        self.evaluator.eval(problem, DA)

        off_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case1', 'offspring.x'))
        off = Population.create(off_x)
        self.evaluator.eval(problem, off)

        post_ca_x = np.loadtxt(path_to_test_resources('ctaea', 'c3dtlz4', 'case1', 'postCA.x'))
        true_pCA = Population.create(post_ca_x)
        self.evaluator.eval(problem, true_pCA)

        survival = CADASurvival(self.ref_dirs)
        mixed = CA.merge(off)
        survival.ideal_point = np.min(np.vstack((DA.get("F"), mixed.get("F"))), axis=0)

        pCA = survival._updateCA(mixed, len(self.ref_dirs))

        pX = set([tuple(x) for x in pCA.get("X")])
        tpX = set([tuple(x) for x in true_pCA.get("X")])
        assert pX == tpX
예제 #27
0
    def _next(self):

        # initialize all ants to be used in this iteration
        ants = []
        for k in range(self.n_ants):
            ant = self.ant()
            ant.initialize(self.problem, self.pheromones)
            ants.append(ant)

        active = list(range(self.n_ants))

        while len(active) > 0:

            for k in active:
                ant = ants[k]

                if ant.has_next():
                    ant.next()

                    if self.local_update:
                        e = ant.last()
                        if e is None or e.pheromone is None:
                            raise Exception(
                                "For a local update the ant has to set the pheromones when notified."
                            )
                        else:
                            self.pheromones.set(
                                e.key,
                                self.pheromones.get(e.key) * ant.alpha +
                                e.pheromone * ant.alpha)
                            # self.pheromones.update(e.key, e.pheromone * ant.alpha)

                else:
                    ant.finalize()
                    active = [i for i in active if i != k]

        colony = Population.create(*ants)

        # this evaluation can be disabled or faked if evaluate_each_ant is false - then the finalize method of the
        # ant has to set the objective and/or constraint values accordingly
        self.evaluator.eval(self.problem, colony)
        set_cv(colony)
        set_feasibility(colony)

        # set the current best including the new colony
        opt = FitnessSurvival().do(problem, Population.merge(colony, self.opt),
                                   1)

        # do the evaporation after this iteration
        self.pheromones.evaporate()

        # select the ants to be used for the global pheromone update
        if self.global_update == "all":
            ants_to_update = colony
        elif self.global_update == "it-best":
            ants_to_update = FitnessSurvival().do(problem, colony, 1)
        elif self.global_update == "best":
            ants_to_update = self.opt
        else:
            raise Exception(
                "Unknown value for global updating the pheromones!")

        # now spread the pheromones for each ant depending on performance
        for ant in ants_to_update:
            for e in ant.path:
                if e.pheromone is None:
                    raise Exception(
                        "The ant has to set the pheromone of each entry in the path."
                    )
                else:
                    self.pheromones.update(e.key, e.pheromone * pheromones.rho)

        self.pop, self.off = colony, colony
        self.opt = opt
예제 #28
0
    def _next(self):

        # all place visited so far
        _X, _F, _evaluated_by_algorithm = self.evaluator.history.get("X", "F", "algorithm")

        # collect attributes from each algorithm and determine whether it has to be replaced or not
        pop, F, n_evals = [], [], []
        for k, algorithm in enumerate(self.algorithms):

            # collect some data from the current algorithms
            _pop = algorithm.pop

            # if the algorithm has terminated or not
            has_finished = algorithm.termination.has_terminated(algorithm)

            # if the area was already explored before
            closest_dist_to_others = vectorized_cdist(_pop.get("X"), _X[_evaluated_by_algorithm != algorithm],
                                                      func_dist=norm_euclidean_distance(self.problem))
            too_close_to_others = (closest_dist_to_others.min(axis=1) < 1e-3).all()

            # whether the algorithm is the current best - if yes it will not be replaced
            current_best = self.evaluator.opt.get("F") == _pop.get("F").min()

            # algorithm not really useful anymore
            if not current_best and (has_finished or too_close_to_others):
                # find a suitable x0 which is far from other or has good expectations
                self.sampling.criterion = lambda X: vectorized_cdist(X, _X).min()
                X = self.sampling.do(self.problem, self.n_initial_samples).get("X")

                # distance in x space to other existing points
                x_dist = vectorized_cdist(X, _X, func_dist=norm_euclidean_distance(self.problem)).min(axis=1)
                f_pred, f_uncert = predict_by_nearest_neighbors(_X, _F, X, 5, self.problem)
                fronts = NonDominatedSorting().do(np.column_stack([- x_dist, f_pred, f_uncert]))
                I = np.random.choice(fronts[0])

                # I = vectorized_cdist(X, _X, func_dist=norm_euclidean_distance(self.problem)).min(axis=1).argmax()

                # choose the one with the largest distance to current solutions
                x0 = X[[I]]

                # replace the current algorithm
                algorithm = get_algorithm("nelder-mead",
                                          problem=self.problem,
                                          x0=x0,
                                          termination=NelderAndMeadTermination(x_tol=1e-3, f_tol=1e-3),
                                          evaluator=self.evaluator,
                                          )
                algorithm.initialize()
                self.algorithms[k] = algorithm

            pop.append(algorithm.pop)
            F.append(algorithm.pop.get("F"))
            n_evals.append(self.evaluator.algorithms[algorithm])

        # get the values of all algorithms as arrays
        F, n_evals = np.array(F), np.array(n_evals)
        rewards = 1 - normalize(F.min(axis=1))[:, 0]
        n_evals_total = self.evaluator.n_eval - self.evaluator.algorithms[self]

        # calculate the upper confidence bound
        ucb = rewards + 0.95 * np.sqrt(np.log(n_evals_total) / n_evals)

        I = ucb.argmax()
        self.algorithms[I].next()

        # create the population object with all algorithms
        self.pop = Population.create(*pop)

        # update the current optimum
        self.opt = self.evaluator.opt
예제 #29
0
 def _set_optimum(self, force=False):
     pbest = Population.create(*self.pop.get("pbest"))
     self.opt = filter_optimum(pbest, least_infeasible=True)
예제 #30
0
파일: so_sqlp.py 프로젝트: abfarr/moo2020
 def _update(self):
     D = self.D
     ind = Individual(X=np.copy(D["X"]), F=np.copy(D["F"]), G=np.copy(-D["G"]))
     ind.CV = Problem.calc_constraint_violation(ind.G[None, :])[0]
     ind.feasible = (ind.CV <= 0)
     self.pop = Population.merge(self.pop, Population.create(ind))