# Does the order of the constraint list matter?

**URL:** https://discourse.julialang.org/t/does-the-order-of-the-constraint-list-matter/132955
**Category:** Optimization (Mathematical)
**Created:** [October 7, 2025, 9:15pm UTC](https://discourse.julialang.org/t/does-the-order-of-the-constraint-list-matter/132955 "2025-10-07T21:15:22Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [October 7, 2025, 9:15pm UTC](https://discourse.julialang.org/t/does-the-order-of-the-constraint-list-matter/132955/1 "2025-10-07T21:15:22Z")

</div>

I moved a group of constraints within a list to a different position for “aesthetic” reasons.  
Instead, I noticed, with surprise, that the resulting solution differed in the values ​​of the x[…] matrix of the variables.  
How should I understand this?

```julia-auto
 model = Model(HiGHS.Optimizer)
    JuMP.set_time_limit_sec(model, 600)
    # set_attribute(model, "mip_rel_gap", 0.75) # parametro di HIGHS
    # set_silent(model)
    @variable(model, x[1:nr, 1:ng, turni], Bin)
    @variable(model, z[1:nr, 1:ng], Bin)
    @constraints(model, begin
        # each day must have exactly one t: (t in turni)
        fer1[k in union(t_feriali,t_card), g in g_feriali], sum(x[:,g,k]) == 1
        fer2[k in t_festivi, g in g_feriali], sum(x[:,g,k]) == 0

        fest1[k in t_festivi, g in g_festivi], sum(x[:,g,k]) == 1
        fest2[k in union(t_feriali, t_card), g in g_festivi], sum(x[:,g,k]) == 0

        # 1 turno di servizio di sabato mattina in CU e CL
        sat[k in t_Cs, g in saturdays(mese,y)], sum(x[:,g,k]) == 1
        # ma solo di sabato e non negli altri giorni
        no_sat[k in t_Cs, g in setdiff(1:ng,saturdays(mese,y))], sum(x[:,g,k]) == 0

        # range of N and NF for row for month
        [r in ops_lim], sum(x[r,j,"N"]+x[r,j,"NF"] for j in 1:ng) <= Nel_Mese["max_notti"] 
        [r in ops_lim], sum(x[r,j,"N"]+x[r,j,"NF"] for j in 1:ng) >= Nel_Mese["min_notti"]
        [r in ops_lim], sum(x[r,j,"N"] for j in 1:ng) <= Nel_Mese["max_notti_feriali"]
        [r in ops_lim], sum(x[r,j,"N"] for j in 1:ng) >= Nel_Mese["min_notti_feriali"]

        # # # max of NF for row for month
        [r in 1:nr], sum(x[r,j,"NF"] for j in g_festivi) <= Nel_Mese["max_notti_festive"]  
        
        # # # NF==2 --> N<=1
        [r in ops_lim], sum(x[r,:,"NF"]) == sum(i * z[r, i] for i in 1:ng)
        [r in ops_lim], z[r,Nel_Mese["NF: NF ->N"]] --> {sum(x[r, :, "N"]) <= Nel_Mese["N: NF ->N"]}
        [r in ops_lim], sum(z[r,:]) <= 1

        # continuità per la cardio urgenza mattutina meno le eccezioni necessarie
        [r in 1:nr, (i,w) in enumerate(wks)], x[r,w[1],"CUM1"]-->{sum(x[r,w,"CUM1"])>=length(w)-wk["continuità_CUM1"][i]}
        [r in 1:nr, (i,w) in enumerate(wks)], x[r,w[1],"CUM2"]-->{sum(x[r,w,"CUM2"])>=length(w)-wk["continuità_CUM2"][i]}
        [r in 1:nr, (i,w) in enumerate(wks)], x[r,w[1],"CLM" ]-->{sum(x[r,w,"CLM"])>=length(w)-wk["continuità_CLM"][i]}

        # # max turni nello stesso giorno per operatore
        # non notte insieme a mattina o pomeriggio, ecc.
        max_turni_fer_N_P[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in ["N","P"]) <= 1
        max_turni_fer_N_M[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in ["N";t_mattina]) <= 1
        max_turni_fer_P_M[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in ["P";t_mattina]) <= 2 # 1
        max_turni_fer[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in t_feriali) <= 2
        max_turni_CU[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in t_card) <= 1
        max_turni_fest[op in 1:nr, g in g_festivi], sum(x[op,g,k] for k in [t_festivi;t_Cs]) <= 1

...

end
...

    peso = Dict{String, Int}()
    for g in turni
        if g in [t_festivi; ["N", "CUMs", "CLMs"]]
            peso[g] = peso_festivi_e_notti
        else
            peso[g] = peso_feriali_giorno
        end
    end

    # Carico di lavoro
    @expression(model, workload[r=no_E], sum(x[r, g,k]*peso[k] for g in 1:ng, k in turni))
  
    # Variabili per max/min carico
    @variable(model, M) # massimo carico
    @variable(model, m) # minimo carico

    @constraint(model, [r in no_E], workload[r] <= M)
    @constraint(model, [r in no_E], workload[r] >= m)

    # Obiettivo: minimizzare squilibrio massimo
    @objective(model, Min, M - m)

...

```

########

```julia-auto
 model = Model(HiGHS.Optimizer)
    JuMP.set_time_limit_sec(model, 600)
    # set_attribute(model, "mip_rel_gap", 0.75) # parametro di HIGHS
    # set_silent(model)
    @variable(model, x[1:nr, 1:ng, turni], Bin)
    @variable(model, z[1:nr, 1:ng], Bin)
    @constraints(model, begin
        # each day must have exactly one t: (t in turni)
        fer1[k in union(t_feriali,t_card), g in g_feriali], sum(x[:,g,k]) == 1
        fer2[k in t_festivi, g in g_feriali], sum(x[:,g,k]) == 0

        fest1[k in t_festivi, g in g_festivi], sum(x[:,g,k]) == 1
        fest2[k in union(t_feriali, t_card), g in g_festivi], sum(x[:,g,k]) == 0

        # 1 turno di servizio di sabato mattina in CU e CL
        sat[k in t_Cs, g in saturdays(mese,y)], sum(x[:,g,k]) == 1
        # ma solo di sabato e non negli altri giorni
        no_sat[k in t_Cs, g in setdiff(1:ng,saturdays(mese,y))], sum(x[:,g,k]) == 0

#####

        # # max turni nello stesso giorno per operatore
        # non notte insieme a mattina o pomeriggio, ecc.
        max_turni_fer_N_P[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in ["N","P"]) <= 1
        max_turni_fer_N_M[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in ["N";t_mattina]) <= 1
        max_turni_fer_P_M[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in ["P";t_mattina]) <= 2 # 1
        max_turni_fer[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in t_feriali) <= 2
        max_turni_CU[op in 1:nr, g in g_feriali], sum(x[op,g,k] for k in t_card) <= 1
        max_turni_fest[op in 1:nr, g in g_festivi], sum(x[op,g,k] for k in [t_festivi;t_Cs]) <= 1

########

        # range of N and NF for row for month
        [r in ops_lim], sum(x[r,j,"N"]+x[r,j,"NF"] for j in 1:ng) <= Nel_Mese["max_notti"] 
        [r in ops_lim], sum(x[r,j,"N"]+x[r,j,"NF"] for j in 1:ng) >= Nel_Mese["min_notti"]
        [r in ops_lim], sum(x[r,j,"N"] for j in 1:ng) <= Nel_Mese["max_notti_feriali"]
        [r in ops_lim], sum(x[r,j,"N"] for j in 1:ng) >= Nel_Mese["min_notti_feriali"]

        # # # max of NF for row for month
        [r in 1:nr], sum(x[r,j,"NF"] for j in g_festivi) <= Nel_Mese["max_notti_festive"]  
        
        # # # NF==2 --> N<=1
        [r in ops_lim], sum(x[r,:,"NF"]) == sum(i * z[r, i] for i in 1:ng)
        [r in ops_lim], z[r,Nel_Mese["NF: NF ->N"]] --> {sum(x[r, :, "N"]) <= Nel_Mese["N: NF ->N"]}
        [r in ops_lim], sum(z[r,:]) <= 1

        # continuità per la cardio urgenza mattutina meno le eccezioni necessarie
        [r in 1:nr, (i,w) in enumerate(wks)], x[r,w[1],"CUM1"]-->{sum(x[r,w,"CUM1"])>=length(w)-wk["continuità_CUM1"][i]}
        [r in 1:nr, (i,w) in enumerate(wks)], x[r,w[1],"CUM2"]-->{sum(x[r,w,"CUM2"])>=length(w)-wk["continuità_CUM2"][i]}
        [r in 1:nr, (i,w) in enumerate(wks)], x[r,w[1],"CLM" ]-->{sum(x[r,w,"CLM"])>=length(w)-wk["continuità_CLM"][i]}

...

end

...

    peso = Dict{String, Int}()
    for g in turni
        if g in [t_festivi; ["N", "CUMs", "CLMs"]]
            peso[g] = peso_festivi_e_notti
        else
            peso[g] = peso_feriali_giorno
        end
    end

    # Carico di lavoro
    @expression(model, workload[r=no_E], sum(x[r, g,k]*peso[k] for g in 1:ng, k in turni))
  
    # Variabili per max/min carico
    @variable(model, M) # massimo carico
    @variable(model, m) # minimo carico

    @constraint(model, [r in no_E], workload[r] <= M)
    @constraint(model, [r in no_E], workload[r] >= m)

    # Obiettivo: minimizzare squilibrio massimo
    @objective(model, Min, M - m)

...

```

That is, I understand that I can have the same optimum (by the way, I don’t know what it is, in my case) in different combinations of the variables, but I can’t explain why a different ordering of the constraints changes the “landing” point.

PS  
Out of curiosity, how can I see the value of the optimum at which the algorithm stopped?

---

<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: [October 7, 2025, 9:30pm UTC](https://discourse.julialang.org/t/does-the-order-of-the-constraint-list-matter/132955/2 "2025-10-07T21:30:03Z")

</div>

> Does the order of the constraint list matter?

The short answer is _yes_.

The main reason is that there can be many equivalent solutions to a problem. Changing the order of the variables and constraints can change some of the internal algorithmic decisions that HiGHS makes during the solution algorithm, and this can cause it to find one solution before another.

However, even if it finds different solutions in _x_, the objective value of each optimal decision will be the same (to within the optimality tolerance).

You can see the final objective value with `objective_value(model)`.
