From f576f8d02ee68e150b796b996907fbecfafdcf26 Mon Sep 17 00:00:00 2001 From: yangyudong <916291030@qq.com> Date: Wed, 16 Apr 2025 01:32:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme=EF=BC=8C=E5=B0=86mc?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=BF=AE=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=A4=9A=E7=9B=AE=E6=A0=87=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 86 ++++++++++++++++++- src/lead/problems/mc/evaluation.py | 23 +++-- .../problems/mc/multi_objective_evolution.log | 1 + .../20250416_010845/generation_0.json | 83 ++++++++++++++++++ src/lead/problems/mc/problem_config.json | 4 +- 5 files changed, 185 insertions(+), 12 deletions(-) create mode 100644 src/lead/problems/mc/multi_objective_evolution.log create mode 100644 src/lead/problems/mc/multi_objective_history/20250416_010845/generation_0.json diff --git a/README.md b/README.md index 3f16d4f..07a327a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,85 @@ -# lead +# LEAD (LLM-Evolved Algorithm Development) -llm驱动的算法开发流程 \ No newline at end of file +LLM驱动的算法进化开发框架,支持单目标和多目标优化问题的算法自动进化。 + +## 单目标算法进化 + +### 1. 配置要求 +在问题目录下的`problem_config.json`中配置: +```json +{ + "multi_objective": false, + "description": "问题描述", + "function_name": "函数名", + "input_format": "输入格式", + "output_format": "输出格式", + "evolution_params": { + "algorithm": "TU", # 或"DE" + "population_size": 8, + "generations": 10 + } +} +``` + +### 2. 运行流程 +1. 初始化种群:LLM根据问题描述生成初始算法代码 +2. 评估:计算每个个体的适应度(单目标值) +3. 进化循环: + - 选择:锦标赛选择或差分进化选择 + - 交叉:代码片段重组 + - 变异:LLM引导的代码变异 +4. 输出:最优算法代码和适应度曲线 + +### 3. 运行命令 +```bash +lead-run --problem [问题名] [--generations 代数] [--population 种群大小] +``` +可选参数: +- `--generations`: 覆盖默认进化代数 +- `--population`: 覆盖默认种群大小 + +## 多目标算法进化 + +### 1. 配置要求 +```json +{ + "multi_objective": true, + "objective_names": ["目标1", "目标2"], + "description": "问题描述", + "evolution_params": { + "algorithm": "MO", + "population_size": 10, + "generations": 20 + } +} +``` + +### 2. 运行流程 +1. 初始化种群:LLM生成初始多目标算法 +2. 评估:计算每个个体的多目标适应度向量 +3. 进化循环: + - 非支配排序 + - 拥挤度计算 + - 精英保留 +4. 输出:Pareto前沿算法集合 + +### 3. 运行命令 +```bash +lead-run --problem [问题名] [--generations 代数] [--population 种群大小] +``` +可选参数同上 + +## 配置说明 + +- `problem_config.json`必须包含: + - 问题描述 + - 输入输出格式 + - 进化参数 +- 可选配置: + - LLM参数 + - 评估超时时间 + +## 结果输出 + +- 单目标:`evolution_history/[时间戳]/`目录保存各代最优解 +- 多目标:`multi_objective_history/[时间戳]/`保存Pareto前沿 \ No newline at end of file diff --git a/src/lead/problems/mc/evaluation.py b/src/lead/problems/mc/evaluation.py index 784016a..9df18de 100644 --- a/src/lead/problems/mc/evaluation.py +++ b/src/lead/problems/mc/evaluation.py @@ -2,16 +2,18 @@ import numpy as np import time from typing import Callable, Dict -def evaluate(coloring_func: Callable[[np.ndarray], np.ndarray], adj_matrix: np.ndarray) -> float: - """评估图着色算法的性能 +def evaluate(coloring_func: Callable[[np.ndarray], np.ndarray], adj_matrix: np.ndarray) -> Dict[str, float]: + """评估图着色算法的多目标性能 Args: coloring_func: 图着色函数 adj_matrix: 图的邻接矩阵 Returns: - float: 适应度分数 = 运行时间 * 使用的颜色数 - 如果解不合法(存在相邻节点同色)则返回无穷大 + Dict[str, float]: 包含两个目标值的字典: + - color_count: 使用的颜色数量 + - execution_time: 运行时间(秒) + 如果解不合法(存在相邻节点同色)则返回无穷大 """ try: # 计时并执行图着色 @@ -26,17 +28,20 @@ def evaluate(coloring_func: Callable[[np.ndarray], np.ndarray], adj_matrix: np.n for j in range(n): if adj_matrix[i][j] == 1 and colors[i] == colors[j]: print(f"非法解:节点{i}和{j}相邻但颜色相同") - return float('inf') + return { + "color_count": float('inf'), + "execution_time": float('inf') + } # 计算使用的颜色数 num_colors = len(set(colors)) - # 计算适应度分数 - fitness = num_colors + execution_time print(f"执行时间:{execution_time:.4f}秒, 使用颜色数:{num_colors}") - # print(f"适应度分数:{fitness:.4f}") - return num_colors + return { + "color_count": num_colors, + "execution_time": execution_time + } except Exception as e: print(f"评估过程出错: {str(e)}") diff --git a/src/lead/problems/mc/multi_objective_evolution.log b/src/lead/problems/mc/multi_objective_evolution.log new file mode 100644 index 0000000..ed3dfe6 --- /dev/null +++ b/src/lead/problems/mc/multi_objective_evolution.log @@ -0,0 +1 @@ +Generation 0000 | Pareto Front Size: 1 | Timestamp: 2025-04-16T01:20:59.478238 diff --git a/src/lead/problems/mc/multi_objective_history/20250416_010845/generation_0.json b/src/lead/problems/mc/multi_objective_history/20250416_010845/generation_0.json new file mode 100644 index 0000000..3d68bce --- /dev/null +++ b/src/lead/problems/mc/multi_objective_history/20250416_010845/generation_0.json @@ -0,0 +1,83 @@ +{ + "generation": 0, + "population": [ + { + "code": "import numpy as np\n\ndef graph_coloring(adj_matrix):\n n = adj_matrix.shape[0]\n colors = [-1] * n\n available = [False] * n\n \n def get_neighbor_colors(node):\n for neighbor in range(n):\n if adj_matrix[node][neighbor] == 1 and colors[neighbor] != -1:\n available[colors[neighbor]] = True\n\n def assign_color(node):\n get_neighbor_colors(node)\n color = 0\n while color < n:\n if not available[color]:\n colors[node] = color\n break\n color += 1\n for neighbor in range(n):\n if adj_matrix[node][neighbor] == 1 and colors[neighbor] != -1:\n available[colors[neighbor]] = False\n \n for node in range(n):\n if colors[node] == -1:\n assign_color(node)\n available = [False] * n\n\n return colors", + "generation": 0, + "fitnesses": { + "color_count": 31, + "execution_time": 1.0018470287322998 + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = adj_matrix.shape[0]\n colors = [-1] * n\n \n vertex_order = list(range(n))\n random.shuffle(vertex_order)\n \n for vertex in vertex_order:\n available_colors = [True] * n\n for neighbor in range(n):\n if adj_matrix[vertex][neighbor] == 1 and colors[neighbor] != -1:\n available_colors[colors[neighbor]] = False\n \n color = 0\n while color < n and not available_colors[color]:\n color += 1\n \n colors[vertex] = color\n \n return colors", + "generation": 0, + "fitnesses": { + "color_count": 32, + "execution_time": 1.5306849479675293 + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = len(adj_matrix)\n colors = [-1] * n\n available_colors = [True] * n\n\n def greedy_coloring():\n colors[0] = 0\n\n for u in range(1, n):\n available_colors[:] = [True] * n\n \n for v in range(n):\n if adj_matrix[u][v] == 1 and colors[v] != -1:\n available_colors[colors[v]] = False\n \n for color in range(n):\n if available_colors[color]:\n colors[u] = color\n break\n\n greedy_coloring()\n \n def optimize_colors():\n color_count = max(colors) + 1\n color_mapping = {i: [] for i in range(color_count)}\n \n for vertex in range(n):\n if colors[vertex] != -1:\n color_mapping[colors[vertex]].append(vertex)\n \n for color in range(color_count):\n if not color_mapping[color]:\n continue\n for new_color in range(color + 1, color_count):\n if new_color not in color_mapping:\n continue\n is_codable = True\n for v1 in color_mapping[color]:\n for v2 in color_mapping[new_color]:\n if adj_matrix[v1][v2] == 1:\n is_codable = False\n break\n if not is_codable:\n break\n if is_codable:\n for v in color_mapping[new_color]:\n colors[v] = color\n del color_mapping[new_color]\n break\n\n optimize_colors()\n \n return colors", + "generation": 0, + "fitnesses": { + "color_count": 31, + "execution_time": 1.539431095123291 + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = len(adj_matrix)\n colors = [-1] * n\n available_colors = [False] * n\n \n def find_available_color(vertex):\n for i in range(n):\n available_colors[i] = True\n \n for neighbor in range(n):\n if adj_matrix[vertex][neighbor] == 1 and colors[neighbor] != -1:\n available_colors[colors[neighbor]] = False\n \n for color in range(n):\n if available_colors[color]:\n return color\n return n\n\n for vertex in range(n):\n colors[vertex] = find_available_color(vertex)\n \n def optimize_coloring():\n unique_colors = sorted(set(colors))\n color_map = {old_color: new_color for new_color, old_color in enumerate(unique_colors)}\n for i in range(n):\n colors[i] = color_map[colors[i]]\n\n optimize_coloring()\n \n return colors", + "generation": 0, + "fitnesses": { + "color_count": 31, + "execution_time": 2.813322067260742 + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = adj_matrix.shape[0]\n colors = [-1] * n\n \n def get_available_colors(vertex):\n available_colors = [True] * n\n for neighbor in range(n):\n if adj_matrix[vertex][neighbor] == 1 and colors[neighbor] != -1:\n available_colors[colors[neighbor]] = False\n return available_colors\n\n vertex_order = list(range(n))\n random.shuffle(vertex_order)\n \n for vertex in vertex_order:\n available_colors = get_available_colors(vertex)\n \n color = 0\n while color < n and not available_colors[color]:\n color += 1\n \n if color == n:\n min_color_used = min([c for c in colors if c != -1], default=0)\n color = min_color_used + 1\n \n colors[vertex] = color\n \n return colors", + "generation": 0, + "fitnesses": { + "color_count": 31, + "execution_time": 2.3673529624938965 + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = adj_matrix.shape[0]\n colors = [-1] * n\n available_colors = [True] * n\n \n def assign_colors():\n for node in range(n):\n if colors[node] == -1:\n reset_available()\n for neighbor in range(n):\n if adj_matrix[node][neighbor] == 1 and colors[neighbor] != -1:\n available_colors[colors[neighbor]] = False\n colors[node] = get_first_available_color()\n \n def reset_available():\n for i in range(n):\n available_colors[i] = True\n\n def get_first_available_color():\n for color in range(n):\n if available_colors[color]:\n return color\n return n\n\n def local_search():\n for node in range(n):\n current_color = colors[node]\n for try_color in range(n):\n if try_color != current_color and is_valid_color_assignment(node, try_color):\n colors[node] = try_color\n break\n\n def is_valid_color_assignment(node, color):\n for neighbor in range(n):\n if adj_matrix[node][neighbor] == 1 and colors[neighbor] == color:\n return False\n return True\n\n assign_colors()\n \n for _ in range(n):\n local_search()\n \n return colors", + "generation": 0, + "fitnesses": { + "color_count": Infinity, + "execution_time": Infinity + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = len(adj_matrix)\n colors = [-1] * n\n available_colors = [True] * n\n\n def is_color_possible(vertex, color):\n for neighbor in range(n):\n if adj_matrix[vertex][neighbor] == 1 and colors[neighbor] == color:\n return False\n return True\n\n def greedy_coloring():\n for vertex in range(n):\n available_colors[:] = [True] * n\n for neighbor in range(n):\n if adj_matrix[vertex][neighbor] == 1 and colors[neighbor] != -1:\n available_colors[colors[neighbor]] = False\n for color in range(n):\n if available_colors[color]:\n colors[vertex] = color\n break\n \n greedy_coloring()\n\n def local_search():\n improved = True\n while improved:\n improved = False\n for vertex in range(n):\n current_color = colors[vertex]\n conflict_colors = set()\n for neighbor in range(n):\n if adj_matrix[vertex][neighbor] == 1:\n conflict_colors.add(colors[neighbor])\n for new_color in range(len(conflict_colors) + 1):\n if new_color not in conflict_colors:\n if new_color != current_color:\n colors[vertex] = new_color\n improved = True\n break\n\n local_search()\n\n return colors", + "generation": 0, + "fitnesses": { + "color_count": Infinity, + "execution_time": Infinity + } + }, + { + "code": "import numpy as np\nimport random\n\ndef graph_coloring(adj_matrix):\n n = len(adj_matrix)\n colors = [-1] * n\n available_colors = [True] * n\n\n def greedy_coloring():\n colors[0] = 0\n\n for u in range(1, n):\n available_colors[:] = [True] * n\n \n for v in range(n):\n if adj_matrix[u][v] == 1 and colors[v] != -1:\n available_colors[colors[v]] = False\n \n for color in range(n):\n if available_colors[color]:\n colors[u] = color\n break\n\n greedy_coloring()\n \n def optimize_colors():\n color_count = max(colors) + 1\n color_mapping = {i: [] for i in range(color_count)}\n \n for vertex in range(n):\n if colors[vertex] != -1:\n color_mapping[colors[vertex]].append(vertex)\n \n merged = True\n while merged:\n merged = False\n for color in range(color_count):\n if not color_mapping[color]:\n continue\n for new_color in range(color + 1, color_count):\n if new_color not in color_mapping:\n continue\n is_codable = True\n for v1 in color_mapping[color]:\n for v2 in color_mapping[new_color]:\n if adj_matrix[v1][v2] == 1:\n is_codable = False\n break\n if not is_codable:\n break\n if is_codable:\n for v in color_mapping[new_color]:\n colors[v] = color\n del color_mapping[new_color]\n merged = True\n color_count -= 1\n break\n if merged:\n break\n\n optimize_colors()\n \n return colors", + "generation": 0, + "fitnesses": { + "color_count": 31, + "execution_time": 2.5284109115600586 + } + } + ], + "pareto_front": [ + { + "code": "import numpy as np\n\ndef graph_coloring(adj_matrix):\n n = adj_matrix.shape[0]\n colors = [-1] * n\n available = [False] * n\n \n def get_neighbor_colors(node):\n for neighbor in range(n):\n if adj_matrix[node][neighbor] == 1 and colors[neighbor] != -1:\n available[colors[neighbor]] = True\n\n def assign_color(node):\n get_neighbor_colors(node)\n color = 0\n while color < n:\n if not available[color]:\n colors[node] = color\n break\n color += 1\n for neighbor in range(n):\n if adj_matrix[node][neighbor] == 1 and colors[neighbor] != -1:\n available[colors[neighbor]] = False\n \n for node in range(n):\n if colors[node] == -1:\n assign_color(node)\n available = [False] * n\n\n return colors", + "generation": 0, + "fitnesses": { + "color_count": 31, + "execution_time": 1.0018470287322998 + } + } + ], + "objective_names": [ + "color_count", + "execution_time" + ] +} \ No newline at end of file diff --git a/src/lead/problems/mc/problem_config.json b/src/lead/problems/mc/problem_config.json index 0adbc46..bea909a 100644 --- a/src/lead/problems/mc/problem_config.json +++ b/src/lead/problems/mc/problem_config.json @@ -3,6 +3,8 @@ "function_name": "graph_coloring", "input_format": "一个numpy数组adj_matrix,表示图的邻接矩阵(n×n的0-1整数矩阵,1表示两点相连,0表示不相连)", "output_format": "返回一个长度为n的整数数组colors,表示每个顶点的颜色编号(从0开始的整数)", + "multi_objective": true, + "objective_names": ["color_count", "execution_time"], "evaluation_timeout": 120, "llm_config": { "api_key": "sk-5wHuJRuC2KDMINeYERru0zCCMrRTzmkrOMwpvBQr4EULV0Tv", @@ -12,7 +14,7 @@ "max_tokens": 8192 }, "evolution_params": { - "algorithm": "TU", + "algorithm": "MO", "population_size": 8, "generations": 10, "mutation_rate": 0.5,