重构框架,提高复用性,算子拆分,代码可读性提高

This commit is contained in:
deastern 2025-04-15 02:35:39 +08:00
parent 5f7b5ef822
commit 8e5a4710d6
14 changed files with 337 additions and 145 deletions

61
.gitignore vendored Normal file
View 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

View File

@ -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

View File

@ -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]

View File

@ -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]

View File

@ -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}"""

View 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'
]

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -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"
}

View File

@ -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"
}