Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在附加距离落在另一个间隔内的间隔中找到最小值?_Python_Python 3.x_Algorithm - Fatal编程技术网

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

假设我有一个区间[360420],一个89的距离和一组区间[480540],[600660],[10201080]和[12001260][ 在391 391+89=480中设置的一个区间内,第一个区间上加上89的第一个值

在python中,获得这个结果最有效的算法或实现是什么


我知道有可能以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为增量通过第一个区间的回路。