【发布时间】:2021-01-27 02:24:43
【问题描述】:
我正在写我的论文申请。我需要线性编程,但我的应用程序是用 Elixir 编写的,这真的不是这种操作的语言。这就是为什么我决定使用 Erlport 作为 Elixir 依赖项,它能够将 Python 代码与 Elixir 连接起来。我还使用 Pulp 作为优化的 Python 库。
Elixir 版本:1.10.4, Erlport 版本:0.10.1, Python版本:3.8.5, 纸浆版本:2.3
我为 Elixir-Python 通信编写了这样一个模块,它利用 GenServer 作为 Elixir 和 Python 之间的主要“通信中心”:
defmodule MyApp.PythonHub do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def init(_opts) do
path = [:code.priv_dir(:feed), "python"]
|> Path.join() |> to_charlist()
{:ok, pid} = :python.start([{ :python_path, path }, { :python, 'python3' }])
{:ok, pid}
end
def handle_call({:call_function, module, function_name, arguments}, _sender, pid) do
result = :python.call(pid, module, function_name, arguments)
{:reply, result, pid}
end
def call_python_function(file_name, function_name, arguments) do
GenServer.call(__MODULE__, {:call_function, file_name, function_name, arguments}, 10_000)
end
end
GenServer 模块正在调用 python 文件,其中包含这样一个函数:
def calculate_meal_4(products_json, diet_json, lower_boundary, upper_boundary, enhance):
from pulp import LpMinimize, LpProblem, LpStatus, lpSum, LpVariable, value
import json
products_dictionary = json.loads(products_json)
print(products_dictionary)
diets_dictionary = json.loads(diet_json)
print(diets_dictionary)
model = LpProblem(name="diet-minimization", sense=LpMinimize)
# ... products setup ...
x = LpVariable("prod_1_100g", lower_boundary, upper_boundary)
y = LpVariable("prod_2_100g", lower_boundary, upper_boundary)
z = LpVariable("prod_3_100g", lower_boundary, upper_boundary)
w = LpVariable("prod_4_100g", lower_boundary, upper_boundary)
optimization_function = # ... optimization function setup ...
model += # ... optimization boundary function setup ...
model += optimization_function
print(model)
solved_model = model.solve()
print(value(model.objective))
return [value(x), value(y), value(z), value(w)]
对 GenServer 本身的调用如下所示:
PythonHub.call_python_function(:diets, python_function, [products_json, meal_statistics_json, @min_portion, @max_portion, @macro_enhancement])
python_function 是 :calculate_meal_4,products_json 和 meal_statistic_json 是包含所需数据的 json。
在通过 python3 Diets.py 调用 calculate_meal_4 时,它会启动上面的 python 脚本并提供一些示例,但真实(取自应用程序),数据一切正常 -我几乎很快就得到了最小化的结果。通过 Elixir Erlport 调用 python 脚本时会出现问题。查看打印的输出,我可以看出它似乎一直有效,直到
solved_model = model.solve()
被调用。然后脚本似乎冻结了,GenServer 终于在 GenServer.call 函数上达到超时。
我还在一个简单的 python 测试文件上测试了调用:
def pass_var(a):
print(a)
return [a, a, a]
效果很好。
这就是为什么我现在真的很困惑,我正在寻找任何建议。可惜我什么也没找到。
【问题讨论】:
标签: python elixir linear-programming pulp