Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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_Algorithm - Fatal编程技术网

Python 如何获取多个周期的交点

Python 如何获取多个周期的交点,python,algorithm,Python,Algorithm,Psudo代码: timelines = [ (range(<from>, <to>), range(<from>, <to>)), (range(<from>, <to>), range(<from>, <to>)), (range(<from>, <to>), range(<from>, <to>)), ] 如何计算这些交点

Psudo代码:

timelines = [
    (range(<from>, <to>), range(<from>, <to>)),
    (range(<from>, <to>), range(<from>, <to>)),
    (range(<from>, <to>), range(<from>, <to>)),
]
如何计算这些交点

我用python编写代码,但欢迎用任何编程语言回答, 因为我只需要了解算法

我正在用python编写代码,但欢迎用任何编程语言回答,因为我只需要理解算法

如果您只需要伪代码,一种算法是:

intersections = total_range
for timeline in timelines:
    intersections = intersection(timeline,intersections)

对于实施交叉口,有几种不同的方法。一种是使用set函数,尽管您必须转换为集合,如果您不想将集合作为输出,则必须转换回:
crossions=crossions.crossion(timeline)
。另一种方法是列表理解:
crosss=[time\u point for time\u point in crosss if time\u point in timeline]

步骤0:创建一个
范围
类以方便:

from collections import namedtuple
Range = namedtuple("Range", ["start", "end"])
步骤1:制作一个函数,计算两个范围之间的交点。此功能适用于包含两个可比较点的任何情况:

def intersect(range1, range2):
    new_range = Range(
        max(range1.start, range2.start),
        min(range1.end, range2.end)
    )
    return new_range if new_range.start < new_range.end else None
步骤3:使用“相交两个”的范围集列表:

def intersect_all(ranges):
    return reduce(intersect_two, ranges)
为了简单起见,我使用整数,但它应该与
datetime
对象同样有效:

>>> timelines = [
...     (Range(0, 11), Range(15, 20)),
...     (Range(8, 16), Range(19, 25)),
...     (Range(0, 10), Range(15, 22)),
... ]
>>>
>>> for intersection in intersect_all(timelines):
...     print(intersection)
...
Range(start=8, end=10)
Range(start=15, end=16)
Range(start=19, end=20)

以下是我对@Felk答案的实现:

from functools import reduce
from psycopg2.extras import DateTimeTZRange


def _DateTimeTZRange_intersect(range1, range2):
    new_range = DateTimeTZRange(
        max(range1.lower, range2.lower),
        min(range1.upper, range2.upper)
    )
    return new_range if new_range.lower < new_range.upper else None

def DateTimeTZRange_intersect(*args):
    return reduce(_DateTimeTZRange_intersect, args) if args else []


def _DateTimeTZRange_intersect_2d(ranges1, ranges2):
    for range1 in ranges1:
        for range2 in ranges2:
            intersection = DateTimeTZRange_intersect(range1, range2)
            if intersection:
                yield intersection

def DateTimeTZRange_intersect_2d(*args):
    return reduce(_DateTimeTZRange_intersect_2d, args) if args else []
从functools导入reduce
从psycopg2.extras导入DateTimeTZRange
定义日期时间范围相交(范围1,范围2):
新范围=日期时间范围(
最大值(范围1.更低,范围2.更低),
最小值(范围1.上限,范围2.上限)
)
如果new_range.lower我会考虑使用Python中的DATETIMLE模块建立日期范围,然后循环遍历这些顺序的日期列表并识别任何匹配。然后,根据没有间隔的最近日期和最不最近日期创建一个新的日期列表。您可能会从中找到有用的信息。尽管问题是根据日期/时间范围来表述的,但任何范围类型都可以进行类似的测试。在上下文中,您可能需要计算两组范围的交点,然后获取该结果并计算其与第三个范围的交点。一个简单的优化是注意,如果结果范围为空,您可以停止,因为结果也将为空。我只想要所有时间线上的周期相交的周期。我从您的psudo代码中了解到的内容可以通过
set.intersection([set(r)for ranges for r in timeline])
@demux来实现,如果您插入
*
set.intersection(*[set(r)for ranges for timeline for r in ranges])
可能会起作用,但这对我来说是有效的。
>>> timelines = [
...     (Range(0, 11), Range(15, 20)),
...     (Range(8, 16), Range(19, 25)),
...     (Range(0, 10), Range(15, 22)),
... ]
>>>
>>> for intersection in intersect_all(timelines):
...     print(intersection)
...
Range(start=8, end=10)
Range(start=15, end=16)
Range(start=19, end=20)
from functools import reduce
from psycopg2.extras import DateTimeTZRange


def _DateTimeTZRange_intersect(range1, range2):
    new_range = DateTimeTZRange(
        max(range1.lower, range2.lower),
        min(range1.upper, range2.upper)
    )
    return new_range if new_range.lower < new_range.upper else None

def DateTimeTZRange_intersect(*args):
    return reduce(_DateTimeTZRange_intersect, args) if args else []


def _DateTimeTZRange_intersect_2d(ranges1, ranges2):
    for range1 in ranges1:
        for range2 in ranges2:
            intersection = DateTimeTZRange_intersect(range1, range2)
            if intersection:
                yield intersection

def DateTimeTZRange_intersect_2d(*args):
    return reduce(_DateTimeTZRange_intersect_2d, args) if args else []