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)]