重构框架,提高复用性,算子拆分,代码可读性提高
This commit is contained in:
parent
5f7b5ef822
commit
8e5a4710d6
61
.gitignore
vendored
Normal file
61
.gitignore
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
Thumbs.db
|
@ -10,6 +10,7 @@ from .individual import AlgorithmIndividual
|
|||||||
from ..config.settings import DEFAULT_EVOLUTION_PARAMS
|
from ..config.settings import DEFAULT_EVOLUTION_PARAMS
|
||||||
from .evolution_algorithms.tournament import TournamentEvolution
|
from .evolution_algorithms.tournament import TournamentEvolution
|
||||||
from .evolution_algorithms.differential import DifferentialEvolution
|
from .evolution_algorithms.differential import DifferentialEvolution
|
||||||
|
from .operators import InitializeOperator
|
||||||
|
|
||||||
class EvolutionEngine:
|
class EvolutionEngine:
|
||||||
def __init__(self, problem_path: str):
|
def __init__(self, problem_path: str):
|
||||||
@ -17,6 +18,7 @@ class EvolutionEngine:
|
|||||||
self.storage = GenerationStorage(problem_path)
|
self.storage = GenerationStorage(problem_path)
|
||||||
self.evaluator = AlgorithmEvaluator(problem_path)
|
self.evaluator = AlgorithmEvaluator(problem_path)
|
||||||
self.llm_client = LLMClient.from_config(problem_path)
|
self.llm_client = LLMClient.from_config(problem_path)
|
||||||
|
self.initialize_operator = InitializeOperator(self.llm_client)
|
||||||
|
|
||||||
# 加载进化参数
|
# 加载进化参数
|
||||||
config = self._load_problem_config()
|
config = self._load_problem_config()
|
||||||
@ -43,7 +45,7 @@ class EvolutionEngine:
|
|||||||
individuals = []
|
individuals = []
|
||||||
|
|
||||||
while len(individuals) < size:
|
while len(individuals) < size:
|
||||||
code = self.llm_client.generate_initial_code(
|
code = self.initialize_operator.generate_initial_code(
|
||||||
problem_config["description"],
|
problem_config["description"],
|
||||||
problem_config["function_name"],
|
problem_config["function_name"],
|
||||||
problem_config["input_format"],
|
problem_config["input_format"],
|
||||||
@ -147,5 +149,4 @@ class EvolutionEngine:
|
|||||||
print(f"加载问题配置:{config_path}")
|
print(f"加载问题配置:{config_path}")
|
||||||
with open(config_path, "r", encoding="utf-8") as f:
|
with open(config_path, "r", encoding="utf-8") as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
# print(f"配置内容:{json.dumps(config, indent=2, ensure_ascii=False)}")
|
|
||||||
return config
|
return config
|
@ -4,6 +4,8 @@ import numpy as np
|
|||||||
from .base import BaseEvolutionAlgorithm
|
from .base import BaseEvolutionAlgorithm
|
||||||
from ..individual import AlgorithmIndividual
|
from ..individual import AlgorithmIndividual
|
||||||
from ..llm_integration import LLMClient
|
from ..llm_integration import LLMClient
|
||||||
|
from ..operators import VerifyOperator
|
||||||
|
from ..operators import DECrossoverOperator, DEMutationOperator
|
||||||
|
|
||||||
class DifferentialEvolution(BaseEvolutionAlgorithm):
|
class DifferentialEvolution(BaseEvolutionAlgorithm):
|
||||||
def __init__(self, config: dict, llm_client: LLMClient):
|
def __init__(self, config: dict, llm_client: LLMClient):
|
||||||
@ -12,6 +14,9 @@ class DifferentialEvolution(BaseEvolutionAlgorithm):
|
|||||||
self.F = config.get("F", 0.8) # 缩放因子
|
self.F = config.get("F", 0.8) # 缩放因子
|
||||||
self.CR = config.get("CR", 0.7) # 交叉概率
|
self.CR = config.get("CR", 0.7) # 交叉概率
|
||||||
self.llm_client = llm_client
|
self.llm_client = llm_client
|
||||||
|
self.crossover_operator = DECrossoverOperator(llm_client)
|
||||||
|
self.mutation_operator = DEMutationOperator(llm_client)
|
||||||
|
self.verify_operator = VerifyOperator(llm_client)
|
||||||
|
|
||||||
def select(self, population: List[AlgorithmIndividual], num_parents: int) -> List[AlgorithmIndividual]:
|
def select(self, population: List[AlgorithmIndividual], num_parents: int) -> List[AlgorithmIndividual]:
|
||||||
"""DE选择:随机选择3个不同的个体作为父代"""
|
"""DE选择:随机选择3个不同的个体作为父代"""
|
||||||
@ -29,65 +34,18 @@ class DifferentialEvolution(BaseEvolutionAlgorithm):
|
|||||||
|
|
||||||
target = parents[0] # 目标向量
|
target = parents[0] # 目标向量
|
||||||
if random.random() < self.CR:
|
if random.random() < self.CR:
|
||||||
# 构建DE交叉提示词
|
child_code = self.crossover_operator.crossover(target.code)
|
||||||
prompt = f"""请将以下代码进行差分进化风格的交叉操作:
|
|
||||||
|
|
||||||
目标代码:
|
|
||||||
{target.code}
|
|
||||||
|
|
||||||
要求:
|
|
||||||
1. 保持函数签名不变
|
|
||||||
2. 使用差分进化的思想,对代码结构进行创新性重组
|
|
||||||
3. 尝试保留目标代码的优秀特性,同时引入新的改进
|
|
||||||
4. 生成的代码必须是完整可运行的函数
|
|
||||||
5. 避免过度复杂化,保持代码的可读性和效率
|
|
||||||
|
|
||||||
建议:
|
|
||||||
- 可以重组代码的核心算法部分
|
|
||||||
- 可以调整关键参数或阈值
|
|
||||||
- 可以优化数据结构的使用
|
|
||||||
- 可以改进算法的某些步骤"""
|
|
||||||
|
|
||||||
child_code = self.llm_client.crossover(target.code, target.code) # 使用相同代码作为基础
|
|
||||||
if child_code:
|
if child_code:
|
||||||
# 验证生成的代码
|
return [AlgorithmIndividual(child_code, target.generation + 1)]
|
||||||
function_name = target.code.split("def ")[1].split("(")[0].strip()
|
|
||||||
verified_code = self.llm_client.verify_code_format(child_code, function_name)
|
|
||||||
if verified_code:
|
|
||||||
return [AlgorithmIndividual(verified_code, target.generation + 1)]
|
|
||||||
|
|
||||||
return [target]
|
return [target]
|
||||||
|
|
||||||
def mutate(self, individual: AlgorithmIndividual) -> AlgorithmIndividual:
|
def mutate(self, individual: AlgorithmIndividual) -> AlgorithmIndividual:
|
||||||
"""DE风格的变异操作"""
|
"""DE风格的变异操作"""
|
||||||
if random.random() < self.F:
|
if random.random() < self.F:
|
||||||
# 构建DE变异提示词
|
mutated_code = self.mutation_operator.mutate(individual.code)
|
||||||
prompt = f"""请对以下代码进行差分进化风格的变异操作:
|
|
||||||
|
|
||||||
原始代码:
|
|
||||||
{individual.code}
|
|
||||||
|
|
||||||
要求:
|
|
||||||
1. 保持函数签名不变
|
|
||||||
2. 引入差分变异的思想,对代码进行局部或全局的改进
|
|
||||||
3. 变异强度应该适中,不要完全改变算法的核心思想
|
|
||||||
4. 生成的代码必须是完整可运行的函数
|
|
||||||
5. 保持代码的可读性和效率
|
|
||||||
|
|
||||||
建议的变异操作:
|
|
||||||
- 调整算法中的关键参数
|
|
||||||
- 修改某些判断条件或循环结构
|
|
||||||
- 优化数据结构的使用方式
|
|
||||||
- 添加或移除某些优化步骤
|
|
||||||
- 改变算法某些部分的实现方法"""
|
|
||||||
|
|
||||||
mutated_code = self.llm_client.mutate(individual.code)
|
|
||||||
if mutated_code:
|
if mutated_code:
|
||||||
# 验证生成的代码
|
return AlgorithmIndividual(mutated_code, individual.generation)
|
||||||
function_name = individual.code.split("def ")[1].split("(")[0].strip()
|
|
||||||
verified_code = self.llm_client.verify_code_format(mutated_code, function_name)
|
|
||||||
if verified_code:
|
|
||||||
return AlgorithmIndividual(verified_code, individual.generation)
|
|
||||||
|
|
||||||
return individual
|
return individual
|
||||||
|
|
||||||
@ -106,4 +64,4 @@ class DifferentialEvolution(BaseEvolutionAlgorithm):
|
|||||||
if len(survivors) < pop_size:
|
if len(survivors) < pop_size:
|
||||||
survivors.extend(population[len(survivors):pop_size])
|
survivors.extend(population[len(survivors):pop_size])
|
||||||
|
|
||||||
return survivors[:pop_size]
|
return survivors[:pop_size]
|
@ -4,12 +4,15 @@ import numpy as np
|
|||||||
from .base import BaseEvolutionAlgorithm
|
from .base import BaseEvolutionAlgorithm
|
||||||
from ..individual import AlgorithmIndividual
|
from ..individual import AlgorithmIndividual
|
||||||
from ..llm_integration import LLMClient
|
from ..llm_integration import LLMClient
|
||||||
|
from ..operators import CrossoverOperator, MutationOperator
|
||||||
|
|
||||||
class TournamentEvolution(BaseEvolutionAlgorithm):
|
class TournamentEvolution(BaseEvolutionAlgorithm):
|
||||||
def __init__(self, config: dict, llm_client: LLMClient):
|
def __init__(self, config: dict, llm_client: LLMClient):
|
||||||
super().__init__(config)
|
super().__init__(config)
|
||||||
self.tournament_size = config.get("tournament_size", 3)
|
self.tournament_size = config.get("tournament_size", 3)
|
||||||
self.llm_client = llm_client
|
self.llm_client = llm_client
|
||||||
|
self.crossover_operator = CrossoverOperator(llm_client)
|
||||||
|
self.mutation_operator = MutationOperator(llm_client)
|
||||||
|
|
||||||
def select(self, population: List[AlgorithmIndividual], num_parents: int) -> List[AlgorithmIndividual]:
|
def select(self, population: List[AlgorithmIndividual], num_parents: int) -> List[AlgorithmIndividual]:
|
||||||
"""锦标赛选择"""
|
"""锦标赛选择"""
|
||||||
@ -28,7 +31,7 @@ class TournamentEvolution(BaseEvolutionAlgorithm):
|
|||||||
return parents
|
return parents
|
||||||
|
|
||||||
if random.random() < self.config["crossover_rate"]:
|
if random.random() < self.config["crossover_rate"]:
|
||||||
child_code = self.llm_client.crossover(parents[0].code, parents[1].code)
|
child_code = self.crossover_operator.crossover(parents[0].code, parents[1].code)
|
||||||
if child_code:
|
if child_code:
|
||||||
return [AlgorithmIndividual(child_code, parents[0].generation + 1)]
|
return [AlgorithmIndividual(child_code, parents[0].generation + 1)]
|
||||||
return [parents[0]]
|
return [parents[0]]
|
||||||
@ -36,7 +39,7 @@ class TournamentEvolution(BaseEvolutionAlgorithm):
|
|||||||
def mutate(self, individual: AlgorithmIndividual) -> AlgorithmIndividual:
|
def mutate(self, individual: AlgorithmIndividual) -> AlgorithmIndividual:
|
||||||
"""LLM代码变异"""
|
"""LLM代码变异"""
|
||||||
if random.random() < self.config["mutation_rate"]:
|
if random.random() < self.config["mutation_rate"]:
|
||||||
mutated_code = self.llm_client.mutate(individual.code)
|
mutated_code = self.mutation_operator.mutate(individual.code)
|
||||||
if mutated_code:
|
if mutated_code:
|
||||||
return AlgorithmIndividual(mutated_code, individual.generation)
|
return AlgorithmIndividual(mutated_code, individual.generation)
|
||||||
return individual
|
return individual
|
||||||
@ -44,4 +47,4 @@ class TournamentEvolution(BaseEvolutionAlgorithm):
|
|||||||
def survive(self, population: List[AlgorithmIndividual], offspring: List[AlgorithmIndividual],
|
def survive(self, population: List[AlgorithmIndividual], offspring: List[AlgorithmIndividual],
|
||||||
pop_size: int) -> List[AlgorithmIndividual]:
|
pop_size: int) -> List[AlgorithmIndividual]:
|
||||||
"""直接用子代替换父代"""
|
"""直接用子代替换父代"""
|
||||||
return offspring[:pop_size]
|
return offspring[:pop_size]
|
@ -48,79 +48,6 @@ class LLMClient:
|
|||||||
temperature=llm_config["temperature"]
|
temperature=llm_config["temperature"]
|
||||||
)
|
)
|
||||||
|
|
||||||
def verify_code_format(self, code: str, function_name: str) -> Optional[str]:
|
|
||||||
"""验证代码格式是否符合要求"""
|
|
||||||
prompt = f"""请检查以下代码是否满足要求,如果不满足则进行修正:
|
|
||||||
{code}
|
|
||||||
|
|
||||||
要求:
|
|
||||||
1. 只包含函数实现代码,不包含任何说明、注释或示例
|
|
||||||
2. 主函数名必须为 {function_name}
|
|
||||||
3. 不包含main函数或测试代码
|
|
||||||
4. 只返回修正后的代码,不要包含任何其他内容
|
|
||||||
|
|
||||||
如果代码已经符合要求,直接返回原代码;如果需要修正,返回修正后的代码。"""
|
|
||||||
|
|
||||||
result = self._call_llm(prompt, operator="verify")
|
|
||||||
return result if result else code
|
|
||||||
|
|
||||||
def generate_initial_code(self, problem_desc: str, function_name: str, input_fmt: str, output_fmt: str) -> str:
|
|
||||||
"""生成初始算法代码"""
|
|
||||||
prompt = f"""请用Python编写一个解决以下问题的函数:
|
|
||||||
问题描述:{problem_desc}
|
|
||||||
|
|
||||||
函数要求:
|
|
||||||
1. 函数名:{function_name}
|
|
||||||
2. 输入:{input_fmt}
|
|
||||||
3. 返回值:{output_fmt}
|
|
||||||
|
|
||||||
注意:
|
|
||||||
- 不需要添加类型注解
|
|
||||||
- 只返回函数代码,不要包含任何解释或测试用例
|
|
||||||
- 我们允许返回的代码中包含了多个函数,但是一定要确直接运行{function_name}函数并将数据传入即可完成全部流程并获得预期的返回
|
|
||||||
- 算法应该尽可能地创新,避免完全依赖已有的成熟算法,可以接受在成熟算法的基础上进行一定的修改
|
|
||||||
- 算法应该尽可能地简洁,避免不必要的复杂性
|
|
||||||
"""
|
|
||||||
code = self._call_llm(prompt, operator="initialize")
|
|
||||||
if code:
|
|
||||||
return self.verify_code_format(code, function_name)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def crossover(self, code1: str, code2: str) -> str:
|
|
||||||
"""代码交叉操作"""
|
|
||||||
prompt = f"""请将以下两个Python函数进行交叉操作,生成一个新的高效实现:
|
|
||||||
函数1:
|
|
||||||
{code1}
|
|
||||||
|
|
||||||
函数2:
|
|
||||||
{code2}
|
|
||||||
|
|
||||||
要求:
|
|
||||||
1. 保持函数签名不变
|
|
||||||
2. 结合两个实现的优点
|
|
||||||
3. 生成完整可运行的函数代码"""
|
|
||||||
code = self._call_llm(prompt, operator="crossover")
|
|
||||||
if code:
|
|
||||||
# 从code1中提取函数名
|
|
||||||
function_name = code1.split("def ")[1].split("(")[0].strip()
|
|
||||||
return self.verify_code_format(code, function_name)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def mutate(self, code: str) -> str:
|
|
||||||
"""代码变异操作"""
|
|
||||||
prompt = f"""请对以下Python函数进行创新性改进:
|
|
||||||
{code}
|
|
||||||
|
|
||||||
要求:
|
|
||||||
1. 保持函数签名不变
|
|
||||||
2. 至少引入一个创新性修改
|
|
||||||
3. 生成完整可运行的函数代码"""
|
|
||||||
result = self._call_llm(prompt, operator="mutation")
|
|
||||||
if result:
|
|
||||||
function_name = code.split("def ")[1].split("(")[0].strip()
|
|
||||||
return self.verify_code_format(result, function_name)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _clean_code(self, code: str) -> str:
|
def _clean_code(self, code: str) -> str:
|
||||||
"""清理LLM返回的代码,移除markdown标记"""
|
"""清理LLM返回的代码,移除markdown标记"""
|
||||||
return code.replace('```python', '').replace('```', '').strip()
|
return code.replace('```python', '').replace('```', '').strip()
|
||||||
@ -150,18 +77,4 @@ class LLMClient:
|
|||||||
return self._clean_code(code)
|
return self._clean_code(code)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"LLM调用失败:{str(e)}")
|
print(f"LLM调用失败:{str(e)}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_code_constraints(self) -> str:
|
|
||||||
"""获取代码约束提示词"""
|
|
||||||
return """
|
|
||||||
注意:
|
|
||||||
1. 请仅返回函数的实现代码,不要包含main函数或使用示例
|
|
||||||
2. 不要包含任何测试代码或调试输出
|
|
||||||
3. 不要包含任何注释说明或markdown标记
|
|
||||||
4. 确保代码可以直接运行,除了必要运行包之外,不要额外的导入语句
|
|
||||||
5. 确保所有导入的包或者函数一定存在,我不希望由于错误的导入造成import error
|
|
||||||
函数要求:
|
|
||||||
1. 主函数名:{function_name}
|
|
||||||
2. 输入:{input_fmt}
|
|
||||||
3. 返回:{output_fmt}"""
|
|
15
src/lead/core/operators/__init__.py
Normal file
15
src/lead/core/operators/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from .verify_operator import VerifyOperator
|
||||||
|
from .initialize_operator import InitializeOperator
|
||||||
|
from .crossover_operator import CrossoverOperator
|
||||||
|
from .mutation_operator import MutationOperator
|
||||||
|
from .de_crossover_operator import DECrossoverOperator
|
||||||
|
from .de_mutation_operator import DEMutationOperator
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'VerifyOperator',
|
||||||
|
'InitializeOperator',
|
||||||
|
'CrossoverOperator',
|
||||||
|
'MutationOperator',
|
||||||
|
'DECrossoverOperator',
|
||||||
|
'DEMutationOperator'
|
||||||
|
]
|
28
src/lead/core/operators/crossover_operator.py
Normal file
28
src/lead/core/operators/crossover_operator.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from ..llm_integration import LLMClient
|
||||||
|
from .verify_operator import VerifyOperator
|
||||||
|
|
||||||
|
class CrossoverOperator:
|
||||||
|
def __init__(self, llm_client: LLMClient):
|
||||||
|
self.llm_client = llm_client
|
||||||
|
self.verify_operator = VerifyOperator(llm_client)
|
||||||
|
|
||||||
|
def crossover(self, code1: str, code2: str) -> str:
|
||||||
|
"""代码交叉操作"""
|
||||||
|
prompt = f"""请将以下两个Python函数进行交叉操作,生成一个新的高效实现:
|
||||||
|
函数1:
|
||||||
|
{code1}
|
||||||
|
|
||||||
|
函数2:
|
||||||
|
{code2}
|
||||||
|
|
||||||
|
要求:
|
||||||
|
1. 保持函数签名不变
|
||||||
|
2. 结合两个实现的优点
|
||||||
|
3. 生成完整可运行的函数代码"""
|
||||||
|
code = self.llm_client._call_llm(prompt, operator="crossover")
|
||||||
|
if code:
|
||||||
|
# 从code1中提取函数名
|
||||||
|
function_name = code1.split("def ")[1].split("(")[0].strip()
|
||||||
|
return self.verify_operator.verify_code_format(code, function_name)
|
||||||
|
return None
|
35
src/lead/core/operators/de_crossover_operator.py
Normal file
35
src/lead/core/operators/de_crossover_operator.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from ..llm_integration import LLMClient
|
||||||
|
from .verify_operator import VerifyOperator
|
||||||
|
|
||||||
|
class DECrossoverOperator:
|
||||||
|
def __init__(self, llm_client: LLMClient):
|
||||||
|
self.llm_client = llm_client
|
||||||
|
self.verify_operator = VerifyOperator(llm_client)
|
||||||
|
|
||||||
|
def crossover(self, code: str) -> Optional[str]:
|
||||||
|
"""DE风格的交叉操作"""
|
||||||
|
prompt = f"""请将以下代码进行差分进化风格的交叉操作:
|
||||||
|
|
||||||
|
目标代码:
|
||||||
|
{code}
|
||||||
|
|
||||||
|
要求:
|
||||||
|
1. 保持函数签名不变
|
||||||
|
2. 使用差分进化的思想,对代码结构进行创新性重组
|
||||||
|
3. 尝试保留目标代码的优秀特性,同时引入新的改进
|
||||||
|
4. 生成的代码必须是完整可运行的函数
|
||||||
|
5. 避免过度复杂化,保持代码的可读性和效率
|
||||||
|
|
||||||
|
建议:
|
||||||
|
- 可以重组代码的核心算法部分
|
||||||
|
- 可以调整关键参数或阈值
|
||||||
|
- 可以优化数据结构的使用
|
||||||
|
- 可以改进算法的某些步骤"""
|
||||||
|
|
||||||
|
child_code = self.llm_client._call_llm(prompt, operator="crossover")
|
||||||
|
if child_code:
|
||||||
|
# 从code中提取函数名
|
||||||
|
function_name = code.split("def ")[1].split("(")[0].strip()
|
||||||
|
return self.verify_operator.verify_code_format(child_code, function_name)
|
||||||
|
return None
|
35
src/lead/core/operators/de_mutation_operator.py
Normal file
35
src/lead/core/operators/de_mutation_operator.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from ..llm_integration import LLMClient
|
||||||
|
from .verify_operator import VerifyOperator
|
||||||
|
|
||||||
|
class DEMutationOperator:
|
||||||
|
def __init__(self, llm_client: LLMClient):
|
||||||
|
self.llm_client = llm_client
|
||||||
|
self.verify_operator = VerifyOperator(llm_client)
|
||||||
|
|
||||||
|
def mutate(self, code: str) -> Optional[str]:
|
||||||
|
"""DE风格的变异操作"""
|
||||||
|
prompt = f"""请对以下代码进行差分进化风格的变异操作:
|
||||||
|
|
||||||
|
原始代码:
|
||||||
|
{code}
|
||||||
|
|
||||||
|
要求:
|
||||||
|
1. 保持函数签名不变
|
||||||
|
2. 引入差分变异的思想,对代码进行局部或全局的改进
|
||||||
|
3. 变异强度应该适中,不要完全改变算法的核心思想
|
||||||
|
4. 生成的代码必须是完整可运行的函数
|
||||||
|
5. 保持代码的可读性和效率
|
||||||
|
|
||||||
|
建议的变异操作:
|
||||||
|
- 调整算法中的关键参数
|
||||||
|
- 修改某些判断条件或循环结构
|
||||||
|
- 优化数据结构的使用方式
|
||||||
|
- 添加或移除某些优化步骤
|
||||||
|
- 改变算法某些部分的实现方法"""
|
||||||
|
|
||||||
|
mutated_code = self.llm_client._call_llm(prompt, operator="mutation")
|
||||||
|
if mutated_code:
|
||||||
|
function_name = code.split("def ")[1].split("(")[0].strip()
|
||||||
|
return self.verify_operator.verify_code_format(mutated_code, function_name)
|
||||||
|
return None
|
30
src/lead/core/operators/initialize_operator.py
Normal file
30
src/lead/core/operators/initialize_operator.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from ..llm_integration import LLMClient
|
||||||
|
from .verify_operator import VerifyOperator
|
||||||
|
|
||||||
|
class InitializeOperator:
|
||||||
|
def __init__(self, llm_client: LLMClient):
|
||||||
|
self.llm_client = llm_client
|
||||||
|
self.verify_operator = VerifyOperator(llm_client)
|
||||||
|
|
||||||
|
def generate_initial_code(self, problem_desc: str, function_name: str, input_fmt: str, output_fmt: str) -> str:
|
||||||
|
"""生成初始算法代码"""
|
||||||
|
prompt = f"""请用Python编写一个解决以下问题的函数:
|
||||||
|
问题描述:{problem_desc}
|
||||||
|
|
||||||
|
函数要求:
|
||||||
|
1. 函数名:{function_name}
|
||||||
|
2. 输入:{input_fmt}
|
||||||
|
3. 返回值:{output_fmt}
|
||||||
|
|
||||||
|
注意:
|
||||||
|
- 不需要添加类型注解
|
||||||
|
- 只返回函数代码,不要包含任何解释或测试用例
|
||||||
|
- 我们允许返回的代码中包含了多个函数,但是一定要确直接运行{function_name}函数并将数据传入即可完成全部流程并获得预期的返回
|
||||||
|
- 算法应该尽可能地创新,避免完全依赖已有的成熟算法,可以接受在成熟算法的基础上进行一定的修改
|
||||||
|
- 算法应该尽可能地简洁,避免不必要的复杂性
|
||||||
|
"""
|
||||||
|
code = self.llm_client._call_llm(prompt, operator="initialize")
|
||||||
|
if code:
|
||||||
|
return self.verify_operator.verify_code_format(code, function_name)
|
||||||
|
return None
|
23
src/lead/core/operators/mutation_operator.py
Normal file
23
src/lead/core/operators/mutation_operator.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from ..llm_integration import LLMClient
|
||||||
|
from .verify_operator import VerifyOperator
|
||||||
|
|
||||||
|
class MutationOperator:
|
||||||
|
def __init__(self, llm_client: LLMClient):
|
||||||
|
self.llm_client = llm_client
|
||||||
|
self.verify_operator = VerifyOperator(llm_client)
|
||||||
|
|
||||||
|
def mutate(self, code: str) -> str:
|
||||||
|
"""代码变异操作"""
|
||||||
|
prompt = f"""请对以下Python函数进行创新性改进:
|
||||||
|
{code}
|
||||||
|
|
||||||
|
要求:
|
||||||
|
1. 保持函数签名不变
|
||||||
|
2. 至少引入一个创新性修改
|
||||||
|
3. 生成完整可运行的函数代码"""
|
||||||
|
result = self.llm_client._call_llm(prompt, operator="mutation")
|
||||||
|
if result:
|
||||||
|
function_name = code.split("def ")[1].split("(")[0].strip()
|
||||||
|
return self.verify_operator.verify_code_format(result, function_name)
|
||||||
|
return None
|
22
src/lead/core/operators/verify_operator.py
Normal file
22
src/lead/core/operators/verify_operator.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from ..llm_integration import LLMClient
|
||||||
|
|
||||||
|
class VerifyOperator:
|
||||||
|
def __init__(self, llm_client: LLMClient):
|
||||||
|
self.llm_client = llm_client
|
||||||
|
|
||||||
|
def verify_code_format(self, code: str, function_name: str) -> Optional[str]:
|
||||||
|
"""验证代码格式是否符合要求"""
|
||||||
|
prompt = f"""请检查以下代码是否满足要求,如果不满足则进行修正:
|
||||||
|
{code}
|
||||||
|
|
||||||
|
要求:
|
||||||
|
1. 只包含函数实现代码,不包含任何说明、注释或示例
|
||||||
|
2. 主函数名必须为 {function_name}
|
||||||
|
3. 不包含main函数或测试代码
|
||||||
|
4. 只返回修正后的代码,不要包含任何其他内容
|
||||||
|
|
||||||
|
如果代码已经符合要求,直接返回原代码;如果需要修正,返回修正后的代码。"""
|
||||||
|
|
||||||
|
result = self.llm_client._call_llm(prompt, operator="verify")
|
||||||
|
return result if result else code
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"generation": 0,
|
||||||
|
"population": [
|
||||||
|
{
|
||||||
|
"code": "import random\n\ndef advanced_sort(arr):\n if len(arr) <= 1:\n return arr\n pivot = random.choice(arr)\n left = [x for x in arr if x < pivot]\n middle = [x for x in arr if x == pivot]\n right = [x for x in arr if x > pivot]\n return advanced_sort(left) + middle + advanced_sort(right)",
|
||||||
|
"fitness": 0.13097989559173584,
|
||||||
|
"generation": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import heapq\n\ndef advanced_sort(data):\n if len(data) < 100:\n return sorted(data)\n else:\n heap = []\n for i in range(0,len(data),100):\n sub_array = data[i:i+100]\n sub_array.sort()\n heapq.heappush(heap,(sub_array[0],sub_array))\n result = []\n while heap:\n smallest, sub_array = heapq.heappop(heap)\n result.append(sub_array.pop(0))\n if sub_array:\n heapq.heappush(heap,(sub_array[0],sub_array))\n return result",
|
||||||
|
"fitness": 0.07502323389053345,
|
||||||
|
"generation": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\n\ndef advanced_sort(arr):\n if len(arr) <= 1:\n return arr\n\n def partition(",
|
||||||
|
"fitness": Infinity,
|
||||||
|
"generation": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import heapq\n\ndef advanced_sort(arr):\n if len",
|
||||||
|
"fitness": Infinity,
|
||||||
|
"generation": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import heapq\nimport math\n\ndef advanced_sort(arr):",
|
||||||
|
"fitness": Infinity,
|
||||||
|
"generation": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"best_fitness": 0.07502323389053345,
|
||||||
|
"best_code": "import heapq\n\ndef advanced_sort(data):\n if len(data) < 100:\n return sorted(data)\n else:\n heap = []\n for i in range(0,len(data),100):\n sub_array = data[i:i+100]\n sub_array.sort()\n heapq.heappush(heap,(sub_array[0],sub_array))\n result = []\n while heap:\n smallest, sub_array = heapq.heappop(heap)\n result.append(sub_array.pop(0))\n if sub_array:\n heapq.heappush(heap,(sub_array[0],sub_array))\n return result",
|
||||||
|
"best_ever_fitness": 0.07502323389053345,
|
||||||
|
"best_ever_code": "import heapq\n\ndef advanced_sort(data):\n if len(data) < 100:\n return sorted(data)\n else:\n heap = []\n for i in range(0,len(data),100):\n sub_array = data[i:i+100]\n sub_array.sort()\n heapq.heappush(heap,(sub_array[0],sub_array))\n result = []\n while heap:\n smallest, sub_array = heapq.heappop(heap)\n result.append(sub_array.pop(0))\n if sub_array:\n heapq.heappush(heap,(sub_array[0],sub_array))\n return result"
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"generation": 1,
|
||||||
|
"population": [
|
||||||
|
{
|
||||||
|
"code": "import heapq\n\ndef advanced_sort(data):\n if len(data) < 16:\n data.sort()\n return data\n\n sub_array_size = 16\n sub_arrays = [data[i:i + sub_array_size] for i in range(0, len(data), sub_array_size)]\n \n for i in range(len(sub_arrays)):\n sub_arrays[i] = merge_sort(sub_arrays[i])\n\n heap = []\n for sub_array in sub_arrays:\n for item in sub_array:\n heapq.heappush(heap, item)\n\n return [heapq.heappop(heap) for _ in range(len(data))]\n\n\ndef merge_sort(arr):\n if len(arr) <= 1:\n return arr\n mid = len(arr) // 2\n left = merge_sort(arr[:mid])\n right = merge_sort(arr[mid:])\n result = []\n i = j = 0\n while i < len(left) and j < len(right):\n if left[i] < right[j]:\n result.append(left[i])\n i += 1\n else:\n result.append(right[j])\n j += 1\n result += left[i:]\n result += right[j:]\n return result",
|
||||||
|
"fitness": 0.11881619691848755,
|
||||||
|
"generation": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import heapq\n\ndef advanced_sort(data):\n if len(data) < 100:\n return sorted(data)\n else:\n heap = []\n for i in range(0,len(data),100):\n sub_array = data[i:i+100]\n sub_array.sort()\n heapq.heappush(heap,(sub_array[0],sub_array))\n result = []\n while heap:\n smallest, sub_array = heapq.heappop(heap)\n result.append(sub_array.pop(0))\n if sub_array:\n heapq.heappush(heap,(sub_array[0],sub_array))\n return result",
|
||||||
|
"fitness": 0.07924771308898926,
|
||||||
|
"generation": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\nimport heapq\n\ndef advanced_sort(arr):\n n = len(arr)\n if n <= 100:\n return sorted(arr)\n elif n <= 1000:\n is_nearly_sorted = all(arr[i] <= arr[i+1] for i in range(n-1))\n if is_nearly_sorted:\n return arr\n else:\n mid = n // 2\n left = advanced_sort(arr[:mid])\n right = advanced_sort(arr[mid:])\n return list(heapq.merge(left, right))\n else:\n max_recursion_depth = 2 * (n**0.5)\n recursion_depth = 0\n return _quicksort_with_limit(arr, max_recursion_depth",
|
||||||
|
"fitness": Infinity,
|
||||||
|
"generation": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(data):\n if len(data) <= 100:\n data.sort()\n return data\n \n num_subarrays = (len(data) + 99) // 100\n subarrays = [data[i*100:(i+1)*100] for i in range(num_subarrays)]\n for i in range(len(subarrays)):\n subarrays[i].sort()\n\n merged = []\n import heapq\n heap = []\n for i in range(len(subarrays)):\n if len(subarrays[i]) > 0:\n heapq.heappush(heap,(subarrays[i][0],i,0))\n\n while heap:\n val,arr_index,element_index = heapq.heappop(heap)\n merged.append(val)\n if element_index + 1 < len(subarrays[arr_index]):\n next_val = subarrays[arr_index][element_index+1]\n heapq.heappush(heap,(next_val,arr_index,element_index+1))\n\n return merged",
|
||||||
|
"fitness": 0.07207369804382324,
|
||||||
|
"generation": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(data):\n return sorted(data, key=lambda x: (len(x), x))",
|
||||||
|
"fitness": Infinity,
|
||||||
|
"generation": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"best_fitness": 0.07207369804382324,
|
||||||
|
"best_code": "def advanced_sort(data):\n if len(data) <= 100:\n data.sort()\n return data\n \n num_subarrays = (len(data) + 99) // 100\n subarrays = [data[i*100:(i+1)*100] for i in range(num_subarrays)]\n for i in range(len(subarrays)):\n subarrays[i].sort()\n\n merged = []\n import heapq\n heap = []\n for i in range(len(subarrays)):\n if len(subarrays[i]) > 0:\n heapq.heappush(heap,(subarrays[i][0],i,0))\n\n while heap:\n val,arr_index,element_index = heapq.heappop(heap)\n merged.append(val)\n if element_index + 1 < len(subarrays[arr_index]):\n next_val = subarrays[arr_index][element_index+1]\n heapq.heappush(heap,(next_val,arr_index,element_index+1))\n\n return merged",
|
||||||
|
"best_ever_fitness": 0.07207369804382324,
|
||||||
|
"best_ever_code": "def advanced_sort(data):\n if len(data) <= 100:\n data.sort()\n return data\n \n num_subarrays = (len(data) + 99) // 100\n subarrays = [data[i*100:(i+1)*100] for i in range(num_subarrays)]\n for i in range(len(subarrays)):\n subarrays[i].sort()\n\n merged = []\n import heapq\n heap = []\n for i in range(len(subarrays)):\n if len(subarrays[i]) > 0:\n heapq.heappush(heap,(subarrays[i][0],i,0))\n\n while heap:\n val,arr_index,element_index = heapq.heappop(heap)\n merged.append(val)\n if element_index + 1 < len(subarrays[arr_index]):\n next_val = subarrays[arr_index][element_index+1]\n heapq.heappush(heap,(next_val,arr_index,element_index+1))\n\n return merged"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user