コード例 #1
0
    def test_run_multiobjective(self):
        result_file = os.path.join(CURRENT_PATH, "data", "reaction_knockout_multi_objective.pkl")
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")

        objective2 = number_of_knockouts()
        objective = [objective1, objective2]

        rko = ReactionKnockoutOptimization(model=self.model,
                                           simulation_method=fba,
                                           objective_function=objective,
                                           heuristic_method=inspyred.ec.emo.NSGA2,
                                           seed=SEED)

        results = rko.run(max_evaluations=3000, pop_size=10, view=SequentialView())

        with open(result_file, 'rb') as in_file:
            if six.PY3:
                expected_results = pickle.load(in_file, encoding="latin1")
            else:
                expected_results = pickle.load(in_file)

        assert_frame_equal(results.solutions, expected_results.solutions)
コード例 #2
0
def cameo_optim(isMultiProc, size):
    model = read_sbml_model(SBML_FILE)
    obj = biomass_product_coupled_yield(
        model.reactions.Ec_biomass_iAF1260_core_59p81M,
        model.reactions.EX_succ_e_, model.reactions.EX_glc_e_)
    ko = ReactionKnockoutOptimization(model=model,
                                      objective_function=obj,
                                      use_nullspace_simplification=False)
    if isMultiProc:
        res = ko.run(pop_size=100,
                     max_generations=1,
                     max_size=size,
                     crossover_rate=0.9,
                     mutation_rate=0.1,
                     indel_rate=0.185,
                     view=MultiprocessingView(processes=2))
    else:
        res = ko.run(pop_size=100,
                     max_generations=1,
                     max_size=size,
                     crossover_rate=0.9,
                     mutation_rate=0.1,
                     indel_rate=0.185)

    res.data_frame.to_csv(basePath + "Results/optim_Ec_iAF1260_ko_cameo.csv")
コード例 #3
0
def evaluate_biomass_coupled_production(
    model: cobra.Model,
    production_id: str,
    biomass_id: str,
    carbon_source_id: str,
) -> Tuple[Optional[float], Optional[float]]:
    """
    Evaluate the biomass coupled production levels in the specific conditions.

    Warnings
    --------
    This function is expected to be called within a context since it modifies
    the model's objective.

    Parameters
    ----------
    model : cobra.Model
        The constraint-based metabolic model of the production organism.
    production_id : str
        The identifier of the reaction representing production, for example,
        a demand reaction on the compound.
    biomass_id : str
        The identifier of the reaction representing biomass accumulation, i.e.,
        growth.
    carbon_source_id : str
        The identifier of the reaction representing carbon uptake, for example,
        a glucose exchange reaction.

    Returns
    -------
    tuple
        float or None
            The theoretical maximum growth rate if any.
        float or None
            The maximum biomass coupled product yield if any.

    """
    bpcy = biomass_product_coupled_yield(
        biomass_id, production_id, carbon_source_id
    )
    try:
        model.objective = biomass_id
        solution = pfba(model)
        growth = solution[biomass_id]
    except OptimizationError as error:
        logger.error(
            "Could not determine biomass coupled production due to a solver "
            "error. %r",
            error,
        )
        growth = None
        bpc_yield = None
    else:
        try:
            bpc_yield = bpcy(model, solution, None)
        except ZeroDivisionError:
            logger.error("Division by zero in yield calculation.")
            bpc_yield = None
    return growth, bpc_yield
コード例 #4
0
    def test_evaluate_infeasibile_solution(self):
        representation = ["ENO", "ATPS4r", "PYK", "GLUDy", "PPS", "CO2t", "PDH",
                          "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"]

        decoder = ReactionKnockoutDecoder(representation, TEST_MODEL)
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, objective1, fba, {})
        fitness = evaluator([[0]])[0]
        self.assertEquals(fitness, 0)
コード例 #5
0
    def test_initializer(self):
        objective = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        rko = ReactionKnockoutOptimization(model=self.model,
                                           simulation_method=fba,
                                           objective_function=objective)

        self.assertTrue(sorted(self.essential_reactions) == sorted(rko.essential_reactions))
        self.assertEqual(rko._target_type, "reaction")
        self.assertTrue(isinstance(rko._decoder, ReactionSetDecoder))
コード例 #6
0
    def test_evaluate_infeasible_solution(self):
        representation = ["ENO", "ATPS4r", "PYK", "GLUDy", "PPS", "CO2t", "PDH",
                          "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"]

        decoder = ReactionSetDecoder(representation, TEST_MODEL)
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, objective1, fba, {})
        fitness = evaluator([[0]])[0]
        self.assertEquals(fitness, 0)
コード例 #7
0
 def test_invalid_initializers(self):
     objective1 = biomass_product_coupled_yield(
         "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
         "EX_ac_LPAREN_e_RPAREN_",
         "EX_glc_LPAREN_e_RPAREN_")
     decoder = ReactionKnockoutDecoder(["PGI", "PDH", "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"], TEST_MODEL)
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, 1, fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, None, fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, [], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, [2, 3], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, [objective1, 2], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, None, [], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, True, [], fba, {})
コード例 #8
0
 def test_invalid_initializers(self):
     objective1 = biomass_product_coupled_yield(
         "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
         "EX_ac_LPAREN_e_RPAREN_",
         "EX_glc_LPAREN_e_RPAREN_")
     decoder = ReactionSetDecoder(["PGI", "PDH", "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"], TEST_MODEL)
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, 1, fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, None, fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, [], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, [2, 3], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, decoder, [objective1], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, None, [], fba, {})
     self.assertRaises(ValueError, KnockoutEvaluator, TEST_MODEL, True, [], fba, {})
コード例 #9
0
    def test_initializer(self):
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        decoder = ReactionSetDecoder(["PGI", "PDH", "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"], TEST_MODEL)
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, objective1, fba, {})
        self.assertEquals(evaluator.decoder, decoder)
        self.assertEquals(evaluator.objective_function, objective1)
        self.assertTrue(hasattr(evaluator, "__call__"))

        objective2 = product_yield("EX_ac_LPAREN_e_RPAREN_", "EX_glc_LPAREN_e_RPAREN_")
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, MultiObjectiveFunction([objective1, objective2]), fba, {})
        self.assertEquals(evaluator.objective_function.objectives, [objective1, objective2])
コード例 #10
0
    def test_evaluate_multiobjective(self):
        representation = ["ATPS4r", "PYK", "GLUDy", "PPS", "CO2t", "PDH",
                          "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"]
        decoder = ReactionKnockoutDecoder(representation, TEST_MODEL)
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        objective2 = product_yield("EX_ac_LPAREN_e_RPAREN_", "EX_glc_LPAREN_e_RPAREN_")

        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, [objective1, objective2], fba, {})
        fitness = evaluator([[0, 1, 2, 3, 4]])[0]

        self.assertIsInstance(fitness, Pareto)
        self.assertAlmostEqual(fitness[0], 0.41, delta=0.02)
        self.assertAlmostEqual(fitness[1], 1.57, delta=0.035)
コード例 #11
0
    def test_initializer(self):
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        decoder = ReactionKnockoutDecoder(["PGI", "PDH", "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"], TEST_MODEL)
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, objective1, fba, {})
        self.assertEquals(evaluator.decoder, decoder)
        self.assertEquals(evaluator.objective_function, objective1)
        self.assertFalse(evaluator.is_mo)
        self.assertTrue(hasattr(evaluator, "__call__"))

        objective2 = product_yield("EX_ac_LPAREN_e_RPAREN_", "EX_glc_LPAREN_e_RPAREN_")
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, [objective1, objective2], fba, {})
        self.assertEquals(evaluator.objective_function, [objective1, objective2])
        self.assertTrue(evaluator.is_mo)
コード例 #12
0
    def test_biomass_product_coupled_yield(self):
        solution = self._MockupSolution()
        solution.set_primal('biomass', 0.6)
        solution.set_primal('product', 2)
        solution.set_primal('substrate', -10)

        of = biomass_product_coupled_yield("biomass", "product", "substrate")
        self.assertEqual(of.name, "bpcy = (biomass * product) / substrate")

        fitness = of(None, solution, None)
        self.assertAlmostEqual((0.6 * 2) / 10, fitness)

        solution.set_primal('substrate', 0)

        fitness = of(None, solution, None)
        self.assertEquals(0, fitness)
コード例 #13
0
    def test_evaluate_multiobjective(self):
        representation = ["ATPS4r", "PYK", "GLUDy", "PPS", "CO2t", "PDH",
                          "FUM", "FBA", "G6PDH2r", "FRD7", "PGL", "PPC"]
        decoder = ReactionSetDecoder(representation, TEST_MODEL)
        objective1 = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")
        objective2 = product_yield("EX_ac_LPAREN_e_RPAREN_", "EX_glc_LPAREN_e_RPAREN_")
        objective = MultiObjectiveFunction([objective1, objective2])
        evaluator = KnockoutEvaluator(TEST_MODEL, decoder, objective, fba, {})
        fitness = evaluator([[0, 1, 2, 3, 4]])[0]

        self.assertIsInstance(fitness, Pareto)
        self.assertAlmostEqual(fitness[0], 0.41, delta=0.02)
        self.assertAlmostEqual(fitness[1], 1.57, delta=0.035)
コード例 #14
0
    def test_biomass_product_coupled_yield(self):
        solution = self._MockupSolution()
        solution.set_primal('biomass', 0.6)
        solution.set_primal('product', 2)
        solution.set_primal('substrate', -10)

        of = biomass_product_coupled_yield("biomass", "product", "substrate")
        self.assertEqual(of.name, "bpcy = (biomass * product) / substrate")

        fitness = of(None, solution, None)
        self.assertAlmostEqual((0.6 * 2) / 10, fitness)

        solution.set_primal('substrate', 0)

        fitness = of(None, solution, None)
        self.assertEquals(0, fitness)
コード例 #15
0
    def test_run_single_objective(self):
        result_file = os.path.join(CURRENT_PATH, "data", "reaction_knockout_single_objective.pkl")
        objective = biomass_product_coupled_yield(
            "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2",
            "EX_ac_LPAREN_e_RPAREN_",
            "EX_glc_LPAREN_e_RPAREN_")

        rko = ReactionKnockoutOptimization(model=self.model,
                                           simulation_method=fba,
                                           objective_function=objective)

        results = rko.run(max_evaluations=3000, pop_size=10, view=SequentialView(), seed=SEED)

        with open(result_file, 'rb') as in_file:
            if six.PY3:
                expected_results = pickle.load(in_file, encoding="latin1")
            else:
                expected_results = pickle.load(in_file)

        assert_frame_equal(results.data_frame, expected_results.data_frame)
コード例 #16
0
    def run(self,
            target=None,
            biomass=None,
            substrate=None,
            max_knockouts=5,
            variable_size=True,
            simulation_method=fba,
            growth_coupled=False,
            max_evaluations=20000,
            population_size=200,
            max_results=50,
            use_nullspace_simplification=True,
            seed=None,
            **kwargs):
        """
        Parameters
        ----------
        target : str, Metabolite or Reaction
            The design target
        biomass : str, Metabolite or Reaction
            The biomass definition in the model
        substrate : str, Metabolite or Reaction
            The main carbon source
        max_knockouts : int
            Max number of knockouts allowed
        variable_size : bool
            If true, all candidates have the same size. Otherwise the candidate size can be from 1 to max_knockouts.
        simulation_method : function
            Any method from cameo.flux_analysis.simulation or equivalent
        growth_coupled : bool
            If true will use the minimum flux rate to compute the fitness
        max_evaluations : int
            Number of evaluations before stop
        population_size : int
            Number of individuals in each generation
        max_results : int
            Max number of different designs to return if found.
        kwargs : dict
            Arguments for the simulation method.
        seed : int
            A seed for random.
        use_nullspace_simplification : Boolean (default True)
            Use a basis for the nullspace to find groups of reactions whose fluxes are multiples of each other and dead
            end reactions. From each of these groups only 1 reaction will be included as a possible knockout.


        Returns
        -------
        OptGeneResult
        """

        target = get_reaction_for(self._model, target)
        biomass = get_reaction_for(self._model, biomass)
        substrate = get_reaction_for(self._model, substrate)

        if growth_coupled:
            objective_function = biomass_product_coupled_min_yield(
                biomass, target, substrate)
        else:
            objective_function = biomass_product_coupled_yield(
                biomass, target, substrate)
        if self.manipulation_type == "genes":
            optimization_algorithm = GeneKnockoutOptimization(
                model=self._model,
                heuristic_method=self._algorithm,
                essential_genes=self._essential_genes,
                plot=self.plot,
                objective_function=objective_function,
                use_nullspace_simplification=use_nullspace_simplification)
        elif self.manipulation_type == "reactions":
            optimization_algorithm = ReactionKnockoutOptimization(
                model=self._model,
                heuristic_method=self._algorithm,
                essential_reactions=self._essential_reactions,
                plot=self.plot,
                objective_function=objective_function,
                use_nullspace_simplification=use_nullspace_simplification)
        else:
            raise ValueError("Invalid manipulation type %s" %
                             self.manipulation_type)
        optimization_algorithm.simulation_kwargs = kwargs
        optimization_algorithm.simulation_method = simulation_method
        optimization_algorithm.archiver = ProductionStrainArchive()

        result = optimization_algorithm.run(max_evaluations=max_evaluations,
                                            pop_size=population_size,
                                            max_size=max_knockouts,
                                            variable_size=variable_size,
                                            maximize=True,
                                            max_archive_size=max_results,
                                            seed=seed,
                                            **kwargs)

        kwargs.update(optimization_algorithm.simulation_kwargs)

        return OptGeneResult(self._model, result, objective_function,
                             simulation_method, self.manipulation_type,
                             biomass, target, substrate, kwargs)
コード例 #17
0
    def run(self,
            target=None,
            biomass=None,
            substrate=None,
            max_swaps=5,
            variable_size=True,
            simulation_method=fba,
            growth_coupled=False,
            max_evaluations=20000,
            population_size=200,
            time_machine=None,
            max_results=50,
            seed=None,
            **kwargs):
        """
        Parameters
        ----------
        target : str, Metabolite or Reaction
            The design target.
        biomass : str, Metabolite or Reaction
            The biomass definition in the model.
        substrate : str, Metabolite or Reaction
            The main carbon source.
        max_swaps : int
            Max number of swaps allowed.
        variable_size : bool
            If true, all candidates have the same size. Otherwise the candidate size can be from 1 to max_knockouts.
        simulation_method : function
            Any method from cameo.flux_analysis.simulation or equivalent.
        growth_coupled : bool
            If true will use the minimum flux rate to compute the fitness.
        max_evaluations : int
            Number of evaluations before stop.
        population_size : int
            Number of individuals in each generation.
        time_machine : TimeMachine
            See TimeMachine.
        max_results : int
            Max number of different designs to return if found.
        kwargs : dict
            Arguments for the simulation method.
        seed : int
            A seed for random.


        Returns
        -------
        HeuristicOptSwapResult
        """

        target = get_reaction_for(self._model, target)
        biomass = get_reaction_for(self._model, biomass)
        substrate = get_reaction_for(self._model, substrate)

        if growth_coupled:
            objective_function = biomass_product_coupled_min_yield(
                biomass, target, substrate)
        else:
            objective_function = biomass_product_coupled_yield(
                biomass, target, substrate)

        optimization_algorithm = CofactorSwapOptimization(
            model=self._model,
            cofactor_id_swaps=self._cofactor_id_swaps,
            skip_reactions=self._skip_reactions,
            objective_function=objective_function)

        optimization_algorithm.simulation_kwargs = kwargs
        optimization_algorithm.simulation_method = simulation_method
        optimization_algorithm.archiver = ProductionStrainArchive()

        result = optimization_algorithm.run(max_evaluations=max_evaluations,
                                            pop_size=population_size,
                                            max_size=max_swaps,
                                            variable_size=variable_size,
                                            maximize=True,
                                            max_archive_size=max_results,
                                            seed=seed,
                                            **kwargs)

        kwargs.update(optimization_algorithm.simulation_kwargs)

        return HeuristicOptSwapResult(self._model, result, self._swap_pairs,
                                      objective_function, simulation_method,
                                      biomass, target, substrate, kwargs)
コード例 #18
0
    def run(self, target=None, biomass=None, substrate=None, max_knockouts=5, variable_size=True,
            simulation_method=fba, growth_coupled=False, max_evaluations=20000, population_size=200,
            max_results=50, use_nullspace_simplification=True, seed=None, **kwargs):
        """
        Parameters
        ----------
        target : str, Metabolite or Reaction
            The design target
        biomass : str, Metabolite or Reaction
            The biomass definition in the model
        substrate : str, Metabolite or Reaction
            The main carbon source
        max_knockouts : int
            Max number of knockouts allowed
        variable_size : bool
            If true, all candidates have the same size. Otherwise the candidate size can be from 1 to max_knockouts.
        simulation_method : function
            Any method from cameo.flux_analysis.simulation or equivalent
        growth_coupled : bool
            If true will use the minimum flux rate to compute the fitness
        max_evaluations : int
            Number of evaluations before stop
        population_size : int
            Number of individuals in each generation
        max_results : int
            Max number of different designs to return if found.
        kwargs : dict
            Arguments for the simulation method.
        seed : int
            A seed for random.
        use_nullspace_simplification : Boolean (default True)
            Use a basis for the nullspace to find groups of reactions whose fluxes are multiples of each other and dead
            end reactions. From each of these groups only 1 reaction will be included as a possible knockout.


        Returns
        -------
        OptGeneResult
        """

        target = get_reaction_for(self._model, target)
        biomass = get_reaction_for(self._model, biomass)
        substrate = get_reaction_for(self._model, substrate)

        if growth_coupled:
            objective_function = biomass_product_coupled_min_yield(biomass, target, substrate)
        else:
            objective_function = biomass_product_coupled_yield(biomass, target, substrate)
        if self.manipulation_type == "genes":
            optimization_algorithm = GeneKnockoutOptimization(
                model=self._model,
                heuristic_method=self._algorithm,
                essential_genes=self._essential_genes,
                plot=self.plot,
                objective_function=objective_function,
                use_nullspace_simplification=use_nullspace_simplification)
        elif self.manipulation_type == "reactions":
            optimization_algorithm = ReactionKnockoutOptimization(
                model=self._model,
                heuristic_method=self._algorithm,
                essential_reactions=self._essential_reactions,
                plot=self.plot,
                objective_function=objective_function,
                use_nullspace_simplification=use_nullspace_simplification)
        else:
            raise ValueError("Invalid manipulation type %s" % self.manipulation_type)
        optimization_algorithm.simulation_kwargs = kwargs
        optimization_algorithm.simulation_method = simulation_method
        optimization_algorithm.archiver = ProductionStrainArchive()

        result = optimization_algorithm.run(max_evaluations=max_evaluations,
                                            pop_size=population_size,
                                            max_size=max_knockouts,
                                            variable_size=variable_size,
                                            maximize=True,
                                            max_archive_size=max_results,
                                            seed=seed,
                                            **kwargs)

        kwargs.update(optimization_algorithm.simulation_kwargs)

        return OptGeneResult(self._model, result, objective_function, simulation_method, self.manipulation_type,
                             biomass, target, substrate, kwargs)
コード例 #19
0
    def run(self, target=None, biomass=None, substrate=None, max_swaps=5, variable_size=True,
            simulation_method=fba, growth_coupled=False, max_evaluations=20000, population_size=200,
            time_machine=None, max_results=50, seed=None, **kwargs):
        """
        Parameters
        ----------
        target : str, Metabolite or Reaction
            The design target.
        biomass : str, Metabolite or Reaction
            The biomass definition in the model.
        substrate : str, Metabolite or Reaction
            The main carbon source.
        max_swaps : int
            Max number of swaps allowed.
        variable_size : bool
            If true, all candidates have the same size. Otherwise the candidate size can be from 1 to max_knockouts.
        simulation_method : function
            Any method from cameo.flux_analysis.simulation or equivalent.
        growth_coupled : bool
            If true will use the minimum flux rate to compute the fitness.
        max_evaluations : int
            Number of evaluations before stop.
        population_size : int
            Number of individuals in each generation.
        time_machine : TimeMachine
            See TimeMachine.
        max_results : int
            Max number of different designs to return if found.
        kwargs : dict
            Arguments for the simulation method.
        seed : int
            A seed for random.


        Returns
        -------
        HeuristicOptSwapResult
        """

        target = get_reaction_for(self._model, target)
        biomass = get_reaction_for(self._model, biomass)
        substrate = get_reaction_for(self._model, substrate)

        if growth_coupled:
            objective_function = biomass_product_coupled_min_yield(biomass, target, substrate)
        else:
            objective_function = biomass_product_coupled_yield(biomass, target, substrate)

        optimization_algorithm = CofactorSwapOptimization(model=self._model,
                                                          cofactor_id_swaps=self._cofactor_id_swaps,
                                                          skip_reactions=self._skip_reactions,
                                                          objective_function=objective_function)

        optimization_algorithm.simulation_kwargs = kwargs
        optimization_algorithm.simulation_method = simulation_method
        optimization_algorithm.archiver = ProductionStrainArchive()

        result = optimization_algorithm.run(max_evaluations=max_evaluations,
                                            pop_size=population_size,
                                            max_size=max_swaps,
                                            variable_size=variable_size,
                                            maximize=True,
                                            max_archive_size=max_results,
                                            seed=seed,
                                            **kwargs)

        kwargs.update(optimization_algorithm.simulation_kwargs)

        return HeuristicOptSwapResult(self._model, result, self._swap_pairs, objective_function,
                                      simulation_method, biomass, target, substrate, kwargs)