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

Python调用外部耗时函数时如何展示程序运行状态?

可行解决方案

1. 动态旋转光标/状态动画

不需要任何进度预估信息,纯视觉反馈,通过不断刷新控制台同一行来展示动态效果,明确告知用户程序未卡死。

示例代码:

import sys
import time
import threading
from pyomo.environ import ConcreteModel, Var, Objective, Constraint, SolverFactory, Integers

def spinning_cursor():
    while not stop_event.is_set():
        for cursor in '|/-\\':
            sys.stdout.write(f'\r求解中 {cursor}')
            sys.stdout.flush()
            time.sleep(0.2)

# 替换为你的实际模型
model = ConcreteModel()
model.x = Var(within=Integers)
model.obj = Objective(expr=model.x**2)
model.con = Constraint(expr=model.x >= 100000)

# 创建线程停止控制事件
stop_event = threading.Event()
# 启动动画线程
status_thread = threading.Thread(target=spinning_cursor)
status_thread.start()

# 调用Gurobi求解器,关闭冗余输出
solver = SolverFactory('gurobi')
solver.options['OutputFlag'] = 0
results = solver.solve(model)

# 停止动画线程并清理输出
stop_event.set()
sys.stdout.write('\r求解完成!\n')
sys.stdout.flush()

2. 利用Gurobi回调函数捕获求解状态

Gurobi支持自定义回调函数,即使关闭了默认输出,也能通过回调定期获取求解的中间状态(节点数、最优界等),既能给用户反馈,还能提供有价值的求解进度信息。

示例代码:

from pyomo.environ import ConcreteModel, Var, Objective, Constraint, SolverFactory, Integers
from gurobipy import GRB
import time

def gurobi_status_callback(model, where):
    global last_print_timestamp
    current_time = time.time()
    # 每隔5秒输出一次状态,或在找到新可行解时更新
    if (where == GRB.Callback.MIPSOL or where == GRB.Callback.NODE) and current_time - last_print_timestamp >= 5:
        node_count = model.cbGet(GRB.Callback.NODECOUNT)
        obj_bound = model.cbGet(GRB.Callback.BOUND)
        current_obj = model.cbGet(GRB.Callback.OBJBST) if where == GRB.Callback.MIPSOL else "暂未找到可行解"
        print(f'\r当前节点数: {node_count} | 最优界: {obj_bound:.2f} | 当前可行解目标值: {current_obj:.2f}', end='')
        last_print_timestamp = current_time

# 替换为你的实际模型
model = ConcreteModel()
model.x = Var(within=Integers)
model.obj = Objective(expr=model.x**2)
model.con = Constraint(expr=model.x >= 100000)

solver = SolverFactory('gurobi')
solver.options['OutputFlag'] = 0
last_print_timestamp = time.time()

# 传递回调函数求解
results = solver.solve(model, callback=gurobi_status_callback)

print('\r求解完成!最终目标值:', model.obj())

3. 后台定时心跳输出

如果不想依赖求解器的回调机制,可启动一个后台线程,每隔固定时间输出心跳信息,避免控制台长时间无输出导致用户误以为程序崩溃。

示例代码:

import threading
import time
import sys
from pyomo.environ import ConcreteModel, Var, Objective, Constraint, SolverFactory, Integers

def heartbeat_notify():
    while not stop_event.is_set():
        sys.stdout.write('\r程序正在求解,请稍候...')
        sys.stdout.flush()
        time.sleep(3)

# 替换为你的实际模型
model = ConcreteModel()
model.x = Var(within=Integers)
model.obj = Objective(expr=model.x**2)
model.con = Constraint(expr=model.x >= 100000)

stop_event = threading.Event()
heartbeat_thread = threading.Thread(target=heartbeat_notify)
heartbeat_thread.start()

# 执行求解
solver = SolverFactory('gurobi')
solver.options['OutputFlag'] = 0
results = solver.solve(model)

# 停止心跳线程并更新输出
stop_event.set()
sys.stdout.write('\r求解完成!\n')
sys.stdout.flush()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:50:20