【代码开发】RL框架和GA 求解器(solver)框架分别阐述
一、RL 训练框架
case_generator; data;
train、test、validate.
gym.env;
一边train 一边用当前模型验证validate来获得两条曲线
train curve和validate curve(反映模型优劣的)
二、GA 求解器(solver)框架”
照抄落地的文件结构 + 每个文件该放什么类/函数 + 互相怎么调用。
一、推荐目录结构(最少但够用)
project/
config.json
main_solve.py
main_batch.py
data/
valid/...
test/...
src/
init.py
io/
init.py
case_loader.py
sim/
init.py
decoder.py
model.py
ga/
init.py
chromosome.py
operators.py
solver.py
eval/
init.py
metrics.py
recorder.py
二、每个文件怎么定义(你照着写接口即可)
1)src/io/case_loader.py:只负责“读数据”
职责:把 case_path 读成统一的 Case 对象(你自己的数据结构)。
建议接口:
-
class CaseLoader:
-
load(case_path) -> Case
-
2)src/sim/model.py:系统与任务的数据结构(纯数据,不做搜索)
职责:定义你问题里的对象:订单、任务、资源(穿梭车、提升机)、距离/时间矩阵等。
建议放:
-
@dataclass Case:包含订单列表、站点、层、巷道、处理时间参数等
-
@dataclass Solution:一个 case 的解(订单序列 + 派车决策)
-
@dataclass SimResult:仿真输出(makespan、各资源时间线等)
3)src/sim/decoder.py:仿真/评估器(你已经写的 decode 就放这里)
职责:给定(Case + Solution)→ 推演 → makespan。
建议接口(最关键):
-
class Decoder:
-
evaluate(case: Case, sol: Solution) -> SimResult 或直接 float
-
(可选)validate(sol, case) -> bool(检查可行性)
说明:Decoder 不做 GA,不做随机搜索,只做“给你一个解,我算分”。
-
4)src/ga/chromosome.py:染色体表示(关键:case-specific)
职责:定义个体怎么存,怎么转成 Solution。
建议接口:
-
@dataclass Chromosome:
-
order_perm: list[int] # 订单ID排列(长度=该case订单数)
-
assign_gene: list[int] # 派车/提升机选择(长度同订单或同任务)
-
fitness: float | None
-
-
def to_solution(ch: Chromosome, case: Case) -> Solution
5)src/ga/operators.py:GA 操作算子(不依赖 decoder)
职责:初始化、选择、交叉、变异、修复。
建议函数:
-
init_population(case, pop_size, rng) -> list[Chromosome]
-
select(pop, k, rng) -> list[Chromosome]
-
crossover(p1, p2, rng) -> (c1, c2) (排序部分用OX/PMX;派车部分用均匀交叉)
-
mutate(ch, rng) -> Chromosome (排序用swap/insert;派车用随机重置)
-
repair(ch, case) -> Chromosome (保证排列合法、派车合法)
6)srcb:GA 主循环(唯一“搜索”所在)
职责:对单个 case 运行 GA,调用 decoder 计算适应度,返回最优解。
建议接口:
-
class GASolver:
-
init(ga_params, rng_seed)
-
solve(case: Case, decoder: Decoder) -> (best_sol: Solution, best_ms: float, curve: list[float])
-
evaluate_population(pop, case, decoder) -> None(写 fitness)
说明:GASolver 才知道“代数”“收敛曲线”。
-
7)src/eval/recorder.py:结果记录(Excel/CSV/图)
职责:把每个 case 的结果、曲线保存到文件。
建议接口:
-
class Recorder:
-
log_case_result(case_id, best_ms, run_time, curve)
-
save_summary(path)
-
save_curves(path)
你如果要保留 pandas 写 xlsx,就放这里。
-
三、文件之间怎么调用(调用链清晰到一眼可复现)
单个 case 求解(最核心流程)
main_solve.py:
-
loader = CaseLoader()
-
case = loader.load(case_path)
-
decoder = Decoder(sim_params)
-
ga = GASolver(ga_params, seed)
-
best_sol, best_ms, curve = ga.solve(case, decoder)
-
recorder.log_case_result(...)
批量 case(论文实验常用)
main_batch.py:
-
valid_paths = 列目录得到一批 case_path
-
for each case_path:
-
load case
-
run GA solve(通常每个 case 重复 R 次不同 seed)
-
统计 mean/std/min
-
-
输出表格 + 收敛曲线(单case或平均)
四、现在项目里应当删掉/彻底隔离的东西
-
gym、env.step、state、done、PPO_model、torch、visdom(除非只是用 visdom画图,但不建议混着)
-
“train/validate”命名建议改成:
-
solve(求解)
-
evaluate(评估)
-
convergence curve(收敛曲线)
-
五、现在最容易卡住的点:Solution 的统一定义
染色体两段:订单排序 + 派车选择。建议把 Solution 固定为:
-
order_sequence:订单ID列表(一个排列)
-
assignment:与订单一一对应的资源选择(穿梭车ID、提升机ID,或编码后的策略)
Decoder 只认 Solution,不直接读 Chromosome。这样后续你换编码方式,Decoder 不用动。
六、一个最小可跑的“主函数骨架”
可以直接按这个写 main_solve.py(不涉及具体业务细节):
from src.io.case_loader import CaseLoader from src.sim.decoder import Decoder from src.ga.solver import GASolver from src.eval.recorder import Recorder def main(): case_path = "./data/test/30_04_01/case_001.json" loader = CaseLoader() case = loader.load(case_path) decoder = Decoder() ga = GASolver(ga_params={"pop": 50, "gen": 200}, rng_seed=0) best_sol, best_ms, curve = ga.solve(case, decoder) rec = Recorder(out_dir="./results") rec.log_case_result(case_id=case.case_id, best_ms=best_ms, run_time=None, curve=curve) rec.save_summary("summary.xlsx") if __name__ == "__main__": main()
更多推荐


所有评论(0)