C# 如何将模型指定为Google或Tools的字符串?

C# 如何将模型指定为Google或Tools的字符串?,c#,.net,mathematical-optimization,constraint-programming,or-tools,C#,.net,Mathematical Optimization,Constraint Programming,Or Tools,我正在为一个软件包开发一个功能。此功能允许用户输入优化模型,系统将使用注入的数据运行这些模型。模型格式可以是任何格式——AMPL、Flatzin、SMT Lib等 微软的Z3看起来很稳定(它支持SMT-LIB),但不幸的是它不是免费的商业用途。经过更多的搜索,我决定了,这是免费的商业用途 不幸的是,我无法找到将模型指定为字符串的方法。例如,下面介绍如何使用Tools.NET API解决一个简单的线性规划问题: Solver solver = Solver.CreateSolver(sol

我正在为一个软件包开发一个功能。此功能允许用户输入优化模型,系统将使用注入的数据运行这些模型。模型格式可以是任何格式——AMPL、Flatzin、SMT Lib等

微软的Z3看起来很稳定(它支持SMT-LIB),但不幸的是它不是免费的商业用途。经过更多的搜索,我决定了,这是免费的商业用途

不幸的是,我无法找到将模型指定为字符串的方法。例如,下面介绍如何使用Tools.NET API解决一个简单的线性规划问题:

    Solver solver = Solver.CreateSolver(solverType);
    Variable x1 = solver.MakeIntVar(0.0, double.PositiveInfinity, "x1");
    Variable x2 = solver.MakeIntVar(0.0, double.PositiveInfinity, "x2");
    Objective objective = solver.Objective();
    objective.SetMinimization();
    objective.SetCoefficient(x1, 1);
    objective.SetCoefficient(x2, 2);
    Constraint ct = solver.MakeConstraint(17, double.PositiveInfinity);
    ct.SetCoefficient(x1, 3);
    ct.SetCoefficient(x2, 2);
    Solver.ResultStatus resultStatus = solver.Solve();
但是,由于我们需要用户指定一个模型,系统可以在以后动态运行(使用它注入的值),因此我们需要能够指定如下模型:

Solver solver = Solver.CreateSolver(solverType);
solver.AddParam("x1", 0);
model = @"
    int: x1;
    var int: x2;
    constraint x1 >= 0;
    constraint x2 >= 0;
    constraint 2*x2 + 3*x1 >= 17;
    solve minimize x1 + 2*x2;
";
results = solver.Solve(model);
确切的语法并不重要。重要的是,用户正在用高级建模语言指定模型,并且可以指定我们可以在后端注入的参数(在本例中,x1

我搜遍了地图,但什么也没找到。诚然,这份文件似乎不完整、不准确/过时,但这是我所能找到的全部。我也搜索了一下,但什么也没找到

虽然我认为或工具有一个支持外部文件的可执行文件,但我不能使用它,因为我们需要为这个解决方案避免任何外部可执行文件

我们可以将JSON字符串解析为Google ProtoBuf。这可能是我们的用户模型语言,甚至可以加糖形成一种。然而,这仍然留下了精确映射的问题,同样,缺乏文档


如何让Google或Tools.NETAPI使用字符串指定模型来实现上述示例?一个代码示例(将JSON字符串解析到Google ProtoBuf中就可以了)或明确的(准确的)文档都可以作为答案。

听起来你想使用动态C#脚本库,比如my Data.Eval库,()?还有其他的,但是这个概念似乎符合你的要求

您应该能够从中的“完整程序”部分获取C#代码,并将其转换为字符串,然后使用任意库对其进行“求值”

如果你认为这就是你要找的,我可以输入完整的例子,我只是不熟悉谷歌或工具,尽管我熟悉线性回归解算器

Console.WriteLine(Evaluator.Eval("return 1+1"));

AMPL和GAMS都有允许这样做的API

  • 有关AMPL,请参阅中的:
    public void Eval(字符串AMPLStatements)
  • 有关GAMS示例,请参见:
    GAMSJob t2=ws.AddJobFromString(GetModelText())输入
不幸的是,这些都是商业系统,所以它们不是免费的。如果我仔细阅读你的帖子,你是在寻找这样一个没有成本的工具


一种可能的方法是使用NEOS API向NEOS服务器提交以AMPL或GAMS表示的优化任务。请参阅:。

我刚刚得到,我假设可以像@Bruce建议的那样,在.NET中使用反射或求值来完成类似的操作。

不太可能。我们已经使用了字符串表达式库。这是因为我们正在寻找具有自己的内置建模语言的东西。动态地允许对C#表达式进行求值并不能为用户提供高级建模语言。这只是意味着他们必须编写C来调用api。我们需要的不是调用api的能力,而是一种建模语言。例如,如果您将Google或Tools API与Minizing语言进行比较,您就会明白我的意思。即使是这个例子也表明,它不是我们正在寻找的api的1:1映射。为什么不使用Roslyn并将语法设置为C#?你说语法无关紧要……另外,如果语法无关紧要,但你不喜欢C#,请使用mps文件格式,或工具支持该格式。LP是一种更易于阅读的格式,但OR工具不支持它。如果您更喜欢LP格式,LPSolve是另一种选择。看看根据GNU LGPL许可。您可以使用read_lp读取lp文件。@MineR语法无关紧要,只要它仍然是一种数学建模语言。这意味着它需要具有建模语言的高级语义。因此,简单地允许他们编写C#并不是一种选择。但你提出了一个很好的观点。为了清晰起见,我将编辑这篇文章。谢谢