Charly Nasic Ответов: 2

Неправильные результаты с Microsoft solver foundation


I have an issue with Microsoft solver foundation.

It is a little hard to explain, so I will try to describe the issue to the best of my abilities:
The goal of the code is to get the optimum selection of air filters to filter a given airflow.
The constraint is that the optimum selection of filters does not exceed a given width.
There are three filters to choose from. Each model of filter has a value of airflow and width.

For instance:
Objetive airflow: 19000
Maximum width: 2236

Filters:
Filter X: Airflow = 5100, width=592
Filter Y: Airflow = 4250, width=490
Filter Z: Airflow = 2550, width=287

The solution would be to get the number of filters type X, Y and Z so that we get as close to the airflow goal, but without exceeding the maximum width:

19000 – (X * 5100 + Y * 4250 + Z * 2550) MINIMIZE THIS
X * 592 + Y * 490 + Z * 287 <= 2236 CONSTRAINT

THis is the code I've benn working on:


Что я уже пробовал:

Это код, который у меня сейчас есть:
Sub OPT_3_FILTROS(ByVal REF_filtros As List(Of String), ByVal Q_filtros As List(Of Double), ByVal W_filtros As List(Of Double), ByVal W_util As Integer, ByVal Q_nominal As Integer, ByRef lista_solucion As List(Of Single), ByRef tipo As List(Of String))

    Dim solver = SolverContext.GetContext()
    Dim model = solver.CreateModel()
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    '                               1: DECISIONES: "decisions"
    Dim X As New Decision(Domain.IntegerNonnegative, "decision_1")
    Dim Y As New Decision(Domain.IntegerNonnegative, "decision_2")
    Dim Z As New Decision(Domain.IntegerNonnegative, "decision_3")

    model.AddDecisions(X, Y, Z)
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    '                               2: OBJETIVOS: "goal"

    model.AddGoal("Goal_0", GoalKind.Minimize, Q_nominal - (Q_filtros(0) * X + Q_filtros(1) * Y + Q_filtros(2) * Z))
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    '                               3: RESTRICCIONES: "constraints"
    model.AddConstraint("C_1", X * W_filtros(0) + Y * W_filtros(1) + Z * W_filtros(2) <= W_util)
 '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    '                               4: RESOLVEMOS: "solve"
    Dim solution = solver.Solve(New ConstraintProgrammingDirective())
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    '                               5: OBTENEMOS RESULTADOS: "solve"
    Dim temp As String = ""
    While (solution.Quality <> SolverQuality.Infeasible)
        lista_solucion.Add(X.GetDouble)
        lista_solucion.Add(Y.GetDouble)
        lista_solucion.Add(Z.GetDouble)
        tipo.Add(solution.Quality.ToString())
        solution.GetNext()
    End While

    solver.ClearModel()

End Sub


In the list "lista_solucion" I get the results of the optimization.
And, as you can see in the code above, I get all optimum solutions, not just one.

If I run this code, I get the following results:
lista_solucion={0,1,6,1,1,4}

This means that there are two optimum solutions:
0 X filters + 1 Y filters + 6 Z filters
1 X filters + 1 Y filters + 4 Z filters

Both solutions obtain this airflow:
0x5100 + 1x4250 + 6x2550 = 19550
1x5100 + 1x4250 + 4x2550 = 19550

So, we have a +550 deviation from goal airflow (19000)

All seems legit.

The problem here is that I have checked that this is not the optimal solution:

If I add this new constraint, that basically means that the solution must not exceed 102% of the goal airflow:
model.AddConstraint("C_2", X * Q_filtros(0) + Y * Q_filtros(1) + Z * Q_filtros(2) <= 1.02*19000)

This time I get the following solutions:
lista_solucion={0,2,4,1,2,2,2,2,0}

This means that there are three optimum solutions this time:
0 X filters + 2 Y filters + 4 Z filters
1 X filters + 2 Y filters + 2 Z filters
2 X filters + 2 Y filters + 0 Z filters

All solutions obtain this airflow:
0x5100 + 2x4250 + 4x2550 = 18700
1x5100 + 2x4250 + 2x2550 = 18700
2x5100 + 2x4250 + 0x2550 = 18700

So, we have a -300 deviation from goal airflow (19000)

Obviously, a -300 difference is lower than a +500 difference.

What is happening here?
Why does it optimize by excess rather that to the closest value to goal?

Charly Nasic

Я думаю, что все было бы решено, если бы я мог использовать абсолютные значения в цели... но, по-видимому, это невозможно?
Кто-нибудь знает способ использовать абсолютное значение в цели?

Charly Nasic

Ладно, на всякий случай, если кто-то вмешается в это дело:
Чтобы добавить цель или ограничение с абсолютным значением, вы не можете использовать math. abs()
Вместо этого вы должны использовать model. abs()

Например:

model.AddGoal("Goal_0", GoalKind.Minimize, model.Abs(Q_nominal - Q_filtros(0) * X - Q_filtros(1) * Y - Q_filtros(2) * Z))


Использование model.abs() решает проблему оптимизации, проблема теперь заключается в том, что, помимо того, что время выполнения процедуры оптимизации взлетело до небес, несколько раз я получаю противоречивые результаты... или вообще никаких результатов.

2 Ответов

Рейтинг:
9

Charly Nasic

Чтобы добавить цель или ограничение с абсолютным значением, вы не можете использовать math. abs()
Вместо этого вы должны использовать model. abs()

model.AddGoal("Goal_0", GoalKind.Minimize, model.Abs(Q_nominal - Q_filtros(0) * X - Q_filtros(1) * Y - Q_filtros(2) * Z))


Рейтинг:
2

Patrice T

Ваша проблема в том, что вы неправильно поняли, как максимизировать/минимизировать

19000 – (X * 5100 + Y * 4250 + Z * 2550) MINIMIZE THIS

это то же самое, что
X * 5100 + Y * 4250 + Z * 2550 MAXIMIZE THIS

ваши 19000-это константа, которая не имеет ничего общего с операцией.

Если вы ищете ответ как можно ближе к 19000, вам нужно изменить его на что-то вроде:
ABS(19000 – (X * 5100 + Y * 4250 + Z * 2550)) MINIMIZE THIS


Некоторые могут видеть первый ответ решателя как лучший, потому что фильтры кабины обрабатывают 100% - ный поток воздуха.


Charly Nasic

Действительно, я ищу самое близкое значение к цели воздушного потока, не имеет значения, находится ли оно выше или ниже цели, просто самое близкое.
Итак, как вы говорите, использование АБС-это правильный путь; просто так получилось, что у меня появилось туннельное зрение на математике.
model. abs-это решение этой проблемы.
Сейчас я нахожу, что иногда получаю противоречивые решения или вообще никаких решений... Это странно.
И чтобы закончить, заметил, что при использовании model.abs время выполнения процедуры значительно увеличивается по сравнению с ее отсутствием...