Python – Non-overlapping Random Ranges
Last Updated :
01 Jun, 2023
Sometimes, while working with Python, we can have problem in which we need to extract N random ranges which are non-overlapping in nature and with given range size. This can have applications in which we work with data. Lets discuss certain way in which this task can be performed.
Method : Using any() + randint() + loop This is brute force way in which this task can be performed. In this we extract random ranges using randint(), and check for non-repetition of number ranges using any() and loop.
Python3
import random
N = 7
K = 5
tot = 10000
res = set ()
for _ in range (N):
temp = random.randint( 0 , tot - K)
while any (temp > = idx and temp < = idx + K for idx in res):
temp = random.randint( 0 , tot - K)
res.add(temp)
res = [(idx, idx + K) for idx in res]
print ( "The N Non-overlapping Random ranges are : " + str (res))
|
Output:
The N Non-overlapping Random ranges are : [(5347, 5352), (7108, 7113), (5479, 5484),
(1906, 1911), (2228, 2233), (5206, 5211), (3260, 3265)]
Time Complexity: O(n*n) where n is the total number of values in the list
Auxiliary Space: O(n) where n is the total number of values in the list
Approach 2 : Using bisect and randint
Python3
import random
import bisect
def random_ranges(n, k, tot):
ranges = []
starts = [random.randint( 0 , tot - k) for _ in range (n)]
starts.sort()
for i in range ( 1 , n):
if starts[i] < = starts[i - 1 ] + k:
starts[i] = starts[i - 1 ] + k + 1
for start in starts:
ranges.append((start, start + k))
return ranges
n = 7
k = 5
tot = 10000
print (random_ranges(n, k, tot))
|
Output
[(1940, 1945), (3328, 3333), (3769, 3774), (3879, 3884), (7356, 7361), (7471, 7476), (9240, 9245)]
This approach uses bisect module to sort the start positions of the ranges and randint from random module to generate random start positions. The code then checks if the current start position is less than or equal to the previous start position + k, if so, it adjusts the current start position to the previous start position + k + 1.
Time complexity: O(nlogn) for sorting and O(n) for looping, so O(nlogn + n) in total.
Auxiliary Space: O(n) for storing the start positions and ranges.
Method: Using List Comprehension
Generate a list of n random start points using list comprehension, where each start point is a random integer between 0 and tot-k inclusive.
Sort the start points in ascending order.
Generate a list of end points using list comprehension, where each end point is the corresponding start point plus k.
Use a loop to iterate through the start points and end points simultaneously.
If the current start point is less than or equal to the previous end point, then set the current start point to be the previous end point plus 1.
Return a list of tuples, where each tuple contains a start point and its corresponding end point.
Python3
import random
def random_ranges(n, k, tot):
start_points = sorted ([random.randint( 0 , tot - k) for _ in range (n)])
end_points = [start + k for start in start_points]
for i in range ( 1 , n):
if start_points[i] < = end_points[i - 1 ]:
start_points[i] = end_points[i - 1 ] + 1
end_points[i] = start_points[i] + k
return [(start, end) for start, end in zip (start_points, end_points)]
n = 7
k = 5
tot = 10000
print (random_ranges(n, k, tot))
|
Output
[(81, 86), (1454, 1459), (3398, 3403), (4467, 4472), (7559, 7564), (7577, 7582), (9551, 9556)]
Time complexity: O(n log n), due to the sorting step.
Auxiliary space: O(n), to store the lists of start points and end points.
Method: Using Numpy
In this method, np.random.randint(0, tot-k, size=n) generates an array of n random integers between 0 and tot-k. np.sort() sorts the array in increasing order. start_points + k generates an array of end points. np.maximum(end_points[:-1], start_points[1:]) sets each end point to the maximum of its current value and the next start point, so that no two ranges overlap. list(zip(start_points, end_points)) combines the start points and end points into a list of tuples representing the random ranges.
Python3
import numpy as np
def random_ranges(n, k, tot):
start_points = np.sort(np.random.randint( 0 , tot - k, size = n))
end_points = start_points + k
end_points[: - 1 ] = np.maximum(end_points[: - 1 ], start_points[ 1 :])
return list ( zip (start_points, end_points))
n = 7
k = 5
tot = 10000
print (random_ranges(n, k, tot))
|
Output:
[(1098, 4710), (4710, 5609), (5609, 5706), (5706, 6048), (6048, 6577), (6577, 8902), (8902, 8907)]
Time complexity: O(n log n), dominated by the sorting step.
Auxiliary Space: O(n), where n is the number of ranges to generate.
Similar Reads
Python - Random range in list
We are given a list we need to find random range in list. For example, a = [10, 20, 30, 40, 50, 60] we need to find random ranges so that given output should be random list and it changes in every execution. Using random.samplerandom.sample can randomly pick elements from the list and preserve origi
2 min read
Python - Get Random Range Average
Given range and Size of elements, extract random numbers within a range, and perform average of it. Input : N = 3, strt_num = 10, end_num = 15 Output : 13.58 Explanation : Random elements extracted between 10 and 15, averaging out to 13.58. Input : N = 2, strt_num = 13, end_num = 18 Output : 15.82 E
5 min read
Python - N Random Tuples list
Sometimes, while working with Python records, we can have a problem in which we need to construct a random tuple list. This can have applications in many domains using gaming and day-to-day programming. Let's discuss specific ways in which this task can be performed in Python. Input: N = 4 R = 6 Out
3 min read
Python | Find overlapping tuples from list
Sometimes, while working with tuple data, we can have a problem in which we may need to get the tuples which overlap a certain tuple. This kind of problem can occur in Mathematics domain while working with Geometry. Let's discuss certain ways in which this problem can be solved. Method #1 : Using lo
5 min read
Python - Extract Missing Ranges
Given list of tuples, start range and end range values, extract the ranges that are missing from the list. Input : test_list = [(7, 2), (15, 19), (38, 50)], strt_val = 5, stop_val = 60 Output : [(5, 7), (2, 60), (2, 15), (19, 60), (19, 38), (50, 60)] Explanation : Missing element ranges starting fro
2 min read
Python - Generate Random String of given Length
Generating random strings is a common requirement for tasks like creating unique identifiers, random passwords, or testing data. Python provides several efficient ways to generate random strings of a specified length. Below, weâll explore these methods, starting from the most efficient. Using random
2 min read
Python - Random Numbers Summation
We need to do summation of random numbers. For example, n = [random.randint(1, 10) for _ in range(5)] it will generate random numbers [4, 8, 9, 4, 6] between 1 to 10 so the resultant output should be 29. Using random.randint()random.randint(a, b) function generates a random integer between a and b (
2 min read
Python | Remove random element from list
Sometimes, while working with Python lists, we can have a problem or part of it, in which we desire to convert a list after deletion of some random element. This can have it's application in gaming domain or personal projects. Let's discuss certain way in which this task can be done. Method : Using
3 min read
Slicing range() function in Python
range() allows users to generate a series of numbers within a given range. Depending on how many arguments the user is passing to the function, the user can decide where that series of numbers will begin and end as well as how big the difference will be between one number and the next.range() takes
2 min read
Python - Random insertion of elements K times
Given 2 list, insert random elements from List 2 to List 1, K times at random position. Input : test_list = [5, 7, 4, 2, 8, 1], add_list = ["Gfg", "Best", "CS"], K = 2 Output : [5, 7, 4, 2, 8, 1, 'Best', 'Gfg'] Explanation : Random elements from List 2 are added 2 times. Input : test_list = [5, 7, 4
5 min read