C# 解算器获取决策中设置的最小值
我正在运行一个代码,需要计算组成动物食品的成分的适当百分比。为了做到这一点,我使用MS Sulver基金会。我将模型设置为通过成分和营养素的最小值和最大值(成分百分比或多或少会干扰营养素)。我需要把动物性食品的成本降到最低。这是我的密码C# 解算器获取决策中设置的最小值,c#,winforms,solver,simplex-algorithm,C#,Winforms,Solver,Simplex Algorithm,我正在运行一个代码,需要计算组成动物食品的成分的适当百分比。为了做到这一点,我使用MS Sulver基金会。我将模型设置为通过成分和营养素的最小值和最大值(成分百分比或多或少会干扰营养素)。我需要把动物性食品的成本降到最低。这是我的密码 private Solution FormularRacao() { var ingredientesRacao = _formulacaoRacao.CarregarIngredientesNutrientesFormulacao(
private Solution FormularRacao()
{
var ingredientesRacao = _formulacaoRacao.CarregarIngredientesNutrientesFormulacao(true);
var nutrientes = _formulacaoRacao.CarregarIngredientesNutrientesFormulacao(false);
var formulacao = _formulacaoRacao.CarregarFormulacao();
SolverContext context = SolverContext.GetContext();
context.ClearModel();
Model model = context.CreateModel();
var objetivo = new SumTermBuilder(ingredientesRacao.Count);
var totalIngrediente = new SumTermBuilder(ingredientesRacao.Count);
List<SumTermBuilder> listaTotalNutriente = new List<SumTermBuilder>();
//Set decisions
foreach (var item in ingredientesRacao)
{
item.Nome = TratarNome(item.Nome);
Decision d = new Decision(Domain.RealRange(Convert.ToDouble(item.Minimo), Convert.ToDouble(item.Maximo)), "d_" + item.Nome);
model.AddDecision(d);
objetivo.Add(Model.Product(d, Convert.ToDouble(item.Custo)));
totalIngrediente.Add(d);
listaTotalNutriente.Add(new SumTermBuilder(nutrientes.Count));
}
var SomaIngrediente = totalIngrediente.ToTerm();
//sum of decisions values must be equal 100
model.AddConstraint("c_totalIngrediente", SomaIngrediente == 100);
//totalIngrediente;
model.AddGoal("racao", GoalKind.Minimize, objetivo.ToTerm());
int indexIngrediente = 0;
int indexNutriente = 0;
//each ingredient contributes with nutrients
//each nutrient has a min and max set
foreach (var ingredienteRacao in ingredientesRacao)
{
Ingrediente ingrediente = _formulacaoRacao.CarregarIngrediente(ingredienteRacao.Id);
indexNutriente = 0;
ingredienteRacao.Nome = TratarNome(ingredienteRacao.Nome);
Decision d = model.Decisions.First(x => x.Name == "d_" + ingredienteRacao.Nome);
foreach (var nutriente in nutrientes)
{
var valor = new object();
if (nutriente.AminoacidoDigestivo.Equals("S"))
{
var aminoacidoDigestivo = _formulacaoRacao.CarregarAminoacidoDigestivo(ingredienteRacao.Id);
valor = aminoacidoDigestivo.GetType().GetProperty(nutriente.Nome).GetValue(aminoacidoDigestivo, null);
}
else
{
nutriente.Nome = TratarNomeNutriente(nutriente.Nome);
valor = ingrediente.GetType().GetProperty(nutriente.Nome).GetValue(ingrediente, null);
}
var proporcaoNutriente = Convert.ToDouble(valor.ToString()) * d;
listaTotalNutriente[indexNutriente].Add(proporcaoNutriente / 100);
if (indexIngrediente == ingredientesRacao.Count - 1) //last iteration
{
var totalNutriente = listaTotalNutriente[indexNutriente].ToTerm();
if (nutriente.Minimo == nutriente.Maximo)
model.AddConstraint("c_" + nutriente.Nome, totalNutriente == Convert.ToDouble(nutriente.Maximo));
else
model.AddConstraint("c" + nutriente.Nome, Convert.ToDouble(nutriente.Minimo) <= totalNutriente <= Convert.ToDouble(nutriente.Maximo));
}
indexNutriente++;
}
indexIngrediente++;
}
//saves the model
TextWriter tw = new StreamWriter("Path\file.oml");
context.SaveModel(FileFormat.OML, tw);
tw.Close();
//Imprime o modelo
TextWriter txt = new StreamWriter("Path\file.txt");
foreach (var item in model.Constraints.ToList())
{
txt.WriteLine(item.Name + ": " + item.Expression);
txt.WriteLine();
}
txt.Close();
Solution solution = context.Solve();
return solution;
}
private Solution FormularRacao()
{
var Ingredentsracao=_formulacaoRacao.carregaringRedientsnutrientesformulacao(真);
var nutrientes=_formulacaoRacao.carregaringredientsnutrientesformulacao(假);
var formulacao=_formulacaoRacao.CarregarFormulacao();
SolverContext上下文=SolverContext.GetContext();
context.ClearModel();
Model Model=context.CreateModel();
var objetivo=新的SumTermBuilder(Ingreditentesracao.Count);
var totalIngrediente=新的SumTermBuilder(IngRedientsRaco.Count);
List listaTotalNutriente=新列表();
//决定
foreach(IngRedientSracao中的var项目)
{
item.Nome=TratarNome(item.Nome);
Decision d=新决策(Domain.RealRange(Convert.ToDouble(item.Minimo)、Convert.ToDouble(item.Maximo)),“d_”+item.Nome);
模型决策(d);
添加(Model.Product(d,Convert.ToDouble(item.Custo));
合计贷方。添加(d);
添加(新SumTermBuilder(nutrients.Count));
}
var SomaIngrediente=totalIngrediente.ToTerm();
//决策值之和必须等于100
model.AddConstraint(“c_totalIngrediente”,SomaIngrediente==100);
//总信用额度;
model.AddGoal(“racao”,GoalKind.Minimize,objetivo.ToTerm());
int indexIngrediente=0;
int indexNutriente=0;
//每种成分都含有营养成分
//每种营养素都有一个最小值和最大值集
foreach(IngreditEnterAcao中的变量IngreditEnterAcao)
{
Ingrediente Ingrediente=_formulacaoRacao.CarregarIngrediente(IngRedientaco.Id);
指数营养素=0;
Ingredienteraco.Nome=TratarNome(Ingredienteraco.Nome);
Decision d=model.Decisions.First(x=>x.Name==“d_u2;”+ingredientaco.Nome);
foreach(营养素中的var nutriente)
{
var valor=新对象();
if(营养素氨基酸二孕酯等于(“S”))
{
var氨基酸二酯=_formulacaoRacao.CarregarAminoacidoDigestivo(ingredienteRacao.Id);
valor=aminoacydigestivo.GetType().GetProperty(nutriente.Nome).GetValue(aminoacydigestivo,null);
}
其他的
{
nutriente.Nome=营养素(nutriente.Nome);
valor=ingrediente.GetType().GetProperty(nutriente.Nome).GetValue(ingrediente,null);
}
var proporcaoNutriente=Convert.ToDouble(valor.ToString())*d;
listaTotalNutriente[indexNutriente]。添加(ProportaNutriente/100);
if(indexIngrediente==ingredientsracao.Count-1)//最后一次迭代
{
var totalNutriente=listaTotalNutriente[indexNutriente].ToTerm();
if(营养素E.Minimo==营养素E.Maximo)
model.AddConstraint(“c_399;”+nutriente.Nome,totalNutriente==Convert.ToDouble(nutriente.Maximo));
其他的
model.AddConstraint(“c”+nutrient.Nome,Convert.ToDouble(nutrient.Minimo)这是我在建模模型时犯的错误。代码运行良好。但它确实帮助我解决了问题,创建了一个txt文件并将所有约束添加到其中,这样我就可以再次检查我正在设置的约束,同时创建一个模型文件(oml)并将其导入Excel,以便我可以检查所有约束集以求解模型。我的问题中会更新代码,以便您可以检查如何创建txt和oml文件。您的问题是什么?为什么解算器会在决策中考虑最小值集,而不是计算适当的值?