我正在为pydrake MathematicalProgram对象使用MathematicalProgram功能,尝试并制作一个进度条,在求解程序运行时可以更新,这样我就可以看到我的解决程序是如何工作的,而不必查看来自SNOPT的过于冗长的输出( BTW无法打印到控制台,只能进行文件)。我的方法是这样的:
import pydrake.solvers.mathematicalprogram as mp
from tqdm import tqdm
prog = mp.MathematicalProgram()
pbar = tqdm(total=max_iterations)
def update(x):
pbar.update(1)
prog.AddVisualizationCallback(update, x)但是,我的问题是SNOPT有主迭代和次迭代,而且似乎我的update回调被调用了,而不管它是大写还是次要的。理想情况下,我希望它只在主要的迭代中被调用,否则我的进度条将比它应该填充的时间更快。
我的问题是:是否有一种方法可以判断特定的迭代是SNOPT的主要迭代还是次要迭代,这样我就可以将这些信息提供给我的update回调,并且只在主要的迭代中更新进度条?或者,我可以将其设置为只在主要迭代时调用可视化回调吗?
发布于 2022-01-07 21:59:33
我使用SNOPT编写的日志文件成功地破解了一个解决方案:
from tqdm import tqdm
import pydrake.solvers.mathematicalprogram as mp
from pydrake.solvers.snopt import SnoptSolver
prog = mp.MathematicalProgram()
fmax_iterations = 20
log_filename = '/tmp/snopt.out'
log = open(log_filename, 'w+')
pbar = tqdm(total=max_iterations)
def update(x):
lines = log.read()
if 'Itns Major Minors' in lines:
idx = lines.rfind('Itns Major Minors')
header, info = lines[idx:].split('\n')[:2]
for name, val in zip(header.split(), info.split()):
if name == 'Major':
pbar.n = int(val)
pbar.refresh()
break
prog.AddVisualizationCallback(update, x)
solver_options = mp.SolverOptions()
solver_options.SetOption(mp.CommonSolverOption.kPrintFileName, log_filename)
solver_options.SetOption(SnoptSolver.id(), "Major iterations limit", max_iterations)
solver_options.SetOption(SnoptSolver.id(), "Print frequency", 1)
result = mp.Solve(prog, solver_options=solver_options)
pbar.n = max_iterations
pbar.refresh()
pbar.close()
log.close()这给了我一个很好的进度条,而SNOPT解决程序在运行时并没有实际打印到它的日志文件中的所有杂乱:
40%|██████████████▍ | 8/20 [00:07<00:11, 1.07it/s]如果在回调函数中有一个程序钩子连接到求解器上,那就更好了,也许这是可能的?除此之外,这似乎能胜任这项工作。
https://stackoverflow.com/questions/70626026
复制相似问题