2010-04-29 10 views
5

Birden çok tarih aralığı ile çakışan kavşakların sayısı arasındaki kesişim konumlarını hesaplamam gerekiyor. Sonra hangi kesişen bölümlerin her birinin hangi tarih/zaman aralıkları ile örtüştüğünü göstermem gerekiyor. Bundan biraz daha karmaşıktır, bu yüzden bir örnek vererek açıklamak için elimden gelenin en iyisini yapacağım. VB.Net'te çalışıyorum, fakat C# örneklerinin her ikiside çalışmamın yanı sıra kabul edilebilir.Birden çok tarih/saat aralığı arasındaki kesişme yerini ve konumunu hesaplayın.

Aynı sistemi içeren birçok yüksek riskli görevimiz var. Aşağıda, başlangıç ​​ve bitiş tarihi/saatleri ile HR1/2/3/4 adlı üç örnek iş var.

  • HR1 {1/6/2010 10:00 - 15:00 1/6/2010}
  • HR2 {1/6/2010 11:00 - 18:00 1/6/2010}
  • HR3 {1/6/2010 12:00 pm - 1/6/2010 14:00}
  • HR4 {1/6/2010 - 18:00 1/6/2010 20:00}

Son sonucun olmasını istediğim aşağıda gösterilmiştir. Herhangi bir şekilde tanımlamakta zorlanıyorum ama örnek olarak.

  • HRE1 {1/6/2010 10:00 - 1/6/2010 11:00} -
  • {sadece çözeltide gerekli değildir okunabilmesi için, Bitiş Zamanı Bölünmüş 1} 1
  • kesiştirir HRE1 {1/6/2010 11:00 - 1/6/2010 12:00} - Kesişim 2
  • HRE2 {1/6/2010 11:00 - 1/6/2010 12:00} - Kesişim 2
  • {Bitiş Saati Bölünmüş 2, sadece, çözeltide gerekli değildir okunabilmesi için}
  • HRE1 {1/6/2010 00:00 - 1/6/2010 14:00} - 3
  • kesiştirir
  • HRE2 {1/6/2010 12:00 - 1/6/2010 14:00} - Kesişim 3
  • HRE3 {1/6/2010 12:00 - 1/6/2010 14:00} - Kesişme noktaları 3
  • {Bitiş Saati Bölünmüş 3, sadece, çözeltide gerekli değildir okunabilmesi için}
  • HRE1 {1/6/2010 14:00 - 1/6/2010 15:00} - 2
  • HRE2 {kesiştirir 1/6/2010 14:00 - 1/6/2010 15:00} - Intersects 2
  • {End Okumak 4, sadece okunabilirlik için, çözüme gerek yoktur}
  • HRE2 {1/6/2010 15 : 00 - 1/6/2010 18:00} - Kesişen 1
  • {Bitiş Saati Bölünmüş 5, sadece, çözeltide gerekli değildir okunabilmesi için}
  • HR4 {1/6/2010 - 18:00 1/6/2010 20:00} - 1

Herhangi bir yardım kesiştirir çok takdir edilecektir.

var timePoints = (from r in ranges select r.Start) 
    .Concat(from r in ranges select r.End) 
    .Distinct().OrderBy(dt => dt).ToArray(); 

var intersectionGroups = from i in Enumerable.Range(0, timePoints.Length - 1) 
         let start = timePoints[i] 
         let end = timePoints[i + 1] 
         select new 
         { 
          Start = start, 
          End = end, 
          Ranges = 
           from range in ranges 
           where range.Start <= start && range.End >= end 
           select range 
         }; 

var intersections = from intGroup in intersectionGroups 
        let count = intGroup.Ranges.Count() 
        from range in intGroup.Ranges 
        select new 
        { 
         Range = range, 
         Start = intGroup.Start, 
         End = intGroup.End, 
         Count = count 
        }; 

Sana sonuçla yapmak istiyorsun bilmiyorum ama intersections yerine intersectionGroups kullanmak daha iyi olabilir:

+1

Sorunu * iki * zaman aralığı için çözebilir misiniz? –

cevap

5
var timePoints = (from r in ranges select r.Start) 
    .Concat(from r in ranges select r.End) 
    .Distinct().OrderBy(dt => dt).ToArray(); 

var intersections = from i in Enumerable.Range(0, timePoints.Length - 1) 
        let start = timePoints[i] 
        let end = timePoints[i + 1] 
        from range in ranges 
        where range.Start <= start && range.End >= end 
        select new { Range = range, Start = start, End = end }; 

DÜZENLEME: kavşakları sayar Modifiye kod .

+0

WOW!Bu aradığım şeye çok yakın. İlk başta anlamadım ama VS içinde koştuktan sonra bir dakika sonra mantıklı. İki küçük şey aklıma geldi ve birincisi orijinal yazıya koymadığım için benim hatamdı. İlk olarak, kaç tane aralığın üst üste geldiği anlatmıyor. Yani 11:00 ile 12:00 arasındaki zaman aralığı için 2 değeri olurdu. Belki de OverlapCount ya da bir şey olarak adlandırılan ek bir özellik. İkincisi: Bahsetmediğim durum buydu. Dizide bulunan ve hiçbir şeyle örtüşmeyen öğeler bırakılır. Onları tutabilmenin bir yolu var mı? Bunu yazıya ekledim. – Peter

+0

Kodum, hiçbir şeyle çakışmayan aralıklar bırakmıyor (örneğinizde HR4 gibi). Sayılara bakacağım. – svick

+0

svick, arkadaşımın güzellik olduğuna dair bir şey. Aslında, yayınlamadan önce problem için bir çözüm geliştirdim, ama o kadar berbattı ki, basit bir çözüm olması gerektiğini biliyordum. Bir kez daha linq günü kaydeder. Yardım için tekrar teşekkürler svick. – Peter

İlgili konular