# Trinary/Ternary Variables

**URL:** https://discourse.julialang.org/t/trinary-ternary-variables/87679
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [September 23, 2022, 1:16am UTC](https://discourse.julialang.org/t/trinary-ternary-variables/87679 "2022-09-23T01:16:38Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)
#### Post date: [September 23, 2022, 1:16am UTC](https://discourse.julialang.org/t/trinary-ternary-variables/87679/1 "2022-09-23T01:16:38Z")

</div>

I am looking to efficiently implement trinary/ternary variables in a JuMP model. I am considering the following options:

1. An integer variable with lb=-1, ub=1 (set of values {-1,0,1})
2. A semi-integer variable…(can take 0 as well as values between bounds) lb=1, ub=2 (set of values {0,1,2})

Is there a performance difference between these two options? Any better options that I have not mentioned? Basically I want it to be more performant than using 2 binary variables. Thoughts?

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [September 23, 2022, 7:49am UTC](https://discourse.julialang.org/t/trinary-ternary-variables/87679/2 "2022-09-23T07:49:26Z")

</div>

For any formulation choice, I would consider what (linear) relaxation is the result after relaxing any discrete variables. This can likely be only understood in conjunction with other problem structure. For example, a single integer variable x, 0 \<= x \<= 2 (or similar) might be useful if the relaxation’s one-dimensional interval produces some convex boundary, over the alternative of two binary variables y and z such that their relaxation is a two-dimensional region with an interior intersection with the feasible region.

---

<div class="post-metadata">

### Author: ![mtanneau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mtanneau/32/17787_2.png) [@mtanneau](https://discourse.julialang.org/u/mtanneau)
#### Post date: [September 23, 2022, 3:12pm UTC](https://discourse.julialang.org/t/trinary-ternary-variables/87679/3 "2022-09-23T15:12:26Z")

</div>

> Is there a performance difference between these two options?

In addition to the quality of the LP relaxation as already mentioned, I usually ask myself what this `{+1, 0, -1}` quantity represents. Is this modeling an alternative between 3 categorical options, e.g., choose between red/blue/green? Or is a physical quantity that can take value \{-1, 0, +1\}?

If it’s the former (3 categories), I would actually go with 3 binaries (see below). If it’s the latter, the integer variable with bounds seems more intuitive. The semi-integer approach would not be my first choice, because it’s mostly intended to distinguish between “zero” and “not zero”.

> Any better options that I have not mentioned?

You can also use 3 binaries: x\_{-1}, x\_{0}, x\_{+1}, and the constraint x\_{-1} + x\_{0} + x\_{+1} = 1.  
The resulting formulation has more variables, but it typically has a better LP relaxation, and MIP solvers like Gurobi/CPLEX will be better at detecting structure and propagating it (especially when branching).

---

<div class="post-metadata">

### Author: ![Leveringhaus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leveringhaus/32/218081_2.png) [@Leveringhaus](https://discourse.julialang.org/u/Leveringhaus)
#### Post date: [August 6, 2025, 10:16am UTC](https://discourse.julialang.org/t/trinary-ternary-variables/87679/4 "2025-08-06T10:16:45Z")

</div>

Hi,

I found this topic while also trying to implement ternary variables in optimization problems.

To my knowledge, your second variant (a semi-integer variable) produces an additional binary variable and corresponding constraints:  
b = {0;1}  
x \<= b \* ub  
x \>= b \* lb  
If you don’t need this binary information in other parts of your optimization model, I don’t see advantages of the second variant. You finally have an integer variable (that is a hidden binary variable, because it only has two values: y=x-1) and a binary variable. At best, this is as performant as using 2 binary variables.

Besides the mentioned variant with three binaries, there are (at least) some more variants:  
{-1;0;1}: x = b\_1 - b\_2 (eventually with b\_1 + b\_2 \<= 1 to prevent two solutions for zero: 0 = 0 - 0 = 1 - 1)  
{0;1;2}: x = b\_1 + b\_2 (eventually with b\_2 \<= b\_1 to order the binaries)  
{0;1;2}: x = b\_1 + 2 \* b\_2 (logarithmic expansion, limited by lb \<= x \<= ub or in this simple case by b\_1 + b\_2 \<= 1)

@chelseas, how did you finally decide to model the ternaries?

Does anybody know some literature about ternary variables in optimization? I didn’t find something helpfull.

---

<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: [August 6, 2025, 11:43pm UTC](https://discourse.julialang.org/t/trinary-ternary-variables/87679/5 "2025-08-06T23:43:56Z")

</div>

Hi @Leveringhaus, welcome to the forum 😄

Some solvers have specialized support for semi-integer variables. For others, JuMP will automatically add the binary. They’re more intended for sets that are not contiguous, like 0 \cup \{5, 6\}.

I’d use @mtanneau’s suggestion of

```julia
model = Model()
@variable(model, x[1:3], Bin)
@constraint(model, sum(x) == 1)

```
