You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何导出OR-Tools CP-SAT的log_search_progress日志?

作业车间调度问题中CP-SAT求解器日志导出的C#实现方案

问题背景

使用C#开发环境,基于OR-Tools的CP-SAT求解器处理作业车间调度问题,需要将log_search_progress的日志内容导出到TXT文件,但现有尝试未成功。

当前求解代码

// Solve
CpSolver solver = new();

List<TaskWithSchedules> tasksToProcess = taskWithSchedules;

decimal timePerTask = _settingsCapacityPlan.AllowedSolverTimePerTaskInSeconds;

decimal solverLimit = timePerTask * tasksToProcess.Count;
// solver needs at least 3 seconds even with the smallest sets
int solverLimitInt = Math.Max((int)Math.Round(solverLimit, 1), 3);

List<string> solverParameters = new()
{
    string.Format("max_time_in_seconds: {0}.0", solverLimitInt),
    "log_search_progress:true",
    // "relative_gap_limit: 0.1"
};

solver.StringParameters = string.Join(",", solverParameters);
_log.Info($"Solver started");

// model.ExportToFile($"model_file_{solveIteration}.txt");

CpSolverStatus status = solver.Solve(model);

失败的尝试

曾尝试通过以下代码获取日志,但调试时log字符串始终为空:

string log;
solver.SetLogCallback((x) => log = x);

Python参考实现

Python中实现该功能较为简单:

solver = cp_model.CpSolver()
solver.parameters.log_search_progress = True

# Custom log function, for example, using the Python logging module instead of stdout
# Useful in a Jupyter notebook, where logging to stdout might not be visible
solver.log_callback = print  # (str)->None
# If using a custom log function, you can disable logging to stdout
solver.parameters.log_to_stdout = False

解决方案

C#版OR-Tools完全支持日志回调功能,问题出在日志的累计方式上,修正方案如下:

1. 用StringBuilder累计日志片段

回调函数会逐段输出日志内容,而非一次性返回完整日志,因此不能直接赋值覆盖,需要用StringBuilder追加内容:

// 初始化日志构建器
var logBuilder = new StringBuilder();

// 设置回调,逐段追加日志
solver.SetLogCallback((message) => 
{
    logBuilder.AppendLine(message);
    // 若求解时间长,可直接逐行写入文件避免内存占用过高
    // File.AppendAllText("solver_log.txt", message + Environment.NewLine);
});

2. 调整求解器参数(可选)

如果不想日志同时输出到控制台,可在参数列表中添加log_to_stdout:false:

List<string> solverParameters = new()
{
    string.Format("max_time_in_seconds: {0}.0", solverLimitInt),
    "log_search_progress:true",
    "log_to_stdout:false" // 关闭控制台日志输出
};

3. 求解完成后导出日志

求解结束后,将累计的日志写入TXT文件:

CpSolverStatus status = solver.Solve(model);
// 将日志写入文件
File.WriteAllText("solver_log.txt", logBuilder.ToString());

核心原因说明

原代码中log = x会每次覆盖之前的日志内容,而CP-SAT的日志回调是分多次调用的,每次传入一段日志片段,因此必须通过累计的方式收集完整日志。

内容的提问来源于stack exchange,提问作者PeterK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:42:42