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
# Python3 code to demonstrate working of
# Non-overlapping Random Ranges
# Using loop + any() + randint()
import random
# initializing N
N = 7
# initializing K
K = 5
# Non-overlapping Random Ranges
# Using loop + any() + randint()
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]
# printing result
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
# Python3 code to demonstrate working of
# Non-overlapping Random Ranges
# Using numpy
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))
# initializing n
n = 7
# initializing k
k = 5
tot = 10000
#printing result
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 origin
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 - 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 (i
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
Generating random number list in Python In Python, we often need to generate a list of random numbers for tasks such as simulations, testing etc. Pythonâs random module provides multiple ways to generate random numbers. For example, we might want to create a list of 5 random numbers ranging from 1 to 100. This article explores different m
3 min read