You could try a brute-force grid search:
my_function <- function(param, q, m){
out <- sum(-param*q + param*m)
-out
}
q <- c(0.6, 0.14, 0.18)
m <- c(0, 2.5 , 4.2)
library("NMOF")
ans <- gridSearch(fun = my_function,
lower = c(0, 0, 0),
upper = c(3, 3, 3),
n = 4, ## 4 levels from lower to upper: 0,1,2,3
q = q, m = m)
The answer is a list of all the possible combinations and their objective-function values:
ans
## $minfun
## [1] -19.14
##
## $minlevels
## [1] 0 3 3
##
## $values
## [1] 0.00 0.60 1.20 1.80 -2.36 -1.76 -1.16 -0.56 -4.72 -4.12
## [11] -3.52 -2.92 -7.08 -6.48 -5.88 -5.28 -4.02 -3.42 -2.82 -2.22
## [21] -6.38 -5.78 -5.18 -4.58 -8.74 -8.14 -7.54 -6.94 -11.10 -10.50
## [31] -9.90 -9.30 -8.04 -7.44 -6.84 -6.24 -10.40 -9.80 -9.20 -8.60
## [41] -12.76 -12.16 -11.56 -10.96 -15.12 -14.52 -13.92 -13.32 -12.06 -11.46
## [51] -10.86 -10.26 -14.42 -13.82 -13.22 -12.62 -16.78 -16.18 -15.58 -14.98
## [61] -19.14 -18.54 -17.94 -17.34
##
## $levels
## $levels[[1]]
## [1] 0 0 0
##
## $levels[[2]]
## [1] 1 0 0
##
## $levels[[3]]
## [1] 2 0 0
##
## .....
##
## $levels[[64]]
## [1] 3 3 3
The levels are non-negative integers, but their sum is unconstrained. To add a sum constraint, either check in the objective function and return a large value if the particular solution violates the constraint (i.e. the solution gets marked as bad). Or filter the results; for instance, suppose the sum should be 2:
valid <- sapply(ans$levels, sum) == 2
ans$values[valid]
## [1] 1.20 -1.76 -4.72 -3.42 -6.38 -8.04
ans$levels[valid]
## [[1]]
## [1] 2 0 0
##
## [[2]]
## [1] 1 1 0
##
## [[3]]
## [1] 0 2 0
##
## [[4]]
## [1] 1 0 1
##
## [[5]]
## [1] 0 1 1
##
## [[6]]
## [1] 0 0 2
Then keep only the best of the valid solutions.
best <- which.min(ans$values[valid])
ans$values[valid][best]
## [1] -8.04
ans$levels[valid][best]
## [[1]]
## [1] 0 0 2