Решатель получает минимальное значение, установленное в решении
Я запускаю код, который должен рассчитать соответствующий процент ингредиентов для составления корма для животных. Для этого я использую MS Solver Foundation. Я установил модель, передавая минимальное и максимальное значение для ингредиентов и питательных веществ (процентное содержание ингредиента влияет на большее или меньшее количество питательных веществ). Мне нужно составить самую дешевую (минимизировать) стоимость корма для животных. Вот мой код
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;
}
В результате я получаю минимальное значение решения, которое было установлено, что означает, что решение не найдено. Мой вопрос: почему решатель учитывает минимальное значение, установленное в решении, а не вычисляет соответствующее значение для каждого решения?
1 ответ
Это была моя ошибка при моделировании модели. Код работал нормально. Но это помогло мне решить эту проблему, создав TXT-файл и добавив в него все свои ограничения, поэтому я мог дважды проверить установленные мной ограничения, а также создать файл модели (oml) и импортировать его в Excel, чтобы я мог проверить все ограничения, установленные для решения модели. Код обновлен в моем вопросе, поэтому, если вам нужно, вы можете проверить, как создавать файлы TXT и OML.