2

我一直在尝试在我的 Haskell 项目中使用glpk-hs,但我完全不知道该怎么做。我stack用来运行我的程序,我的困惑很可能来自我对它的工作原理缺乏了解。

话虽如此,我已经下载了 glpk-hs-0.7并将提取的文件夹放在我的项目文件夹中。我正在运行我的代码stack ghci my_program.hs,对文件具有以下依赖stack.yaml项:

"extra-deps: - gasp-1.2.0.0 - glpk-hs-0.7"

它成功安装了 gasp,但glpk安装失败并出现以下错误:glpk-hs > * Missing (or bad) C library: glpk.
我还尝试通过下载可执行文件并将其添加到 PATH 来为 Windows安装glpkglpsol ,当我在 cmd 上运行时,它会显示以下消息:

GLPSOL: GLPK LP/MIP Solver, v4.65 No input problem file specified; try glpsol --help

我错过了什么?我注意到在glpk-hs-0.7/glpk文件夹中有一个 glpk.c 文件。我应该编译并执行这个程序吗?

顺便说一句,我现在在 Windows 10 上运行,但我主要在 Linux 机器上工作,所以如果有一个适用于两个系统的解决方案,我将不胜感激。

谢谢!

4

1 回答 1

2

该软件包为单独安装的GLPK 库glpk-hs提供了 GHC 接口,但安装不会自动安装所需的库。编译包的文件无济于事,因为那只是一些有助于构建接口的存根 C 代码。(绝大多数为其他库提供“桥梁”的 GHC 包都是这样设计的,所以不是特例。)glpk-hs"glpk.c"glpk-hs

apt install libglpk-dev在 Linux 下,在尝试(重新)安装之前,您需要使用发行版的包管理器以“通常”的方式安装 GLPK 包的开发版本(例如,对于基于 Debian 的发行版,您需要运行)glpk-hs包裹。

在 Windows 下,我想从GLPK for Windows Project Page下载带有预编译二进制文件的 zipfile 可能是最简单的。将其解压缩到方便的地方,然后根据该网页上的说明,将 32 位或 64 位 DLL(视情况而定)复制到c:\windows\system32目录中。

为了stack针对库进行构建,它需要指定一些额外的库和包含文件目录。在您的项目特定stack.yaml(或全局config.yaml)中,您需要添加指向适当解压缩路径的行。例如,类似(假设是 64 位环境):

# in stack.yaml or config.yaml
extra-lib-dirs:     ["c:\\users\\XXXXX\\glpk-4.65\\w64"]
extra-include-dirs: ["c:\\users\\XXXXX\\glpk-4.65\\src"]

此外,由于 Cabal 正在寻找glpk.lib而不是,我遇到了另一个问题glpk_4_65.lib,所以我不得不将库复制过来。我不确定是否有更好的方法来做到这一点。

> cd c:\users\XXXXX\glpk-4.65\w64
> cp glpk_4_65.lib glpk.lib

现在,最新的glpk-hs-0.7软件包与当前的 GHCcontainers版本不兼容,因此您需要在stack.yaml文件中使用较早的解析器。lts-12.26解析器为我工作:

# in stack.yaml
resolver: lts-12.26

最后,GLPK 仅适用于线程运行时,因此将标志添加到您的.cabal文件中:

-- in your .cabal file
executable glpktest
  ghc-options: -threaded -O2

您可以从https://github.com/jyp/glpk-hs/blob/master/examples/example1.hs获取示例。删除该import Algebraic.Classes行,因为它不需要,并在您的文件中使用以下executable子句:.cabal

-- in your .cabal file
executable glpktest
  hs-source-dirs:    src
  main-is:           Example1.hs
  default-language:  Haskell2010
  build-depends:     base >= 4.7 && < 5
                   , glpk-hs
                   , containers
  ghc-options:       -threaded -O2

以及以下内容stack.yaml

-- full stack.yaml contents

resolver: lts-12.26

packages:
- .

extra-deps:
- glpk-hs-0.7
- gasp-1.2.0.0

extra-lib-dirs:     ["c:\\users\\XXXXX\\glpk-4.65\\w64"]
extra-include-dirs: ["c:\\users\\XXXXX\\glpk-4.65\\src"]

你应该能够stack buildstack exec glpktest那个例子。如果可执行文件正确构建但运行它没有产生输出,则可能是因为找不到 DLL。确保已将正确的 DLL 集复制到c:\windows\system32.

总结假设 64 位环境的所有步骤:

  1. 从winglpk项目下载并解压预编译的二进制文件
  2. 将 DLL 从w64目录复制到c:\windows\system32
  3. w64目录中,复制glpk_4_65.libglpk.lib.
  4. stack.yaml上述内容与解析器lts-12.26和适当的目录设置一起使用。
  5. 将上面给出的子句复制到您的文件中(包括GHC 选项) ,尝试上面stack buildExample1.hs链接(首先删除不必要的import行)executable.cabal-threaded
  6. 使用stack exec glpktest,您会希望看到打印的解决方案(x1=40、x2=50 和 x3=0)。
于 2020-01-25T19:47:09.613 回答