[英]Writing COIN-OR CBC Log File
我正在使用 COIN-OR 的 CBC 求解器來解決一些數值優化問題。 我正在通過 PuLP 在 Python 中構建優化問題。
我注意到像 GUROBI 和 CPLEX 這樣的求解器會創建日志文件,但我似乎無法弄清楚如何讓 CBC 創建日志文件(而不是將優化器的進度打印到屏幕上)。
有人知道 CBC 中設置日志文件的選項嗎? 將所有標准輸出重定向到一個文件對我來說不起作用,因為我正在並行解決一堆問題並希望將它們的日志文件分開。
這是我如何調用求解器的示例。 這很好用,並將進度打印到終端。
prob.solve(pulp.COIN_CMD(msg=1, options=['DivingVectorlength on','DivingSome on']))
這是我認為應該如何構建解決方案的方式(盡管顯然LogFileName不是有效的 CBC 選項)。
prob.solve(pulp.COIN_CMD(msg=1, options=['DivingVectorlength on', 'DivingSome on', 'LogFileName stats.log']))
對此的任何幫助將不勝感激。 幾個小時以來,我一直在瀏覽互聯網、文檔和 CBC 互動會議,試圖弄清楚這一點。
我無法在不更改pulp
源代碼的情況下找到答案,但如果這不打擾您,那么請走以下路線:
導航到您的紙漿安裝庫的目錄並查看solvers.py
文件。
感興趣的功能是solve_CBC
在COIN_CMD
類。 在該方法中,參數形成單個命令傳遞給cbc-64
求解器程序,然后使用subprocess.Popen
方法調用它。 此方法的stdout
參數要么設置為None
要么os.devnull
對我們來說都不是很有用。 您可以在第 1340 行(對於 PuLP 1.5.6)看到進程調用。
cbc = subprocess.Popen((self.path + cmds).split(), stdout = pipe,
stderr = pipe)
該來源還揭示了問題 (mps) 和解決方案 (sol) 文件被寫入/tmp
目錄(在 UNIX 機器上),並且文件名包括調用它的解釋器的pid
。 我使用這個 id 打開一個文件並將它傳遞給那個參數。 像這樣:
logFilename = os.path.join(self.tmpDir, "%d-cbc.log" % pid)
logFile = open(logFilename, 'a')
cbc = subprocess.Popen((self.path + cmds).split(), stdout = logFile,
stderr = pipe)
果然,運行后在/tmp
目錄下看到了我的日志文件。 您可以使用log N
設置詳細程度,請參閱 cbc 幫助以獲取更多文檔。 由於這會為每個進程 ID 創建一個不同的文件,我認為它將解決您並行運行多個求解器的問題。
有關在調用 PuLP 和 CBC 的腳本中只需要幾行代碼的解決方案,請參閱 James Vogel( https://github.com/voglster ,也許)在https://groups.google.com/forum 上的解決方案/#!topic/pulp-or-discuss/itbmTC7uNCQ ,基於os.dup()
和os.dup2()
。
我希望將它復制到這里以防止鏈接腐爛不是不合適的,但是請參閱原始帖子以獲取逐行解釋以及我從 tempfile 包中不了解的一些復雜內容。 我自己的用法不太復雜,使用實際的永久文件名:
from os import dup, dup2, close
f = open('capture.txt', 'w')
orig_std_out = dup(1)
dup2(f.fileno(), 1)
status = prob.solve (PULP_CBC_CMD(maxSeconds = i_max_sec, fracGap = d_opt_gap, msg=1)) # CBC time limit and relative optimality gap tolerance
print('Completion code: %d; Solution status: %s; Best obj value found: %s' % (status, LpStatus[prob.status], value(prob.objective)))
dup2(orig_std_out, 1)
close(orig_std_out)
f.close()
這會在當前目錄中的capture.txt
中為您留下有用的信息。
重用@Mike 的答案,PuLP(自 2.2 起)現在包括通過將logPath
參數與要寫入的文件的路徑一起傳遞來將日志寫入文件的可能性。
所以你現在可以這樣做:
prob.solve(pulp.COIN_CMD(msg=1, logPath="stats.log", options=['DivingVectorlength on', 'DivingSome on']))
唯一的警告是您不能再“在屏幕上”看到它,因為它將輸出重定向到文件。 在這種情況下,您不需要提供msg=1
,只需提供logPath
。
logPath
參數在以下幾個求解器中是一致的(在 PuLP >= 2.2 中):PULP_CBC_CMD、COIN_CMD、PULP_COIN_CMD、GUROBI、CPLEX、CPLEX_CMD、GUROBI_CMD。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.