# Why the results of my model remain the same even if the objective value changes?

**URL:** <https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817>\
**Category:** Optimization (Mathematical)\
**Created:** [September 18, 2020, 2:05am UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817 "2020-09-18T02:05:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [September 18, 2020, 2:05am UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817/1 "2020-09-18T02:05:59Z")

</div>

I am struggling with modeling so much, for me what is logical is not so in the model. The next thing is how to force the system to change results by changing the objective value, so let me explain.

I see we can only have one objective value and that is OK. So my guessing is that the system will try to Min (or Max) the value of the objective function by changing the variable(s), is that correct?

In my objective function I have 2 parts:

```julia
        @variable(premex, PRODAMOUNT[op_k in keys(_ORDER_PRODUCTs_ALL), u_k in keys(UNITS), t in TIME], Int, lower_bound = 0)

        @objective(
            premex,
            Min,
            sum(
                sum(
                    (
                        (
                            sum(
                                PRODAMOUNT[op_k, u_k, t] 
                                for (op_k, op) in _ORDER_PRODUCTs_ALL
                            )
                             == 0 ? 0 : u["cap"]
                        ) - 
                        sum(
                            PRODAMOUNT[op_k, u_k, t] * _PRODUCTs_ALL[op["product"]]["bagSize"] 
                            for (op_k, op) in _ORDER_PRODUCTs_ALL
                        )
                    ) * u["util_cost1"]
                for (u_k, u) in UNITS
                )  
                +
                sum(
                    sum(
                        PRODAMOUNT[op_k, u_k, t] 
                        == 0 ? 0 :
                        (t > _ORDERs_ALL[op["order"]]["details"]["deadline"] ? (t - _ORDERs_ALL[op["order"]]["details"]["deadline"]) * 1000000 : 0)
                    for (op_k, op) in _ORDER_PRODUCTs_ALL
                    )
                for (u_k, u) in UNITS
                )
            for t in TIME
            )
        )

```

as you can see outer loop is TIME, the first part of it is:

```julia
                sum(
                    (
                        (
                            sum(
                                PRODAMOUNT[op_k, u_k, t] 
                                for (op_k, op) in _ORDER_PRODUCTs_ALL
                            )
                             == 0 ? 0 : u["cap"]
                        ) - 
                        sum(
                            PRODAMOUNT[op_k, u_k, t] * _PRODUCTs_ALL[op["product"]]["bagSize"] 
                            for (op_k, op) in _ORDER_PRODUCTs_ALL
                        )
                    ) * u["util_cost1"]
                for (u_k, u) in UNITS
                )  

```

This should force the minimum waste of machines’ capacity. After running with only this part the model is giving objective\_value(premex) = 1.172286e6

The next part:

```julia
                sum(
                    sum(
                        PRODAMOUNT[op_k, u_k, t] 
                        == 0 ? 0 :
                        (t > _ORDERs_ALL[op["order"]]["details"]["deadline"] ? (t - _ORDERs_ALL[op["order"]]["details"]["deadline"]) * 1000000 : 0)
                    for (op_k, op) in _ORDER_PRODUCTs_ALL
                    )
                for (u_k, u) in UNITS
                )

```

Should force orders that have a deadline to move up (to be finished first). This I didn’t compose perfectly but it should work. And the objective\_value(premex) = 6.4791172286e10 in this case.

As you can see the objective\_value changes significantly, but the results remain the same.

I clearly said that if PRODAMOUNT[op\_k, u\_k, t] == 0 then the system will have no issues, but if not then the penalty should apply (if any). I think this is not enough for the system to recognize what to do to make no penalties.

In other words, how to force model to finish orders that have deadlines first?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 18, 2020, 2:39am UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817/2 "2020-09-18T02:39:01Z")

</div>

This is the same issue as [Condition in @objective - #5 by odow](https://discourse.julialang.org/t/condition-in-objective/46526/5).

You cannot put conditions like this in the objective, because they get evaluated with JuMP `VariableRef` rather than the _value_ of the variable.

You need to use a mixed-integer reformulation.

```nohighlight
# Instead of
model = Model()
@variable(model, x[1:2], Bin)
@show sum(x) == 0 # false! because x[1] + x[2] != 0
@objective(model, Min, sum(x) == 0 ? 0 : 1)
@show objective_value(model) # 1.0 <-- a constant!

# Use
model = Model()
@variable(model, x[1:2] >= 0, Int)
@variable(model, y, Bin)
M = 10_000 # A number bigger than optimal `sum(x)`.
@constraint(model, sum(x) - M * y <= 0)
@objective(model, Min, 1 * y)

```

MIP-modelling is an art, and there are a lot of tradeoffs and tractability issues you need to consider. e.g., how big is M? You’re going to run into issues if you model is large.

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [September 18, 2020, 6:32am UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817/3 "2020-09-18T06:32:25Z")

</div>

So you are suggesting another variable and constant big enough to become bigger than the sum of the original one?

@odow do you have any more complex examples of how to model objective function so I can check them. Maybe I will have more ideas, thanks a lot for your help with this.

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [September 18, 2020, 7:39am UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817/4 "2020-09-18T07:39:23Z")

</div>

And can I do it this way then?

```julia
            @variable(premex, PRODAMOUNT[op_k in keys(_ORDER_PRODUCTs_ALL), u_k in keys(UNITS), t in TIME], Int, lower_bound = 0)
            @variable(premex, UTILIZATION[u_k in keys(UNITS), t in TIME], Int, lower_bound = 0)
            @variable(premex, DEADLINE[t in TIME], Int, lower_bound = 0)

    @timeit to "Objective" begin
        @objective(
            premex,
            Min,
            sum(
                sum(
                    UTILIZATION[u_k, t]
                    for (u_k, u) in UNITS
                ) +
                DEADLINE[t]
            for t in TIME
            )
        )
    end

    @timeit to "UTILIZATION" begin
        @constraint(
            premex,
            [u_k in keys(UNITS), t in TIME],
            UTILIZATION[u_k, t] == 
            sum(
                (
                    (
                        sum(
                            PRODAMOUNT[op_k, u_k, t] 
                            for (op_k, op) in _ORDER_PRODUCTs_ALL
                        )
                        == 0 ? 0 : UNITS[u_k]["cap"]
                    ) - 
                    sum(
                        PRODAMOUNT[op_k, u_k, t] * _PRODUCTs_ALL[op["product"]]["bagSize"] 
                        for (op_k, op) in _ORDER_PRODUCTs_ALL
                    )
                ) * UNITS[u_k]["util_cost1"]
            )          
        )    
    end

    @timeit to "DEADLINE" begin
        @constraint(
            premex,
            [t in TIME],
            DEADLINE[t in TIME] == 
            sum(
                sum(
                    PRODAMOUNT[op_k, u_k, t] 
                    == 0 ? 0 :
                    (t - _ORDERs_ALL[op["order"]]["details"]["deadline"]) * 1000000 
                for (op_k, op) in _ORDER_PRODUCTs_ALL
                    if t > _ORDERs_ALL[op["order"]]["details"]["deadline"]
                )
            for (u_k, u) in UNITS
            )    
        )    
    end

```

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [September 18, 2020, 12:24pm UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817/5 "2020-09-18T12:24:13Z")

</div>

Or maybe this way:

```julia
            @variable(premex, PRODAMOUNT[op_k in keys(_ORDER_PRODUCTs_ALL), u_k in keys(UNITS), t in TIME], Int, lower_bound = 0)

            @variable(premex, UTILIZATION_CAP[u_k in keys(UNITS), t in TIME], Int, lower_bound = 0)

        @objective(
            premex,
            Min,
            sum(
                UTILIZATION_CAP[u_k, t]
                for (u_k, u) in UNITS, t in TIME
            )
        )

        @constraint(
            premex,
            [op_k in keys(_ORDER_PRODUCTs_ALL), u_k in keys(UNITS), t in TIME],
            PRODAMOUNT[op_k, u_k, t] => 
            {
                UTILIZATION_CAP[u_k, t] == UNITS[u_k]["cap"] -
                sum(
                    PRODAMOUNT[op_k, u_k, t] * _PRODUCTs_ALL[op["product"]]["bagSize"] 
                    for (op_k, op) in _ORDER_PRODUCTs_ALL
                )
            }
        )    

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 18, 2020, 7:56pm UTC](https://discourse.julialang.org/t/why-the-results-of-my-model-remain-the-same-even-if-the-objective-value-changes/46817/6 "2020-09-18T19:56:22Z")

</div>

The cookbook has lots of examples: [9 Mixed integer optimization — MOSEK Modeling Cookbook 3.3.0](https://docs.mosek.com/modeling-cookbook/mio.html)

Instead of posting these code snippets, please post reproducible examples.

```nohighlight
model = Model()
@variable(model, x[1:2] >= 0, Int)
@variable(model, y, Bin)
@constraint(model, y => {sum(x) <= 0})
@objective(model, Min, 1 * y)

```
