檢測重疊週期的算法[重複]

本文翻譯自:Algorithm to detect overlapping periods [duplicate]

This question already has an answer here: 這個問題在這裏已有答案:

I've to detect if two time periods are overlapping. 我要檢測兩個時間段是否重疊。
Every period has a start date and an end date. 每個期間都有開始日期和結束日期。
I need to detect if my first time period (A) is overlapping with another one(B/C). 我需要檢測我的第一個時間段(A)是否與另一個時間段(B / C)重疊。
In my case, if the start of B is equal to the end of A, they are not overlapping(the inverse too) 在我的情況下,如果B的起點等於A的結尾,則它們不重疊(反之亦然)
I found the following cases: 我發現了以下情況:

在此輸入圖像描述

So actually I'm doing this like this: 所以實際上我這樣做是這樣的:

tStartA < tStartB && tStartB < tEndA //For case 1
OR
tStartA < tEndB && tEndB <= tEndA //For case 2
OR
tStartB < tStartA  && tEndB > tEndA //For case 3

(The case 4 is taken in the account either in case 1 or in case 2) (案例4在案例1或案例2中被記入帳戶)

It works , but it seems not very efficient. 有效 ,但似乎效率不高。

So, first is there an existing class in c# that can modelize this(a time period), something like a timespan, but with a fixed start date. 所以,首先在c#中有一個現有的類可以對此進行建模(一個時間段),類似於時間跨度,但具有固定的開始日期。

Secondly: Is there already ac# code(like in the DateTime class) which can handle this? 第二:是否已經有ac#代碼(比如在DateTime類中)可以處理這個問題?

Third: if no, what would be your approach to make this comparison the most fast? 第三:如果不是,那麼你最快速地進行這種比較的方法是什麼?


#1樓

參考:https://stackoom.com/question/uhae/檢測重疊週期的算法-重複


#2樓

Simple check to see if two time periods overlap: 只需檢查兩個時間段是否重疊:

bool overlap = a.start < b.end && b.start < a.end;

or in your code: 或者在你的代碼中:

bool overlap = tStartA < tEndB && tStartB < tEndA;

(Use <= instead of < if you change your mind about wanting to say that two periods that just touch each other overlap.) (如果你改變主意想要說兩個相互接觸的時期重疊,那就用<=代替<


#3樓

There is a wonderful library with good reviews on CodeProject: http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET 有一個很棒的圖書館,對CodeProject有很好的評價: http//www.codeproject.com/Articles/168662/Time-Period-Library-for-NET

That library does a lot of work concerning overlap, intersecting them, etc. It's too big to copy/paste all of it, but I'll see which specific parts which can be useful to you. 那個庫在重疊,交叉它們等方面做了很多工作。複製/粘貼它們太大了,但是我會看到哪些特定的部分對你有用。


#4樓

How about a custom interval-tree structure? 自定義區間樹結構怎麼樣? You'll have to tweak it a little bit to define what it means for two intervals to "overlap" in your domain. 您需要稍微調整一下,以定義在您的域中“重疊”兩個間隔的含義。

This question might help you find an off-the-shelf interval-tree implementation in C#. 這個問題可能有助於您在C#中找到現成的區間樹實現。


#5樓

You can create a reusable Range pattern class : 您可以創建可重用的Range模式類:

public class Range<T> where T : IComparable
{
    readonly T min;
    readonly T max;

    public Range(T min, T max)
    {
        this.min = min;
        this.max = max;
    }

    public bool IsOverlapped(Range<T> other)
    {
        return Min.CompareTo(other.Max) < 0 && other.Min.CompareTo(Max) < 0;
    }

    public T Min { get { return min; } }
    public T Max { get { return max; } }
}

You can add all methods you need to merge ranges, get intersections and so on... 您可以添加合併範圍,交叉點等所需的所有方法......


#6樓

I don't believe that the framework itself has this class. 我不相信框架本身就有這個類。 Maybe a third-party library... 也許是第三方圖書館......

But why not create a Period value-object class to handle this complexity? 但是爲什麼不創建一個Period值對象類來處理這種複雜性呢? That way you can ensure other constraints, like validating start vs end datetimes. 這樣您就可以確保其他約束,例如驗證開始日期和結束日期時間。 Something like: 就像是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Whatever.Domain.Timing {
    public class Period {
        public DateTime StartDateTime {get; private set;}
        public DateTime EndDateTime {get; private set;}

        public Period(DateTime StartDateTime, DateTime EndDateTime) {
            if (StartDateTime > EndDateTime)
                throw new InvalidPeriodException("End DateTime Must Be Greater Than Start DateTime!");
            this.StartDateTime = StartDateTime;
            this.EndDateTime = EndDateTime;
        }


        public bool Overlaps(Period anotherPeriod){
            return (this.StartDateTime < anotherPeriod.EndDateTime && anotherPeriod.StartDateTime < this.EndDateTime)
        }

        public TimeSpan GetDuration(){
            return EndDateTime - StartDateTime;
        }

    }

    public class InvalidPeriodException : Exception {
        public InvalidPeriodException(string Message) : base(Message) { }    
    }
}

That way you will be able to individually compare each period... 這樣你就可以單獨比較每個時期......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章