Python 如何在附加距离落在另一个间隔内的间隔中找到最小值?
假设我有一个区间[360420],一个89的距离和一组区间[480540],[600660],[10201080]和[12001260][ 在391 391+89=480中设置的一个区间内,第一个区间上加上89的第一个值 在python中,获得这个结果最有效的算法或实现是什么Python 如何在附加距离落在另一个间隔内的间隔中找到最小值?,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,假设我有一个区间[360420],一个89的距离和一组区间[480540],[600660],[10201080]和[12001260][ 在391 391+89=480中设置的一个区间内,第一个区间上加上89的第一个值 在python中,获得这个结果最有效的算法或实现是什么 我知道有可能以1的增量循环通过第一个间隔并得到结果,但是,我想知道是否有其他蛮力的特定算法…进行一次设置交集并取最小值: >>> interval = range(360, 420) >>&g
我知道有可能以1的增量循环通过第一个间隔并得到结果,但是,我想知道是否有其他蛮力的特定算法…进行一次设置交集并取最小值:
>>> interval = range(360, 420)
>>> distance = 89
>>> other_intervals = [range(480, 540), range(600, 660), range(1020, 1080), range(1200, 1260)]
>>> from functools import reduce
>>> min(
... set(range(interval.start + distance, interval.stop + distance))
... & reduce(set.union, map(set, other_intervals), set())
) - distance
391
设置交叉点并取最小值:
>>> interval = range(360, 420)
>>> distance = 89
>>> other_intervals = [range(480, 540), range(600, 660), range(1020, 1080), range(1200, 1260)]
>>> from functools import reduce
>>> min(
... set(range(interval.start + distance, interval.stop + distance))
... & reduce(set.union, map(set, other_intervals), set())
) - distance
391
这是一个比遍历范围内的每个整数快得多的算法。它迭代列表中的每个间隔,并使用比较和减法来找到所需的值。它是关于间隔列表长度的复杂性,是关于间隔大小的O1
class interval:
"An interval of the form [a, b["
def __init__(self, a, b):
self.a = a
self.b = b
def is_inside(self, other):
return any(other.a <= x < other.b for x in [self.a, self.b - 1])
def intersects(self, other):
return self.is_inside(other) or other.is_inside(self)
def find_intersection(self, others):
for i, other in enumerate(others):
if self.intersects(other):
# if other.a >= self.a, offset is the difference
# between other.a and self.a, otherwise self.a > other.a,
# so the lower bound of self is inside the other interval,
# so the offset is 0 away from the lower bound
offset = other.a - self.a if other.a >= self.a else 0
return i, offset
def __add__(self, offset):
return interval(self.a + offset, self.b + offset)
other_intervals = [interval(480, 540), interval(600, 660), interval(1020, 1080), interval(1200, 1260)]
# The interval [360, 420[ + 89 falls within the
# first interval in the list (index 0), and is 31 into
# the interval, (i.e. 360+31+89=480) hence the
# result (0, 31)
print((interval(360, 420) + 89).find_intersection(other_intervals))
# Neither a distance of 1 nor 100000 puts the
# first interval inside any of the others, so
# it returns None
print((interval(360, 420) + 1).find_intersection(other_intervals))
print((interval(360, 420) + 100000).find_intersection(other_intervals))
# 360 + 183 + 57 = 600, which is the lower bound of the
# second interval (index 1), hence the result (1, 57)
print((interval(360, 420) + 183).find_intersection(other_intervals))
# if the lower bound of the first interval is inside the
# other interval, the offset is 0: 360 + 121 = 481, whic
# is already inside [480, 540[, so nothing else needs to be added
print((interval(360, 420) + 121).find_intersection(other_intervals))
此函数返回间隔内的偏移量,例如,问题中的示例为31。如果要获得391,只需执行360+31即可。这里有一个算法,它比遍历范围内的每个整数快得多。它会遍历列表中的每个间隔,并使用比较和减法来查找期望值。间隔列表的长度取决于复杂性,间隔大小取决于O1
class interval:
"An interval of the form [a, b["
def __init__(self, a, b):
self.a = a
self.b = b
def is_inside(self, other):
return any(other.a <= x < other.b for x in [self.a, self.b - 1])
def intersects(self, other):
return self.is_inside(other) or other.is_inside(self)
def find_intersection(self, others):
for i, other in enumerate(others):
if self.intersects(other):
# if other.a >= self.a, offset is the difference
# between other.a and self.a, otherwise self.a > other.a,
# so the lower bound of self is inside the other interval,
# so the offset is 0 away from the lower bound
offset = other.a - self.a if other.a >= self.a else 0
return i, offset
def __add__(self, offset):
return interval(self.a + offset, self.b + offset)
other_intervals = [interval(480, 540), interval(600, 660), interval(1020, 1080), interval(1200, 1260)]
# The interval [360, 420[ + 89 falls within the
# first interval in the list (index 0), and is 31 into
# the interval, (i.e. 360+31+89=480) hence the
# result (0, 31)
print((interval(360, 420) + 89).find_intersection(other_intervals))
# Neither a distance of 1 nor 100000 puts the
# first interval inside any of the others, so
# it returns None
print((interval(360, 420) + 1).find_intersection(other_intervals))
print((interval(360, 420) + 100000).find_intersection(other_intervals))
# 360 + 183 + 57 = 600, which is the lower bound of the
# second interval (index 1), hence the result (1, 57)
print((interval(360, 420) + 183).find_intersection(other_intervals))
# if the lower bound of the first interval is inside the
# other interval, the offset is 0: 360 + 121 = 481, whic
# is already inside [480, 540[, so nothing else needs to be added
print((interval(360, 420) + 121).find_intersection(other_intervals))
此函数返回间隔内的偏移量,例如问题中的示例为31。如果要获得391,只需执行360+31。该算法相当于OP表示希望避免的暴力方法。setrange5为{0,1,2,3,4},因此setrangeinterval.start+distance,interval.stop+distance是范围内所有数字的集合,使集合的交点相当于以1为增量通过第一个区间的循环。该算法相当于OP表示希望避免的暴力方法。setrange5是{0,1,2,3,4},因此setrangeinterval.start+distance,interval.stop+distance是范围内所有数字的集合,使集合交点相当于以1为增量通过第一个区间的回路。