Home > Software design >  Split number in random parts with constrain
Split number in random parts with constrain

Time:07-08

I am trying to find a smart way for splitting a number (eg 50) into a number of random parts (e.g. 20) BUT under the constrain that each generated random value cannot be greater than a specific value (e.g. 4).

So for example in this case I would expect as an output a vector of 20 values of which sum is 50 but none of the 20 values is greater than 4 (e.g 2.5, 1.3, 3.9 etc..)

I had a look at similar questions but from what i see these are dealing with splitting a number into equal or random parts but none of them included the constrain, which is the bit i am stuck with! Any help would be higly appreciated!!

CodePudding user response:

set.seed(42)
repeat {
  vec <- runif(20)
  vec <- 50 * vec/sum(vec)
  if (all(vec <= 4)) break
} 
sum(vec)
# [1] 50
# [1] 50
vec
#  [1] 3.7299658 3.8207653 1.1666852 3.3860087 2.6166080 2.1165253 3.0033133 0.5490801 2.6787741 2.8747815 1.8663641
# [12] 2.9320577 3.8109668 1.0414675 1.8849202 3.8327490 3.9885516 0.4790347 1.9367197 2.2846613

Note: it is feasible with certain combinations that this could run "forever" (improbable to find a vector where all values are under 4). This works well here, but if you (say) change 20 to 10, it will never succeed (and will loop forever).

CodePudding user response:

Another possible solution (by limiting the range of the interval of the uniform distribution, it is more likely to get a solution):

set.seed(123)

x <- 50
n <- 20
threshold <- 4

gotit <- F
while (!gotit)
{  
  v <- round(runif(n, 0, x/(n/2)), 1)
  
  if (sum(v) == x & all(v <= threshold))
    gotit <- T
}

v

#>  [1] 2.2 3.0 2.2 3.0 3.0 0.5 2.4 2.5 2.7 4.0 1.0 1.7 1.2 2.8 2.9 3.3 2.9 3.0 3.0
#> [20] 2.7
  • Related