如何在 VSCode 中配置和編寫 LINGO

多玩我的世界盒子發表於2024-04-24

目錄
  • 如何在 VSCode 中配置和編寫 LINGO
    • 安裝 VSCode 擴充套件
    • LINGO 指令碼檔案與 runlingo 命令
    • LINGO 命令列互動和指令碼檔案
    • 配置 Visual Stdio Code 的設定
      • 配置 LTF 檔案的程式碼高亮
    • 關於檔案相容的一些小問題

如何在 VSCode 中配置和編寫 LINGO

LINGO 是用來解決最佳化問題的一個特別好用的軟體,可以快速求解線性規劃、非線性規劃、線性和非線性方程組等規劃問題。,LINGO 好處多多確實很方便,但是 LINGO 18.0 原生的 IDE 不能說依託答辯吧,只能說慘不忍睹:無論是冷戰風格的遠古介面還是一寫註釋就會混亂的程式碼高亮,以及相容性奇差無比的富文字支援,都讓我這種賽博顏狗感到滿滿的惡意。按照我的理解和猜測,包括我在內的很多人都會強勢訴諸於其他的程式碼編輯器,比如 Visual Stdio Code。

image

但是與此同時,當你在網上一搜尋,就會發現全網際網路上找不出幾個關於怎麼在 VSCode 裡面配置和使用 LINGO 的教程。畢竟,確實,真到了解決大型複雜工程學規劃問題的時候有 MATLAB、GurobiSCIP 等一大眾高階貨色,再怎麼也不會真拿 LINGO 去求解。沒有辦法,只能自己動手豐衣足食了。

本教程將教會你如何一步一步在 VSCode 中配置自己的 LINGO IDE。

安裝 VSCode 擴充套件

首先,VSCode 上面確實有一個 Lingo language support 的擴充套件,而且根據我的嘗試,所有的擴充套件裡面只有這一個擴充套件是靠譜的。(其他的擴充套件不要安裝。有些是 lingoJS 的擴充套件,有些半身不遂,會把檔案高亮覆蓋掉。)我們首先把這個擴充套件安裝上。

安裝好擴充套件之後,可以看到模型檔案已經擁有了還算不錯的高亮可以看。但是仍然不能一鍵執行求解模型。

image

對於程式碼的自動執行,我們需要安裝 Code Runner 外掛 並進行自動化配置。自動化配置的具體流程我們會在下面的文章裡面跟大家介紹。

LINGO 指令碼檔案與 runlingo 命令

查閱 LINGO 的幫助文件可以發現 LINGO 的幫助文件裡面提及了一個名為 RunLingo 的程式。找到這樣一段描述,我翻譯了一下:

LINGO的Windows版本包括一個名為RunLingo的實用程式。RunLingo可以用於處理LINGO指令碼檔案,但是,RunLingo不包括LINGO互動式版本中的前端圖形介面。RunLingo是從命令列呼叫的,您可以在命令列中輸入指令碼檔名。RunLingo將其輸出寫入標準輸出裝置。RunLingo在生產環境中非常有用——如果您希望LINGO作為更大規劃系統的一部分在後臺安靜地執行。

嘗試在命令列終端中輸入 runlingo 命令:

 $ runlingo

Enter "runlingo script_file_path" to execute the
LINGO command script in file script_file_path.

可以看見 runlingo 命令已經在 LINGO 安裝時被新增到了環境變數,這個時候已經可以直接呼叫了,使用方法為:

runlingo <指令碼檔名>.ltf

如果在程式安裝的時候,出於某些原因 runlingo 沒有被正常新增到環境變數導致命令無法執行,可能需要手動新增。手動新增環境變數的方法請自行在網上搜尋。

LINGO 命令列互動和指令碼檔案

RunLingo 不能直接執行常見的 LINGO 模型檔案(.lg4 或者 .lng 之類的)。相反,它直接執行的是 LINGO 的指令碼檔案 .ltf 格式。關於 .ltf 檔案 LINGO 官方文件裡面 [有相應的解釋可以在這個連結裡檢視](LINGO 15 Online Users Manual。簡單的來講:.ltf 檔案裡面編寫的是 LINGO 的互動命令。由於 LINGO 命令列互動對大多數人來講都很陌生、很少使用,因此我們這裡解釋一下:

在 LINGO 主介面標籤欄下依次點選 WindowCommand Window 可以開啟命令列圖窗,輸入 COM 檢視可用的命令:

: COM

 LINGO commands by category.  For information on a specific command, type:
 'HELP command-name'.

   1) Information
      COM     CAT     HELP    MEM

   2) Input
      MODEL   TAKE    RMPS    FRMPS   RMPI    RLPF

   3) Display
      LOOK    GEN     PAUS    HIDE    STATS   PICTURE DUAL    XDETEQ  SCENE
      SHOWNL  LISTFIX

   4) File Output
      DIV     RVRT    SAVE    SMPS    SMPI

   5) Solution
      GO      SOLU    NONZ    RANGE   DEBUG

   6) Problem Editing
      DEL     EXT     ALT

   7) Quit
      QUIT

   8) System Parameters
      PAGE    TERS    VERB    WIDTH   SET     FREEZE  DBUID   DBPWD   APISET

   9) Miscellaneous
      TIME

有一說一這個命令列互動相當的不好用,我的建議是沒啥大事別瞎折騰……

輸入 HELP <命令名稱> 可以檢視命令幫助提示。比如:

:HELP TAKE

  TAKE command:

  Allows  a  series  of commands to be taken from a file.  The
  file  contents  should  appear  exactly as  terminal  input.
  A file created with the "SAVE" command  can be read with the
  TAKE command.

與此同時,在 LINGO 安裝的目錄下的 Samples 資料夾裡面有一個 LTF 指令碼的示例檔案 TEST.ltf,檔案裡面展示了 LTF 指令碼的一些基本使用方法和常用的書寫方法。如果用任意的文字編輯器開啟,就可以看到裡面的內容為:

! Input a small model
MODEL:
MAX = 20 * X + 30 * Y;
X <= 50;
Y  <= 60;
X + 2 * Y <= 120;
END
! Terse output mode
SET TERSEO 1
! Solve the model
GO
! Open a file
DIVERT SOLU.TXT
! Send solution to the file
SOLUTION
! Close solution file
RVRT
! Quit LINGO
QUIT

同時,結尾處有一個文字編輯器沒有辦法識別的特殊字元。我在這裡沒有貼出來。關於這個特殊字元的問題,我們會在後面糾結。

簡單的來講,從 LINGO 的官方文件來看,官方文件鼓勵使用者將指令碼和模型寫在同一個檔案裡面。我個人認為,對於簡單的模型來說,確實可以這樣做,但是對於複雜模型來說,這樣做會增加程式碼編寫的負擔。 我的建議是將用於執行模型的指令碼,書寫在一個獨立的 .ltf 檔案裡,同時,將模型書寫在另外一個 .lng 檔案裡。前者定義在命令列中執行模型的各項規則,而後者則是模型的直接定義,方便專案的遷移和管理。以下是一個 DEMO:

以下是 lingo.ltf 的內容:

! LINGO 用於執行模型的指令碼;

! 讀取模型到 runlingo;
take LP.lng

! 執行模型;
GO

! 輸出模型結果到檔案 `sulution.txt`
! 要求目錄下存在 `sulution.txt`
! 即使註釋掉內容模型還是會在終端輸出結果
!;
DIVERT solution.txt
SOLUTION
RVRT

! 退出 LINGO;
QUIT

以下是 LP.lng 的內容:

! 規劃模型的定義檔案
! 
! 工程專案投資問題
! ================
! 
! 某公司有一批資金欲投資到5個工程專案中,
! 各工程專案的淨收益(投入資金的百分比)見下表所示
! 工程專案 |  A  |  B  |  C  |  D  |  E  
! -------- | --- | --- | --- | --- | ---
! 收益 / % | 10  | 12  | 15  | 12  |  8
! 
! 由於一些原因,公司決定用於專案A的投資不大於其他各項投資之和,
! 而用於專案B和專案D的投資要大於專案C和專案E的投資。
! 
! 試確定投資分配方案,使該公司收益最大。
!;

MODEL:

SETS:
  Pro / 1..5 / : x;
ENDSETS

DATA:
ENDDATA

max = 0.10 * x(1) + 0.12 * x(2) + 0.15 * x(3) + 0.12 * x(4) + 0.08 * x(5);

x(1) - x(2) - x(3) - x(4) - x(5) <= 0;
       x(2) - x(3) + x(4) - x(5) >= 0;

@sum(
     Pro(i):x(i)
     )=1;

@for(
      Pro(i):x(i)>=0
    );
END

這些內容都可以直接在 Visual Stdio Code 中編寫。

配置 Visual Stdio Code 的設定

至此我們可以開始配置 VSCode。

配置 LTF 檔案的程式碼高亮

LINGO 的擴充套件預設不支援 LTF 檔案的高亮。我們可以在 VSCode 的設定框中搜尋 files.Associations,可以找到下面的設定。我們在 Files: Associations 中將 *.lng*.ltf 格式的檔案關聯到 lingo 語言(由於已經安裝了 LINGO 語言的擴充套件,因此 lingo 的 Value 已經可以被識別。)

image

接下來我們在搜尋框裡輸入 code-runner,在設定裡找到 Executor Map,點選 Edit in setting.json

image

像圖中這樣,在接下來立即開啟的 .json 檔案中找到如下的項:

"code-runner.executorMap":{
    ...
}

"code-runner.executorMap" 儲存了由使用者自行定義的、字尾名為 .* 的檔案在按下一件執行之後執行的終端命令。對於 .ltf 檔案,我們可以定義如下的規則:

    "code-runner.executorMap":{
        /* 由使用者定義的各項程式語言原始檔的執行命令 */
        ".ltf" : "runlingo $fileName"
    },

至此為止,配置已經基本完成。其餘的各項,可以根據個人需求的不同自行配製。

關於檔案相容的一些小問題

  1. LINGO 預設的 .lg4 檔案實際上是二進位制檔案格式,無法直接用文字編輯器開啟。需要另存為 .lng 的純文字格式。

  2. .lng 格式如果出現亂碼,尤其是中文註釋亂碼,請在 VSCode 右下角找到編碼格式按鈕,重新透過 GB2312 編碼格式開啟。

  3. 對於 .lng 檔案,由於我們現在用 RunLingo 命令從 LTF 呼叫,因此應當在文字開頭用和末尾用 MODEL: ... END 關鍵字包裹全文,SETSDATA 的定義也要包含在內。防止出現不必要的各種問題。

  4. 不知道為什麼,LINGO 會預設在 .lng 格式的純文字檔案末尾新增一個文字編輯器無法識別的字元。如下圖所示。目前看來直接刪掉這個字元對求解沒有影響。

image

相關文章