Home > Enterprise >  Generating four complementary intervals between 0 and 1
Generating four complementary intervals between 0 and 1

Time:07-14

How do I generate a list that contains four tuples and each tuple is compose by two numbers between 0.0 and 1.0 following this rules:

  • The first and the second number of each tuple cannot be the samecov
  • The second number must be bigger than the first one
  • The range cover by all four tuples must add 1
  • The range covered by each tuple cannot have a intersection

(0.01, 0.1), (0.1,0.2), (0.3,1), (0.2,0.29) -> acceptable

(0.1,0.2), (0.2,0.3) ,(0.2,0.3) ,(0.4,0.5) -> repeated interval

(0.1, 0.2), (0.30000000000000004, 0.5), (0.4, 0.8), (0.6, 0.9) -> the range between the four tuples not add to 1 or 100%

So far I code this logic but I'm not respecting the condition for the ranges to be complementary

interval_range = range(0, 100, 10)
interval = [
    (lowerlimit, upperlimit)
    for lowerlimit, upperlimit in product(interval_range, interval_range)
    if lowerlimit < upperlimit
]

interval_final = []
for one, two, three, four in product(interval, interval, interval, interval):
    size = one   two   three   four
    size_no_dup = set(size)
    if sum([one[1]-one[0],two[1]-two[0],three[1]-three[0],four[1]-four[0]]) == 100 and len(size) == len(size_no_dup):
        interval_final.append((one, two, three, four))
        break #just to see if the logic is working

CodePudding user response:

Based on the discussion in the comments, this solution uses ints from 0 to 100 rather than floats, and gives non-overlapping ranges whose widths sum to 100.

This uses itertools.pairwise which is new in Python 3.10.

import random
import itertools

cuts = random.sample(range(1, 100), k=3)  # 3 guaranteed different random numbers from 1 to 99 inclusive
ranges = list(itertools.pairwise([0]   sorted(cuts)   [100]))
print(ranges)

Example output:

[(0, 11), (11, 63), (63, 72), (72, 100)]

If you want multiple combinations, you can wrap this in a for loop. If you want to reproducibly generate the same series of solutions, set random.seed to a fixed value.

For earlier versions of Python 3, an alternative is:

import random

cuts = random.sample(range(1, 100), k=3)
points = [0]   sorted(cuts)   [100]
ranges = [(points[i], points[i 1]) for i in range(len(points)-1)]
print(ranges)

To enumerate every valid combination:

valid = []
for x in range(1, 98):
    for y in range(x 1, 99):
        for z in range(y 1, 100):
            valid.append([(0, x), (x, y), (y, z), (z, 100)])
print(len(valid))
print(valid[0])
print(valid[-1])

prints:

156849
[(0, 1), (1, 2), (2, 3), (3, 100)]
[(0, 97), (97, 98), (98, 99), (99, 100)]
  • Related