コード例 #1
0
def make_multiobjective_function(sources,
                                 bounds=None,
                                 function_type="worst_case",
                                 interpolation_method="nearest",
                                 bad_sources=None):
    """Make the multiobjective function"""

    if function_type == "multiobjective_counting":
        problem = make_multiobjective_function_counting(
            sources, bounds=bounds, interpolation_method=interpolation_method)
        algorithm = NSGAII(
            problem,
            variator=CompoundOperator(  # TODO look further into this
                SBX(), HUX(), PM(), BitFlip()))
    elif function_type == "multiobjective_competing":
        if bad_sources is None:
            raise ValueError(
                "specify bad_sources for multiobjective_competing")
        problem = make_multiobjective_function_competing(
            sources,
            bounds=bounds,
            bad_sources=bad_sources,
            interpolation_method=interpolation_method)  # TODO remove this
        algorithm = NSGAII(problem)
    else:
        raise ValueError("The type : {} was not valid".format(function_type))

    return algorithm
コード例 #2
0
    def __init__(self,
                 problem,
                 epsilons,
                 population_size=100,
                 generator=RandomGenerator(),
                 selector=TournamentSelector(2),
                 recency_list_size=50,
                 max_mutation_index=10,
                 **kwargs):
        super(BorgMOEA, self).__init__(
            EpsMOEA(problem, epsilons, population_size, generator, selector,
                    **kwargs))
        self.recency_list = deque()
        self.recency_list_size = recency_list_size
        self.restarted_last_check = False
        self.base_mutation_index = 0
        self.max_mutation_index = max_mutation_index

        # overload the variator and iterate method
        self.algorithm.variator = Multimethod(self, [
            GAOperator(SBX(), PM()),
            DifferentialEvolution(),
            UM(),
            PCX(),
            UNDX(),
            SPX()
        ])

        self.algorithm.iterate = self.iterate
コード例 #3
0
def calibrate(run_counts):
    """调用优化计算模型进行参数优选
    Parameters
    ----------
    run_counts: int   运行次数

    Returns
    ---------
    optimal_params: list
          非劣解集
    """
    algorithm = NSGAII(XajCalibrate(),
                       population_size=500,
                       variator=GAOperator(SBX(0.95, 20.0), PM(2, 25.0)))
    algorithm.run(run_counts)

    # We could also get only the non-dominated solutions,这里只展示非劣解集
    nondominated_solutions = nondominated(algorithm.result)

    # plot the results using matplotlib
    # 如果目标超过三个,可视化方面需要进行降维操作,这里先以两个目标为例进行分析
    plt.scatter([s.objectives[0] for s in nondominated_solutions],
                [s.objectives[1] for s in nondominated_solutions])
    plt.xlim([0, 1])
    plt.ylim([0, 1])
    plt.xlabel("$mare$")
    plt.ylabel("$nse$")
    plt.show()

    # 返回最优参数
    optimal_params = []
    for nondominated_solution in nondominated_solutions:
        optimal_params.append(nondominated_solution.variables)
    return optimal_params
コード例 #4
0
    def __init__(self,
                 problem,
                 epsilons,
                 population_size=100,
                 generator=RandomGenerator(),
                 selector=TournamentSelector(2),
                 variator=None,
                 **kwargs):
        self.problem = problem

        # Parameterization taken from
        # Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed
        variators = [
            GAOperator(
                SBX(probability=self.sbx_prop,
                    distribution_index=self.sbx_dist),
                PM(probability=self.pm_p, distribution_index=self.pm_dist)),
            GAOperator(
                PCX(nparents=self.pcx_nparents,
                    noffspring=self.pcx_noffspring,
                    eta=self.pcx_eta,
                    zeta=self.pcx_zeta),
                PM(probability=self.pm_p, distribution_index=self.pm_dist)),
            GAOperator(
                DifferentialEvolution(crossover_rate=self.de_rate,
                                      step_size=self.de_stepsize),
                PM(probability=self.pm_p, distribution_index=self.pm_dist)),
            GAOperator(
                UNDX(nparents=self.undx_nparents,
                     noffspring=self.undx_noffspring,
                     zeta=self.undx_zeta,
                     eta=self.undx_eta),
                PM(probability=self.pm_p, distribution_index=self.pm_dist)),
            GAOperator(
                SPX(nparents=self.spx_nparents,
                    noffspring=self.spx_noffspring,
                    expansion=self.spx_expansion),
                PM(probability=self.pm_p, distribution_index=self.pm_dist)),
            UM(probability=self.um_p)
        ]

        variator = Multimethod(self, variators)

        super(GenerationalBorg, self).__init__(
            NSGAII(problem, population_size, generator, selector, variator,
                   EpsilonBoxArchive(epsilons), **kwargs))
コード例 #5
0
    def fit(self, X, y):

        opt_start_time = time.time()
        kfold = None
        if isinstance(self.cv, int) and self.cv == 1:
            X_train, X_val, y_train, y_val = train_test_split(
                X, y, test_size=0.2, random_state=self.random_seed, stratify=y)
            logger.info("Not using Cross-Validation. "
                        "Performing single train/test split")
        else:
            is_clf = self.model.is_classifier()
            kfold = check_cv(self.cv, y=y, classifier=is_clf)
            # kfold = StratifiedKFold(
            #    n_splits=self.cv, random_state=self.random_seed, shuffle=True
            # )
            logger.info(f"Using Cross-Validation - {kfold}")

        self.ind = 0

        def train_test_model(parameter):
            # First check if we exceeded allocated time budget
            current_time = time.time()
            elapsed_time = current_time - opt_start_time
            if (self.max_opt_time
                    is not None) and (elapsed_time > self.max_opt_time):
                msg = (
                    f"Max optimization time exceeded. "
                    f"Max Opt time = {self.max_opt_time}, Elapsed Time = {elapsed_time}, "
                    f"NFE Completed - {self.ind}")
                raise MaxBudgetExceededException(msg)

            self.ind = self.ind + 1
            logger.info(f"Training population {self.ind}")

            parameter = self.param_to_dict(
                parameter,
                self.model_helper.param_choices,
                self.model_helper.param_categories,
                self.model_helper.param_type,
            )

            scorers = [get_scorer(scorer) for scorer in self.scoring]
            nscorers = len(scorers)

            try:
                if kfold is None:
                    clf = self.model_helper.create_instance(parameter)
                    clf_trained = clf.fit(X_train, y_train)

                    obj_val = [
                        scorer(clf_trained, X_val, y_val) for scorer in scorers
                    ]

                else:

                    obj_scores = [[] for _ in range(nscorers)]

                    # Perform k-fold cross-validation
                    for train_index, test_index in kfold.split(X, y):
                        if isinstance(X, pd.DataFrame):
                            X_train_split, X_val_split = (
                                X.iloc[train_index],
                                X.iloc[test_index],
                            )
                            y_train_split, y_val_split = (
                                y.iloc[train_index],
                                y.iloc[test_index],
                            )
                        else:
                            X_train_split, X_val_split = X[train_index], X[
                                test_index]
                            y_train_split, y_val_split = y[train_index], y[
                                test_index]

                        clf = self.model_helper.create_instance(parameter)
                        clf_trained = clf.fit(X_train_split, y_train_split)

                        obj_score = [
                            scorer(clf_trained, X_val_split, y_val_split)
                            for scorer in scorers
                        ]
                        for i in range(nscorers):
                            obj_scores[i].append(obj_score[i])

                    # Aggregate CV score
                    obj_val = [np.mean(obj_scores[i]) for i in range(nscorers)]
                    logger.debug(f"Obj k-fold scores - {obj_scores}")

                # By default we are solving a minimization MOO problem
                fitnessValue = [
                    self.best_score[i] - obj_val[i] for i in range(nscorers)
                ]
                logger.info(f"Train fitnessValue - {fitnessValue}")

            except jsonschema.ValidationError as e:
                logger.error(f"Caught JSON schema validation error.\n{e}")
                logger.error("Setting fitness (loss) values to infinity")
                fitnessValue = [np.inf for i in range(nscorers)]
                logger.info(f"Train fitnessValue - {fitnessValue}")

            return fitnessValue

        def time_check_callback(alg):
            current_time = time.time()
            elapsed_time = current_time - opt_start_time
            logger.info(
                f"NFE Complete - {alg.nfe}, Elapsed Time - {elapsed_time}")

        parameter_num = len(self.model_helper.param_choices)
        target_num = len(self.scoring)
        # Adjust max_evals if not a multiple of population size. This is
        # required as Platypus performs evaluations in multiples of
        # population_size.
        adjusted_max_evals = (self.max_evals //
                              self.population_size) * self.population_size
        if adjusted_max_evals != self.max_evals:
            logger.info(
                f"Adjusting max_evals to {adjusted_max_evals} from specified {self.max_evals}"
            )

        problem = Problem(parameter_num, target_num)
        problem.types[:] = self.model_helper.types
        problem.function = train_test_model

        # Set the variator based on types of decision variables
        varg = {}
        first_type = problem.types[0].__class__
        all_type_same = all([isinstance(t, first_type) for t in problem.types])
        # use compound operator for mixed types
        if not all_type_same:
            varg["variator"] = CompoundOperator(SBX(), HUX(), PM(), BitFlip())

        algorithm = NSGAII(
            problem,
            population_size=self.population_size,
            **varg,
        )

        try:
            algorithm.run(adjusted_max_evals, callback=time_check_callback)
        except MaxBudgetExceededException as e:
            logger.warning(
                f"Max optimization time budget exceeded. Optimization exited prematurely.\n{e}"
            )

        solutions = nondominated(algorithm.result)
        # solutions = [s for s in algorithm.result if s.feasible]`
        # solutions = algorithm.result

        moo_solutions = []
        for solution in solutions:
            vars = []
            for pnum in range(parameter_num):
                vars.append(problem.types[pnum].decode(
                    solution.variables[pnum]))

            vars_dict = self.param_to_dict(
                vars,
                self.model_helper.param_choices,
                self.model_helper.param_categories,
                self.model_helper.param_type,
            )
            moo_solutions.append(self.Soln(vars_dict, solution.objectives))
            logger.info(f"{vars}, {solution.objectives}")

        self.moo_solutions = moo_solutions

        pareto_models = []
        for solution in self.moo_solutions:
            est = self.model_helper.create_instance(solution.variables)
            est_trained = est.fit(X, y)
            pareto_models.append((solution.variables, est_trained))

        self.pareto_models = pareto_models
        return self
コード例 #6
0
 for index, (free_node_num, fix_node_num) in enumerate(
         zip(free_nodes_num, fix_nodes_num)):
     problem = Ansys_GA(mapdl, free_node_num, fix_node_num)
     parent = problem.nvars * parent_mult_value
     #parent = 1
     print(parent)
     history = []
     GA_result_dir = os.path.join(
         PATH, "free_{}_fix_{}".format(free_node_num, fix_node_num))
     os.makedirs(GA_result_dir, exist_ok=True)
     if index == 0:  # 一つ目のGAでは遺伝子を引き継がない
         problem = Ansys_GA(mapdl, free_node_num, fix_node_num)
         algorithm = NSGAII(problem,
                            population_size=parent,
                            variator=CompoundOperator(
                                SBX(), HUX(), PM(), BitFlip()))
     else:  # 二回目以降のGAでは遺伝子を引き継ぐ
         load_GA_result_dir = os.path.join(
             PATH, "free_{}_fix_{}".format(free_nodes_num[index - 1],
                                           fix_nodes_num[index - 1]))
         load_gene_path = os.path.join(load_GA_result_dir, "parents.pk")
         problem = Ansys_GA(mapdl, free_node_num, fix_node_num)
         prior_problem = Ansys_GA(mapdl, free_nodes_num[index - 1],
                                  fix_nodes_num[index - 1])
         algorithm = FixNode_NSGAII(problem,
                                    prior_problem,
                                    gene_path=load_gene_path,
                                    population_size=parent,
                                    variator=CompoundOperator(
                                        SBX(), HUX(), PM(), BitFlip()))
     for i in tqdm(range(generation)):
コード例 #7
0
    def __init__(self,
                 problem,
                 epsilons,
                 population_size=100,
                 generator=RandomGenerator(),
                 selector=TournamentSelector(2),
                 variator=None,
                 **kwargs):

        L = len(problem.parameters)

        # -------------------------------------------------------------------
        #                           DefaultValue            BorgValue
        # PM   probability          1.0                     1.0 / L
        #      distribution index   20                      < 100 (20)
        #      source     Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed
        #
        # SBX  probability          1.0                     > 0.8 (1.0)
        #      distribution index   15                      < 100 (15)
        #      source     Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed;
        #                 Simulated Binary Crossover for Continuous Search
        #                 Space - Deb, Agrawal
        #
        # PCX  nparents             10                      3 (10)
        #      noffspring           2                       2-15 (2)
        #      eta                  0.1                     (0.1)
        #      zeta                 0.1                     (0.1)
        #      source     A Computationally Efficient Evolutionary Algorithm
        #                 for Real-Parameter Optimization - Deb et al 2002
        #
        # DE   crossover rate       0.1                     0.6 (0.1)
        #      step size            0.5                     0.6 (0.5)
        #      source     Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed
        #
        # UNDX nparents             10                      3 (10)
        #      noffspring           2                       2 (2)
        #      zeta                 0.5                     0.5
        #      eta                  0.35                    0.35/sqrt(L) (0.35)
        #      source     Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed;
        #                 A Computationally Efficient Evolutionary Algorithm
        #                 for Real-Parameter Optimization - Deb et al 2002
        #
        # SPX  nparents             10                      L + 1 (10)
        #      noffspring           2                       L + 1 (2)
        #      expansion            None                    sqrt((L+1)+1) (3.0)
        #      source     Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed;
        #                 Multi-parent Recombination with Simplex Crossover
        #                 in Real Coded Genetic Algorithms - Tsutsui
        #
        # UM   probability          1                       1.0 / L
        #      source     Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed
        # -------------------------------------------------------------------

        variators = [
            GAOperator(SBX(probability=1.0, distribution_index=15.0),
                       PM(probability=1.0 / L, distribution_index=20.0)),
            GAOperator(PCX(nparents=3, noffspring=2, eta=0.1, zeta=0.1),
                       PM(probability=1.0 / L, distribution_index=20.0)),
            GAOperator(
                DifferentialEvolution(crossover_rate=0.6, step_size=0.6),
                PM(probability=1.0 / L, distribution_index=20.0)),
            GAOperator(
                UNDX(nparents=3, noffspring=2, zeta=0.5, eta=0.35 / sqrt(L)),
                PM(probability=1.0 / L, distribution_index=20.0)),
            GAOperator(
                SPX(nparents=L + 1, noffspring=L + 1, expansion=sqrt(L + 2)),
                PM(probability=1.0 / L, distribution_index=20.0)),
            UM(probability=1 / L)
        ]

        variator = Multimethod(self, variators)

        super(NSGAIIHybrid, self).__init__(
            NSGAII(problem, population_size, generator, selector, variator,
                   EpsilonBoxArchive(epsilons), **kwargs))
コード例 #8
0
def bar_multi_GA(nx=20,
                 ny=20,
                 volume_frac=0.5,
                 parent=400,
                 generation=100,
                 path="data"):
    PATH = os.path.join(path, "bar_nx_{}_ny_{}".format(nx, ny),
                        "gen_{}_pa_{}".format(generation, parent))
    os.makedirs(PATH, exist_ok=True)
    start = time.time()

    def objective(vars):
        y_1, y_2, y_3, x_4, nodes, widths = convert_var_to_arg(vars)
        edges = make_6_bar_edges(nx, ny, y_1, y_2, y_3, x_4, nodes, widths)
        rho = make_bar_structure(nx, ny, edges)
        volume = np.sum(rho) / (nx * ny)

        return [calc_E(rho), calc_G(rho)], [volume]

    def convert_var_to_arg(vars):
        y_1 = vars[0]
        y_2 = vars[1]
        y_3 = vars[2]
        x_4 = vars[3]
        node_y_indexes = vars[4:4 + 6 * 3]
        node_x_indexes = vars[4 + 6 * 3:4 + 6 * 3 * 2]
        nodes = np.stack([node_x_indexes, node_y_indexes], axis=1)
        widths = vars[4 + 6 * 3 * 2:]
        return y_1, y_2, y_3, x_4, nodes, widths

    # 2変数2目的の問題
    problem = Problem(4 + 6 * 3 * 2 + 6 * 4, 2, 1)
    # 最小化or最大化を設定
    problem.directions[:] = Problem.MAXIMIZE

    # 決定変数の範囲を設定
    x_index_const = Integer(1, nx)  # x座標に関する制約
    y_index_const = Integer(1, ny)  # y座標に関する制約
    bar_constraint = Real(0, ny / 2)  # バーの幅に関する制約
    problem.types[0:3] = y_index_const
    problem.types[3] = x_index_const
    problem.types[4:4 + 6 * 3] = y_index_const
    problem.types[4 + 6 * 3:4 + 6 * 3 * 2] = x_index_const
    problem.types[4 + 6 * 3 * 2:] = bar_constraint

    problem.constraints[:] = "<=" + str(volume_frac)
    problem.function = objective
    problem.directions[:] = Problem.MAXIMIZE
    algorithm = NSGAII(problem,
                       population_size=parent,
                       variator=CompoundOperator(SBX(), HUX(), PM(),
                                                 BitFlip()))
    algorithm.run(generation)

    # グラフを描画

    fig = plt.figure()
    plt.scatter([s.objectives[0] for s in algorithm.result],
                [s.objectives[1] for s in algorithm.result],
                c="blue",
                label="infeasible solution")

    plt.scatter([s.objectives[0] for s in algorithm.result if s.feasible],
                [s.objectives[1] for s in algorithm.result if s.feasible],
                c="red",
                label='feasible solution')

    # 非劣解をとりだす
    nondominated_solutions = nondominated(algorithm.result)
    plt.scatter(
        [s.objectives[0] for s in nondominated_solutions if s.feasible],
        [s.objectives[1] for s in nondominated_solutions if s.feasible],
        c="green",
        label="pareto solution")
    plt.legend(loc='lower left')

    plt.xlabel("$E$")
    plt.ylabel("$G$")
    fig.savefig(os.path.join(PATH, "graph.png"))
    plt.close()

    for solution in [s for s in nondominated_solutions if s.feasible]:
        vars_list = []
        for j in solution.variables[:3]:
            vars_list.append(y_index_const.decode(j))
        vars_list.append(x_index_const.decode(solution.variables[3]))
        for j in solution.variables[4:4 + 6 * 3]:
            vars_list.append(y_index_const.decode(j))
        for j in solution.variables[4 + 6 * 3:4 + 6 * 3 * 2]:
            vars_list.append(x_index_const.decode(j))
        for j in solution.variables[4 + 6 * 3 * 2:]:
            vars_list.append(bar_constraint.decode(j))
        y_1, y_2, y_3, x_4, nodes, widths = convert_var_to_arg(vars_list)
        edges = make_6_bar_edges(nx, ny, y_1, y_2, y_3, x_4, nodes, widths)
        image = make_bar_structure(nx, ny, edges)
        np.save(
            os.path.join(
                PATH, 'E_{}_G_{}.npy'.format(solution.objectives[0],
                                             solution.objectives[1])), image)

    convert_folder_npy_to_image(PATH)

    elapsed_time = time.time() - start

    with open("time.txt", mode='a') as f:
        f.writelines("bar_nx_{}_ny_{}_gen_{}_pa_{}:{}sec\n".format(
            nx, ny, generation, parent, elapsed_time))
コード例 #9
0
    def __init__(self,
                 problem,
                 epsilons,
                 population_size=100,
                 generator=RandomGenerator(),
                 selector=TournamentSelector(2),
                 variator=None,
                 **kwargs):

        L = len(problem.nvars)
        p = 1 / L

        # Parameterization taken from
        # Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed
        variators = [
            GAOperator(SBX(probability=1.0, distribution_index=15.0),
                       PM(probability=p, distribution_index=20.0)),
            GAOperator(PCX(nparents=3, noffspring=2, eta=0.1, zeta=0.1),
                       PM(probability=p, distribution_index=20.0)),
            GAOperator(
                DifferentialEvolution(crossover_rate=0.6, step_size=0.6),
                PM(probability=p, distribution_index=20.0)),
            GAOperator(
                UNDX(nparents=3,
                     noffspring=2,
                     zeta=0.5,
                     eta=0.35 / math.sqrt(L)),
                PM(probability=p, distribution_index=20.0)),
            GAOperator(
                SPX(nparents=L + 1,
                    noffspring=L + 1,
                    expansion=math.sqrt(L + 2)),
                PM(probability=p, distribution_index=20.0)),
            UM(probability=1 / L)
        ]

        variator = Multimethod(self, variators)

        super(GenerationalBorg, self).__init__(
            NSGAII(problem, population_size, generator, selector, variator,
                   EpsilonBoxArchive(epsilons), **kwargs))

        # class GeneAsGenerationalBorg(EpsilonProgressContinuation):
        #     '''A generational implementation of the BORG Framework, combined with
        #     the GeneAs appraoch for heterogenously typed decision variables
        #
        #     This algorithm adopts Epsilon Progress Continuation, and Auto Adaptive
        #     Operator Selection, but embeds them within the NSGAII generational
        #     algorithm, rather than the steady state implementation used by the BORG
        #     algorithm.
        #
        #     Note:: limited to RealParameters only.
        #
        #     '''
        #
        #     # TODO::
        #     # Addressing the limitation to RealParameters is non-trivial. The best
        #     # option seems to be to extent MultiMethod. Have a set of GAoperators
        #     # for each datatype.
        #     # next Iterate over datatypes and apply the appropriate operator.
        #     # Implementing this in platypus is non-trivial. We probably need to do some
        #     # dirty hacking to create 'views' on the relevant part of the
        #     # solution that is to be modified by the operator
        #     #
        #     # A possible solution is to create a wrapper class for the operators
        #     # This class would create the 'view' on the solution. This view should
        #     # also have a fake problem description because the number of
        #     # decision variables is sometimes used by operators. After applying the
        #     # operator to the view, we can than take the results and set these on the
        #     # actual solution
        #     #
        #     # Also: How many operators are there for Integers and Subsets?
        #
        #     def __init__(self, problem, epsilons, population_size=100,
        #                  generator=RandomGenerator(), selector=TournamentSelector(2),
        #                  variator=None, **kwargs):
        #
        #         L = len(problem.parameters)
        #         p = 1/L
        #
        #         # Parameterization taken from
        #         # Borg: An Auto-Adaptive MOEA Framework - Hadka, Reed
        #         real_variators = [GAOperator(SBX(probability=1.0, distribution_index=15.0),
        #                                PM(probability=p, distribution_index=20.0)),
        #                     GAOperator(PCX(nparents=3, noffspring=2, eta=0.1, zeta=0.1),
        #                                PM(probability =p, distribution_index=20.0)),
        #                     GAOperator(DifferentialEvolution(crossover_rate=0.6,
        #                                                      step_size=0.6),
        #                                PM(probability=p, distribution_index=20.0)),
        #                     GAOperator(UNDX(nparents= 3, noffspring=2, zeta=0.5,
        #                                     eta=0.35/math.sqrt(L)),
        #                                PM(probability= p, distribution_index=20.0)),
        #                     GAOperator(SPX(nparents=L+1, noffspring=L+1,
        #                                    expansion=math.sqrt(L+2)),
        #                                PM(probability=p, distribution_index=20.0)),
        #                     UM(probability = 1/L)]
        #
        #         # TODO
        #         integer_variators = []
        #         subset_variators = []
        #
        #         variators = [VariatorWrapper(variator) for variator in real_variators]
        #         variator = Multimethod(self, variators)
        #
        #         super(GenerationalBorg, self).__init__(
        #                 NSGAII(problem,
        #                        population_size,
        #                        generator,
        #                        selector,
        #                        variator,
        #                        EpsilonBoxArchive(epsilons),
        #                        **kwargs))
        #
        #
        # class VariatorWrapper(object):
        #     def __init__(self, actual_variator, indices, problem):
        #         '''
        #
        #         Parameters
        #         ----------
        #         actual_variator : underlying GAOperator
        #         indices : np.array
        #                   indices to which the variator should be applied
        #         probem :  a representation of the problem considering only the
        #                   same kind of Parameters
        #
        #         '''
        #         self.variator = actual_variator
        #         self.indices = indices
        #
        #     def evolve(self, parents):

        fake_parents = [self.create_view[p] for p in parents]
        fake_children = self.variator.evolve(fake_parents)

        # tricky, no 1 to 1 mapping between parents and children
        # some methods have 3 parents, one child
        children = [map_back]

        pass
コード例 #10
0
    for t in range(experient_num):
        PATH = os.path.join(save_dir, "{}".format(t))
        os.makedirs(PATH, exist_ok=True)

        start = time.time()
        # instantiate the optimization algorithm to run in parallel
        for index, (free_node_num, fix_node_num) in enumerate(zip(free_nodes_num, fix_nodes_num)):
            problem = GA_type(free_node_num, fix_node_num)
            parent = problem.nvars * parent_mult_value
            history = []
            GA_result_dir = os.path.join(PATH, "free_{}_fix_{}".format(free_node_num, fix_node_num))
            os.makedirs(GA_result_dir, exist_ok=True)
            with ProcessPoolEvaluator(8) as evaluator:
                if index == 0:  # 一つ目のGAでは遺伝子を引き継がない
                    problem = GA_type(free_node_num, fix_node_num)
                    algorithm = Customized_GeneticAlgorithm(problem, population_size=parent, variator=CompoundOperator(SBX(), HUX(), PM(), BitFlip()), evaluator=evaluator)
                else:  # 二回目以降のGAでは遺伝子を引き継ぐ
                    load_GA_result_dir = os.path.join(PATH, "free_{}_fix_{}".format(free_nodes_num[index - 1], fix_nodes_num[index - 1]))
                    load_gene_path = os.path.join(load_GA_result_dir, "parents.pk")
                    problem = GA_type(free_node_num, fix_node_num)
                    prior_problem = GA_type(free_nodes_num[index - 1], fix_nodes_num[index - 1])
                    algorithm = algorithm_type(problem, prior_problem, gene_path=load_gene_path, population_size=parent, variator=CompoundOperator(SBX(), HUX(), PM(), BitFlip()), evaluator=evaluator)
                for i in tqdm(range(generation)):
                    algorithm.step()
                    efficiency_results = [s.objectives[0] for s in algorithm.result if s.feasible]  # 実行可能解しか抽出しない
                    if len(efficiency_results) != 0:
                        max_efficiency = max(efficiency_results)
                    else:
                        max_efficiency = problem.penalty_value
                    history.append(max_efficiency)
                    epochs = np.arange(i + 1) + 1
コード例 #11
0
 # instantiate the optimization algorithm to run in parallel
 for index, (free_node_num,
             fix_node_num) in enumerate(zip(free_nodes_num, fix_nodes_num)):
     problem = VolumeConstraint_GA(free_node_num, fix_node_num)
     parent = problem.nvars * parent_mult_value
     history = []
     GA_result_dir = os.path.join(
         PATH, "free_{}_fix_{}".format(free_node_num, fix_node_num))
     os.makedirs(GA_result_dir, exist_ok=True)
     with ProcessPoolEvaluator(8) as evaluator:
         if index == 0:  # 一つ目のGAでは遺伝子を引き継がない
             problem = VolumeConstraint_GA(free_node_num, fix_node_num)
             algorithm = NSGAII(problem,
                                population_size=parent,
                                variator=CompoundOperator(
                                    SBX(), HUX(), PM(), BitFlip()),
                                evaluator=evaluator)
         else:  # 二回目以降のGAでは遺伝子を引き継ぐ
             load_GA_result_dir = os.path.join(
                 PATH, "free_{}_fix_{}".format(free_nodes_num[index - 1],
                                               fix_nodes_num[index - 1]))
             load_gene_path = os.path.join(load_GA_result_dir, "parents.pk")
             problem = VolumeConstraint_GA(free_node_num, fix_node_num)
             prior_problem = VolumeConstraint_GA(free_nodes_num[index - 1],
                                                 fix_nodes_num[index - 1])
             algorithm = FixNode_NSGAII(problem,
                                        prior_problem,
                                        gene_path=load_gene_path,
                                        population_size=parent,
                                        variator=CompoundOperator(
                                            SBX(), HUX(), PM(), BitFlip()),
コード例 #12
0
def run(parent, generation, save_interval, save_dir="GA/result"):
    def objective(vars):
        # TODO condition edges_indicesの中身は左の方が右よりも小さいということをassertする
        gene_nodes_pos, gene_edges_thickness, gene_adj_element = convert_var_to_arg(vars)
        return [calculate_efficiency(gene_nodes_pos, gene_edges_thickness, gene_adj_element)]

    def make_adj_triu_matrix(adj_element, node_num, condition_edges_indices):
        """隣接情報を示す遺伝子から,edge_indicesを作成する関数
        """
        adj_matrix = np.zeros((node_num, node_num))
        adj_matrix[np.triu_indices(node_num, 1)] = adj_element

        adj_matrix[(condition_edges_indices[:, 0], condition_edges_indices[:, 1])] = 1
        edge_indices = np.stack(np.where(adj_matrix), axis=1)

        return edge_indices

    def make_edge_thick_triu_matrix(gene_edges_thickness, node_num, condition_edges_indices, condition_edges_thickness, edges_indices):
        """edge_thicknessを示す遺伝子から,condition_edge_thicknessを基にedges_thicknessを作成する関数
        """
        tri = np.zeros((node_num, node_num))
        tri[np.triu_indices(node_num, 1)] = gene_edges_thickness

        tri[(condition_edges_indices[:, 0], condition_edges_indices[:, 1])] = condition_edges_thickness
        edges_thickness = tri[(edges_indices[:, 0], edges_indices[:, 1])]

        return edges_thickness

    def convert_var_to_arg(vars):
        nodes_pos = np.array(vars[0:gene_node_pos_num])
        nodes_pos = nodes_pos.reshape([int(gene_node_pos_num / 2), 2])
        edges_thickness = vars[gene_node_pos_num:gene_node_pos_num + gene_edge_thickness_num]
        adj_element = vars[gene_node_pos_num + gene_edge_thickness_num: gene_node_pos_num + gene_edge_thickness_num + gene_edge_indices_num]
        return nodes_pos, edges_thickness, adj_element

    def calculate_efficiency(gene_nodes_pos, gene_edges_thickness, gene_adj_element, np_save_path=False):
        condition_nodes_pos, input_nodes, input_vectors, output_nodes, \
            output_vectors, frozen_nodes, condition_edges_indices, condition_edges_thickness\
            = make_main_node_edge_info(*condition(), condition_edge_thickness=0.2)

        # make edge_indices
        edges_indices = make_adj_triu_matrix(gene_adj_element, node_num, condition_edges_indices)

        # make nodes_pos
        nodes_pos = np.concatenate([condition_nodes_pos, gene_nodes_pos])

        # 条件ノードが含まれている部分グラフを抽出
        G = nx.Graph()
        G.add_nodes_from(np.arange(len(nodes_pos)))
        G.add_edges_from(edges_indices)
        condition_node_list = input_nodes + output_nodes + frozen_nodes

        trigger = 0  # 条件ノードが全て接続するグラフが存在するとき,トリガーを発動する
        for c in nx.connected_components(G):
            sg = G.subgraph(c)  # 部分グラフ
            if set(condition_node_list) <= set(sg.nodes):  # 条件ノードが全て含まれているか
                edges_indices = np.array(sg.edges)
                trigger = 1
                break
        if trigger == 0:  # ペナルティを発動する
            return -10.0

        # make edges_thickness
        edges_thickness = make_edge_thick_triu_matrix(gene_edges_thickness, node_num, condition_edges_indices, condition_edges_thickness, edges_indices)

        env = BarFemGym(nodes_pos, input_nodes, input_vectors,
                        output_nodes, output_vectors, frozen_nodes,
                        edges_indices, edges_thickness, frozen_nodes)
        env.reset()
        efficiency = env.calculate_simulation()
        if np_save_path:
            env.render(save_path=os.path.join(np_save_path, "image.png"))
            np.save(os.path.join(np_save_path, "nodes_pos.npy"), nodes_pos)
            np.save(os.path.join(np_save_path, "edges_indices.npy"), edges_indices)
            np.save(os.path.join(np_save_path, "edges_thickness.npy"), edges_thickness)

        return float(efficiency)

    node_num = 85
    parent = (node_num * 2 + int(node_num * (node_num - 1) / 2) * 2)  # 本来ならこれの10倍

    PATH = os.path.join(save_dir, "parent_{}_gen_{}".format(parent, generation))
    os.makedirs(PATH, exist_ok=True)

    condition_node_num = 10
    gene_node_pos_num = (node_num - condition_node_num) * 2

    gene_edge_thickness_num = int(node_num * (node_num - 1) / 2)
    gene_edge_indices_num = gene_edge_thickness_num

    # 2変数2目的の問題
    problem = Problem(gene_node_pos_num + gene_edge_thickness_num + gene_edge_indices_num, 1)

    # 最小化or最大化を設定
    problem.directions[:] = Problem.MAXIMIZE

    # 決定変数の範囲を設定
    coord_const = Real(0, 1)
    edge_const = Real(0.1, 1)  # バグが無いように0.1にする
    adj_constraint = Integer(0, 1)

    problem.types[0:gene_node_pos_num] = coord_const
    problem.types[gene_node_pos_num:gene_node_pos_num + gene_edge_thickness_num] = edge_const
    problem.types[gene_node_pos_num + gene_edge_thickness_num: gene_node_pos_num + gene_edge_thickness_num + gene_edge_indices_num] = adj_constraint
    problem.function = objective

    algorithm = NSGAII(problem, population_size=parent,
                       variator=CompoundOperator(SBX(), HUX(), PM(), BitFlip()))

    history = []

    for i in tqdm(range(generation)):
        algorithm.step()
        nondominated_solutions = nondominated(algorithm.result)
        efficiency_results = [s.objectives[0] for s in nondominated_solutions]
        max_efficiency = max(efficiency_results)
        history.append(max_efficiency)

        epochs = np.arange(i + 1) + 1
        result_efficiency = np.array(history)
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        ax.plot(epochs, result_efficiency, label='efficiency')
        ax.set_xlim(1, max(epochs))
        ax.set_xlabel('epoch')
        ax.legend()
        ax.set_title("efficiency curve")
        plt.savefig(os.path.join(PATH, "history.png"))
        plt.close()

        if i % save_interval == 0:
            save_dir = os.path.join(PATH, str(i))
            max_index = efficiency_results.index(max_efficiency)
            max_solution = nondominated_solutions[max_index]

            vars = []
            vars.extend([coord_const.decode(i) for i in max_solution.variables[0:gene_node_pos_num]])
            vars.extend([edge_const.decode(i) for i in max_solution.variables[gene_node_pos_num:gene_node_pos_num + gene_edge_thickness_num]])
            vars.extend([adj_constraint.decode(i) for i in max_solution.variables[gene_node_pos_num + gene_edge_thickness_num: gene_node_pos_num + gene_edge_thickness_num + gene_edge_indices_num]])
            gene_nodes_pos, gene_edges_thickness, gene_adj_element = convert_var_to_arg(vars)
            calculate_efficiency(gene_nodes_pos, gene_edges_thickness, gene_adj_element, np_save_path=save_dir)

            np.save(os.path.join(save_dir, "history.npy"), history)