如何使用 C# 中的参数调用 python 函数并获取返回值

问题描述 投票:0回答:1

你好,我正在尝试从 C# 中调用以下 python 函数“mclp”

import numpy as np
from scipy.spatial import distance_matrix
from gurobipy import *
from scipy.spatial import ConvexHull
from shapely.geometry import Polygon, Point
from numpy import random

def generate_candidate_sites(points,M=100):
    hull = ConvexHull(points)
    polygon_points = points[hull.vertices]
    poly = Polygon(polygon_points)
    min_x, min_y, max_x, max_y = poly.bounds
    sites = []
    while len(sites) < M:
        random_point = Point([random.uniform(min_x, max_x),
                             random.uniform(min_y, max_y)])
        if (random_point.within(poly)):
            sites.append(random_point)
    return np.array([(p.x,p.y) for p in sites])

def mclp(points,K,radius,M):
    import time
    start = time.time()
    sites = generate_candidate_sites(points,M)
    J = sites.shape[0]
    I = points.shape[0]
    D = distance_matrix(points,sites)
    mask1 = D<=radius
    D[mask1]=1
    D[~mask1]=0
    # Build model
    m = Model()
    # Add variables
    x = {}
    y = {}
    for i in range(I):
      y[i] = m.addVar(vtype=GRB.BINARY, name="y%d" % i)
    for j in range(J):
      x[j] = m.addVar(vtype=GRB.BINARY, name="x%d" % j)

    m.update()
    # Add constraints
    m.addConstr(quicksum(x[j] for j in range(J)) == K)

    for i in range(I):
        m.addConstr(quicksum(x[j] for j in np.where(D[i]==1)[0]) >= y[i])

    m.setObjective(quicksum(y[i]for i in range(I)),GRB.MAXIMIZE)
    m.setParam('OutputFlag', 0)
    m.optimize()
    end = time.time()
   
    solution = []
    if m.status == GRB.Status.OPTIMAL:
        for v in m.getVars():
            # print v.varName,v.x
            if v.x==1 and v.varName[0]=="x":
               solution.append(int(v.varName[1:]))
    opt_sites = sites[solution]
    return opt_sites

输入参数是

K = 20
radius = 0.2
M = 100
points =[[ 1.85737721  0.3341904 ]
 [-0.93679108  0.3511183 ]
 [ 0.68220641  0.84082034]
 [-0.88955891  0.84335212]
 [ 1.83264259 -0.15681283]
 [ 1.2737921  -0.04591726]
 [ 0.12594991  0.93641684]
 [ 0.15216603  0.75590733]
 [ 0.93954871 -0.61432142]
 [ 0.44905661 -0.39367967]]

在 C# 中,我想将此函数称为“opt_sites= mclp(points,K,radius,M)”

'points' 和 'opt_sites' 是类似的数组。我试过 Ironpython,但我无法在其中安装 numpy 或 gurobipy。所以我相信理想的方法是使用 C# 中的直接进程调用方法。我很困惑如何传递数组的“点”参数。

目前我的 C# 代码看起来像这样

string python = @"C:\Users\MSI\anaconda3\python.exe";
string myPythonApp = @"C:\Users\MSI\Documents\Work\Development\mclp.py";
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.Arguments = myPythonApp + " " + x + " " + y;`

我很困惑如何将点数组传递给 python。 谁能帮忙?

python c# arrays function arguments
1个回答
0
投票

一种方法是将您的输入序列化为 json,然后在 python 中将该 json 加载到字典中。另外,看起来你想解析标准输出的输出,所以只打印

mclp
的结果。

将此添加到 python 脚本的底部:

# Can be imported at the top with the rest of the imports
import sys
import json

def main():
    # Assuming the first argument passed to the script is the path to the json
    # Can also be changed to hardcoded file path
    json_path = sys.argv[1]

    with open(json_path) as fs:
        input_data = json.load(fs)

    points = np.asarray(input_data["points"])
    result = mclp(points, input_data["K"], input_data["radius"], input_data["M"])
    print(result)

if __name__ == "__main__":
    main()

示例命令行命令为:

python mcpl.py my_input_file.json

© www.soinside.com 2019 - 2024. All rights reserved.