'how to model a GEKKO constraint to guarantee the count of variables with same value > k

I have the following objective function :
Minimize(sum(abs(di[i]-d[i]) ) )

and I want to add a constraint to make sure that d[i] is appeared at least k times in d
d is a vector of ordered integers like d=[14, 14, 13, 12, 12, 11, 11, 9, 8, 8, 6, 6, 5, 5, 5, 5, 3, 3, 2, 1]

I am using GEKKO to solve it, but I didn't manage to formulate the constraint
this is the code for solving the objective function

from gekko import GEKKO
z = GEKKO()
z.options.SOLVER=1  # APOPT is an MINLP solver
d=[14, 14, 13, 12, 12, 11, 11, 9, 8, 8, 6, 6, 5, 5, 5, 5, 3, 3, 2, 1] 
n=len(d)
di = [z.Var(i,lb=i,ub=len(d),integer=True) for i in d]
#Objective function
z.Obj(sum(abs(di[i]-d[i])for i in range(n)) )
z.solve()

for Example : for k = 3 , I would like to get
di = [14, 14, 14, 12, 12, 12, 12, 9, 9, 9, 6, 6, 6, 5, 5, 5, 3, 3, 3, 3]



Solution 1:[1]

Here is a strategy to count the occurrences of each in the list d.

import numpy as np
from gekko import GEKKO
m = GEKKO(remote=True)
# create x / xi arrays
d=[14,14,13,12,12,11,11,9,8,8,6,6,5,5,5,5,3,3,2,1]
n=len(d)
di = [m.Param(i,lb=1,ub=14,integer=True) for i in d]
# count functions
bins = np.arange(1,15,1); nb = len(bins)
bC = m.Array(m.Var,(nb,n))
for j,b in enumerate(bins):
    bL = [m.if3(di[i]-(b-0.1),0,1) for i in range(n)]
    bU = [m.if3(di[i]-(b+0.1),1,0) for i in range(n)]
    m.Equations([bC[j,i]==bU[i]*bL[i] for i in range(n)])
k = m.Array(m.Var,nb,lb=0)
m.Equations([k[j]==m.sum(bC[j,:]) for j in range(nb)])
m.Minimize(m.sum([(di[i]-d[i])**2 for i in range(n)]))
m.options.SOLVER=1
m.solve()

#print('bC=',bC)
print('k=',k)

This produces a solution:

 Successful solution
 
 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :   0.524600000000646      sec
 Objective      :   0.000000000000000E+000
 Successful solution
 ---------------------------------------------------
 
k= [[1.0] [1.0] [2.0] [0.0] [4.0] [2.0] [0.0] [2.0] [1.0] [0.0] [2.0] [2.0]
 [1.0] [2.0]]

I tried setting di = [m.Var(i,lb=1,ub=14,integer=True) for i in d] with k = m.Array(m.Var,nb,lb=3) but then the solver fails with no feasible solution because all of the k values must be greater than 3. Maybe someone else can figure out a clever formulation so that k is either zero or >=3.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Hedengren