Can I restrict variable to only a few values?

How should I write in CVX if a variable x can only take value in \{0.001, 0.01, 0.1\}?

x is an expression which can take the values 0.001, 0.01, or 0.1

variable b(2) binary
x = 0.001 + 0.009*b(1) + 0.099*b(2)
sum(b) <= 1

It works.
Thank you for your help.

In your example, if x(12) is variable and its sum is equal to another number. How should it be written?
i mean
x(12) varible
variable b(2) binary
x(1:12) ==0.001 + 0.009b(1) + 0.099b(2)
sum(b) <= 1
sum(x)==number( for example)
I wrote in this way, but because we have two equity, the answer was NAN error

In that example, the only number which could be feasible is
12*0.001
or
12*0.01
or
12*0.1

Depending on the other constraints, even those numbers don’t mean the overall problem has to be feasible.

If this doesn’t answer your question, you need to state the question more clearly, perhaps showing complete code, input data, and CVX and solver output, along with what you don’t like about that output.

CVX allows equality constraints, provided both sides are affine. But they might make the problem infeasible, in which case CVX would populate the CVX variables with NaN and inform you of the infeasibiliity (unless you have used the quiet option).

Edit: Given your also have the constraint sum(x) <= 1, number being 12*0.1 would be infeasible.

like that: if a variable p can only take value in -2 ,2, 0
cvx_begin quiet
cvx_solver Mosek
variable p(12)
variable z(2) binary
obj func for {simplicity ( minimize (0 )]
subject to
p==repmat(0+(-2)z(1)+2(z(2)),12,1);
sum(z)<=1;

                 sum(p)  ==14
              cvx_end

I want it to be 0 and -2 in some places according to the objective function, but in the end their sum should be equal to 14.

Your program is infeasible as written. Each of the 12 elements of p are identical. Therefore, everything other than the following will be infeasible.
sum(p) == -24
sum(p) == 0
sum(p) == 24

If you want to allow the elements of p to be different, which seems like a usual thing to do, this code would work

cvx_begin
variable z(12,2) binary
p = -2*z(:,1) + 2*z(:,2);
minimize(your_objective_function) % can use any combination of z and p
subject to
sum(z,2) <= 1
cvx_end

I have made the program a little simpler by making p an expression rather than a variable with a constraint, but that would work as well.

Also, don’t use quiet until everything is working as you want. That way you will see the solver and CVX output.

What should be done if the variable is a factor of two? that’s mean
…,-4,-2,0,2,4,6,…
Because if we use the above method, the number of binary variables will increase a lot and it will be very difficult to solve the problem. Is there another way?

variable x integer
y_is_even_integer = 2*x; % y_is_even_integer is created as an expression by assignment
y_lower_bound <= y_is_even_integer <= y_uuper_bound
% objective function and constraints constructed using y_is_even_integer

Hi Mark,

I am trying to solve a similar problem using CVX, where I want the values of my optimization variable x to be restricted in the set {-1,0,1}. No other constraints

Code snippet.

n = 16
A = 25600 x 16
B = 25600 x 1
cvx_begin
    variable x(n) binary 
    minimize(norm(A*x - B,1))  
cvx_end

What constraints should I add to the problem definition so that x can only belong to {-1,0,1}? Also, what is the most appropriate norm to consider in this case?

Thank you for your help

n = 16
A = 25600 x 16
B = 25600 x 1
cvx_begin
    variable x(n) integer
    minimize(norm(A*x - B,1))  
    -1 <= x <= 1
cvx_end

It’s your problem, so you have to decide which norm to use. I don’t see how x being in the set {-1,0,1} determines which norm is most appropriate.

1 Like

Hi Mark,

So, right now the solution I get mostly comprises of x values chosen as either 1 or -1, however, the values hardly ever go to zero. Of course, the solution is correct but can we add an additional constraint (for example, sum(abs(x(n))<M) to the problem, so that some of the optimization variables can be forced to zero? In my problem, this translates to saving energy by activating as few variables as possible.

Code:

n = 16
A = 25600 x 16
B = 25600 x 1
cvx_begin
variable x(n) integer
minimize(norm(A*x - B,1))
-1 <= x <= 1
cvx_end

You can use
sum(abs(x)) <= M
if you want to limit the number of non-zeros to no more than M.

1 Like

Thank you. That works perfectly.