2013-04-30 16 views
5

Ho un elenco di elementi di lavoro. Ogni oggetto di lavoro ha un inizio e un orario di fine.Ottieni interruzioni da un elenco di volte

Quindi, in pratica sembra che questo:

List<Work> works = new List<Work>(); 
works.Add(new Work(
    new DateTime(2013, 4, 30, 9, 0, 0), 
    new DateTime(2013, 4, 30, 11, 0, 0)); 

Ora voglio ottenere il tempo totale che è stato lavorato. Di nuovo, fondamentalmente questo è facile:

09:00-11:00 => 2 hours 
13:00-17:00 => 4 hours 
---- 
06:00 hours 

È solo la somma.

Ma ora diventa difficile: come faccio a calcolare questa somma se voglio estrarre tempi paralleli?

esempio

09:00-11:00 => 2 hours 
10:00-11:30 => 1.5 hours 
13:00-17:00 => 4 hours 
---- 
06:30 hours 

è di 6,5 ore, ma la somma è di 7,5 ore. Il fatto che due elementi di lavoro siano mappati sull'intervallo tra le 10 e le 11 fa la differenza.

Come potrei risolvere questo per un numero arbitrario di elementi di lavoro che possono sovrapporsi l'un l'altro in praticamente in ogni modo possibile (circostante, inizio sovrapposizioni, sovrapposizioni di fine, incluso)?

+0

Ci sono intervalli impostati (ad esempio 0,5 ore è il minimo)?Se è così, un modo semplice sarebbe quello di controllare ogni mezz'ora di spazio per un oggetto di lavoro che lo circonda e basta aggiungerli tutti. –

+0

Purtroppo no, i tempi sono completamente arbitrari e possono variare da secondi a più giorni. –

+1

Ora l'ho risolto usando questa libreria: Facile, diretto e funziona :-) –

risposta

5

Creare coppie di (tempo, valore), in cui il valore è +1 per l'inizio del lavoro e -1 per la fine. Quindi ordina le coppie per data. Facendo scorrere la lista che hai, puoi calcolare la somma dei valori - quando è positivo, il lavoro sta "procedendo". Durante l'iterazione, segna i momenti in cui la somma dei valori passa da 0 a positiva e da positiva a 0. Otterrai intervalli disgiunti.

Esempio:

11 - 13, 12 - 16, 15 - 17, 18 - 19

si dà (11, 1) (12, 1) (13 -1) (15, 1) (16, -1) (17, -1) (18, 1) (19, -1)

la somma va (11, 1) (12, 2) (13 1) (15 , 2) (16, 1) (17, 0) (18, 1) (19, 0),

quindi i periodi disgiunti sono (11, 17) e (18, 19)

+2

Codice di esempio: http://pastebin.com/KnhRwrsX Sentiti libero di modificare la tua risposta, se vuoi. –

+0

L'ho implementato e funziona perfettamente :-) Grazie per il suggerimento! –

+0

Grazie per il campione, l'ho visto troppo tardi, ma ora confronterò la tua contro la mia soluzione e prendo il meglio di entrambi :-)) –

2

Hmm, una volta ho risolto un problema simile (non con i tempi, ma con intervalli che si sovrappongono). Soluzione Ho applicato era piuttosto semplice:

  1. Ordina gli elementi in ordine crescente
  2. A partire dal primo elemento, vedere se si sovrappone con l'elemento successivo
  3. Se si tratta - rielaborare gli elementi, sezione estratto overlaping come nuovo elemento , modificare vecchi elementi terminare prima/dopo iniziare sovrapposizione periodo
  4. Inserire elemento appena creato tra due elementi vecchi
  5. continuare l'elaborazione

Dovrebbe funzionare bene, tuttavia se si dispone di enormi quantità di dati ci potrebbe essere un modo migliore per risolverlo. È solo l'approccio più semplice (almeno per me). Si finirà con un elenco di volte senza sezioni sovrapposte, quindi sarà possibile solo scorrere l'elenco e riepilogare i tempi.

Problemi correlati