Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 求解线性规划的有效方法_C#_Performance_Cplex - Fatal编程技术网

C# 求解线性规划的有效方法

C# 求解线性规划的有效方法,c#,performance,cplex,C#,Performance,Cplex,我研究线性规划,我需要解决一个复杂的(数百个变量和约束)问题。有很多方法可以在自立解算器中解决LP(这不是问题)。但是,我需要从C#应用程序中解决它。 我尽了最大的努力找到了解决C#代码内部LP的方法,但我唯一找到的(而且是可用的)是CPLEX和它的.NET Concert库。这看起来很好(实际上我现在正在使用它,而且效果很好),但是一些大型复杂问题的公式是一个真正的噩梦!什么可以用AMPL写10行,任何人都可以理解,需要大约200行C# 你知道有哪种C#库能够以某种高效(友好)的方式提供问题模

我研究线性规划,我需要解决一个复杂的(数百个变量和约束)问题。有很多方法可以在自立解算器中解决LP(这不是问题)。但是,我需要从C#应用程序中解决它。 我尽了最大的努力找到了解决C#代码内部LP的方法,但我唯一找到的(而且是可用的)是CPLEX和它的.NET Concert库。这看起来很好(实际上我现在正在使用它,而且效果很好),但是一些大型复杂问题的公式是一个真正的噩梦!什么可以用AMPL写10行,任何人都可以理解,需要大约200行C#

你知道有哪种C#库能够以某种高效(友好)的方式提供问题模型定义吗? (CPLEX接受LP格式,但当你试图解决一个有很多变量的问题时,它可能会增长到数百兆字节,然后算法运行了很长时间)或者我听说有可能将AMPL转换为LP格式,然后用CPLEX C#library解决,但听起来效率不高:-)


简言之,我有一个C#项目。我需要解决LP问题。我需要非常有效地解决它。。。所有这些都是以一种相当简单的方式进行的(不是数百条混沌线在for cycles中添加变量和约束等)。

也许这不是您想要的答案,但Concert for.NET是一种建模线性程序的好方法。我认为你只是夸大了AMPL和Concert for.NET之间的区别。以下是AMPL手册示例中AMPL中的steel.mod,后面是CPLEX附带的steel.cs的一部分。这大致对应于相同的代码。缺少了一些东西,比如数据读取和调用解算器,但必须在AMPL中的单独文件中写入。有122行

是的,它比AMPL更难,因为它是通用编程语言的API。如果您需要使用C#,并且您可以访问CPLEX,这可能就足够了。它还具有比AMPL更大的功能,比如在整数程序中访问分支和绑定树

CPLEX本身包含许多非常好的音乐会示例

set PROD;     # products
param T > 0;  # number of weeks

param rate {PROD} > 0;          # tons per hour produced
param inv0 {PROD} >= 0;         # initial inventory
param avail {1..T} >= 0;        # hours available in week
param market {PROD,1..T} >= 0;  # limit on tons sold in week

param prodcost {PROD} >= 0;     # cost per ton produced
param invcost {PROD} >= 0;      # carrying cost/ton of inventory
param revenue {PROD,1..T} >= 0; # revenue per ton sold

var Make {PROD,1..T} >= 0;      # tons produced
var Inv {PROD,0..T} >= 0;       # tons inventoried
var Sell {p in PROD, t in 1..T} >= 0, <= market[p,t]; # tons sold

maximize Total_Profit:
  sum {p in PROD, t in 1..T} (revenue[p,t]*Sell[p,t] -
    prodcost[p]*Make[p,t] - invcost[p]*Inv[p,t]);

subject to Time {t in 1..T}:
  sum {p in PROD} (1/rate[p]) * Make[p,t] <= avail[t];

subject to Init_Inv {p in PROD}:  Inv[p,0] = inv0[p];

subject to Balance {p in PROD, t in 1..T}:
  Make[p,t] + Inv[p,t-1] = Sell[p,t] + Inv[p,t];


    public class Steel {
       internal static int _nProd;
       internal static int _nTime;

       internal static double[] _avail;
       internal static double[] _rate;
       internal static double[] _inv0;
       internal static double[] _prodCost;
       internal static double[] _invCost;

       internal static double[][] _revenue;
       internal static double[][] _market;

       internal static void ReadData(string fileName) {
          InputDataReader reader = new InputDataReader(fileName);

          _avail    = reader.ReadDoubleArray();
          _rate     = reader.ReadDoubleArray();
          _inv0     = reader.ReadDoubleArray();
          _prodCost = reader.ReadDoubleArray();
          _invCost  = reader.ReadDoubleArray();
          _revenue  = reader.ReadDoubleArrayArray();
          _market   = reader.ReadDoubleArrayArray();

          _nProd = _rate.Length;
          _nTime = _avail.Length;
       }

       public static void Main(string[] args) {
          try {
             string filename = "../../../../examples/data/steel.dat";
             if ( args.Length > 0 )
                filename = args[0];
             ReadData(filename);

             Cplex cplex = new Cplex();

             // VARIABLES
             INumVar[][] Make = new INumVar[_nProd][];
             for (int p = 0; p < _nProd; p++) {
                Make[p] = cplex.NumVarArray(_nTime, 0.0, System.Double.MaxValue);
             }

             INumVar[][] Inv = new INumVar[_nProd][];
             for (int p = 0; p < _nProd; p++) {
                Inv[p] = cplex.NumVarArray(_nTime, 0.0, System.Double.MaxValue);
             }

             INumVar[][] Sell = new INumVar[_nProd][];
             for (int p = 0; p < _nProd; p++) {
                 Sell[p] = new INumVar[_nTime];
                for (int t = 0; t < _nTime; t++) {
                   Sell[p][t] = cplex.NumVar(0.0, _market[p][t]);
                }
             }

             // OBJECTIVE
             ILinearNumExpr TotalRevenue  = cplex.LinearNumExpr();
             ILinearNumExpr TotalProdCost = cplex.LinearNumExpr();
             ILinearNumExpr TotalInvCost  = cplex.LinearNumExpr();

             for (int p = 0; p < _nProd; p++) {
                for (int t = 1; t < _nTime; t++) {
                   TotalRevenue.AddTerm (_revenue[p][t], Sell[p][t]);
                   TotalProdCost.AddTerm(_prodCost[p], Make[p][t]);
                   TotalInvCost.AddTerm (_invCost[p], Inv[p][t]);
                }
             }

             cplex.AddMaximize(cplex.Diff(TotalRevenue, 
                                          cplex.Sum(TotalProdCost, TotalInvCost)));

             // TIME AVAILABILITY CONSTRAINTS

             for (int t = 0; t < _nTime; t++) {
                ILinearNumExpr availExpr = cplex.LinearNumExpr();
                for (int p = 0; p < _nProd; p++) {
                   availExpr.AddTerm(1.0/_rate[p], Make[p][t]);
                }
                cplex.AddLe(availExpr, _avail[t]);
             }

             // MATERIAL BALANCE CONSTRAINTS

             for (int p = 0; p < _nProd; p++) {
                cplex.AddEq(cplex.Sum(Make[p][0], _inv0[p]), 
                            cplex.Sum(Sell[p][0], Inv[p][0]));
                for (int t = 1; t < _nTime; t++) {
                   cplex.AddEq(cplex.Sum(Make[p][t], Inv[p][t-1]), 
                               cplex.Sum(Sell[p][t], Inv[p][t]));
                }
             }

             cplex.ExportModel("steel.lp");

             if ( cplex.Solve() ) {
                System.Console.WriteLine();
                System.Console.WriteLine("Total Profit = " + cplex.ObjValue);

                System.Console.WriteLine();
                System.Console.WriteLine("\tp\tt\tMake\tInv\tSell");

                for (int p = 0; p < _nProd; p++) {
                   for (int t = 0; t < _nTime; t++) {
                      System.Console.WriteLine("\t" + p +"\t" + t +"\t" + cplex.GetValue(Make[p][t]) +
                                               "\t" + cplex.GetValue(Inv[p][t]) +"\t" + cplex.GetValue(Sell[p][t]));
                   }
                }
             }
             cplex.End();
          }
          catch (ILOG.Concert.Exception exc) {
             System.Console.WriteLine("Concert exception '" + exc + "' caught");
          }
          catch (System.IO.IOException exc) {
             System.Console.WriteLine("Error reading file " + args[0] + ": " + exc);
          }
          catch (InputDataReader.InputDataReaderException exc) {
             System.Console.WriteLine(exc);
          }
       }
    }
set PROD;#产品
参数T>0;#周数
参数率{PROD}>0;#每小时生产吨
参数inv0{PROD}>=0;#初始库存
参数avail{1..T}>=0;#每周可用小时数
参数市场{PROD,1..T}>=0;#每周销售的吨数限制
参数prodcost{PROD}>=0;#每吨生产成本
参数invcost{PROD}>=0;#账面成本/吨存货
参数收入{PROD,1..T}>=0;#每吨销售收入
变量Make{PROD,1..T}>=0;#生产吨
var Inv{PROD,0..T}>=0;#库存吨

VAR卖出{p在PRD,t在1…t}>=0,如果你使用C或C++,我可以推荐。这是一个非常干净的代码,它附带了一个AMPL的特定子集的实现和一个完全满足您所使用的模型大小的解算器。因此,您可以用GNU Mathprog(其AMPL方言)编写模型,并将其直接输入LP解算器。

Microsoft提供了。我从未使用过它,所以我不能说它是否解决了你的问题。它可能仍然值得一看。可能不太适合这样做:基于“FindMeAPI我喜欢”的问题不能由其他人回答。也不推荐使用SO问题作为“库”的搜索引擎。这里可能有一个重复(或类似)的问题:这个库似乎很有趣:我想我应该补充一点,GLPK也有一个C#包装器。我想这个包装叫做“GLPK”。不过我从来没有试过,所以我不能保证它的质量。你说的或多或少是对的。我只是觉得Concert模型公式很难阅读或修改。由于公式不是很自然(从数学角度来看),与AMPL相比,很可能很容易犯错误(周期、指数等),AMPL可以在几秒钟内检查,您几乎可以立即发现错误。但我同意,到目前为止,音乐会是我找到的最好的解决办法。