<br><br><div class="gmail_quote">2009/10/19  <span dir="ltr">&lt;<a href="mailto:michele@nectarine.it">michele@nectarine.it</a>&gt;</span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Salve a tutti,<br>
ho un problema interessante che vorrei discutere con voi.<br>
In generale, sono interessato a due eventi che sono intermittenti (=<br>
iniziano e finiscono casualmente) e concorrenti (= capitano<br>
contemporaneamente e non).<br>
<br>
Per capirci meglio, in input ho due liste che contengono gli istanti<br>
di (inizio, fine) dei due eventi:<br>
s1ev = [(1723, 18550), (100000, 101000)]<br>
s2ev = [(9154, 9307), (9340, 10442), (87361, 98214)]<br>
<br>
quindi l&#39;evento s1ev è cominciato a 1723 e finito a 18550, riprende a<br>
100000 e termina a 101000, etc.<br>
<br>
Ora, supponendo di tracciare una linea temporale unica e dato che i<br>
due eventi s1 e s2 sono sincronizzati sulla stessa linea temporale,<br>
vorrei calcolare:<br>
a) gli istanti di tempo (inizio, fine) in cui gli eventi sono entrambi<br>
attivi [s1ev and s2ev]<br>
b) gli istanti di tempo (inizio, fine) in cui esattamente *un* evento<br>
(non specifico quale è attivo [s1ev xor s2ev]<br>
c) gli istanti di tempo (inizio, fine) in cui *nessun* evento è attivo<br>
[!s1ev and !s2ev]<br>
<br>
Date le premesse, riesco a calcolare il punto a) in questo modo:<br>
s1ev = [(1723, 18550), (100000, 101000)]<br>
s2ev = [(9154, 9307), (9340, 10442), (87361, 98214)]<br>
<br>
# end = [1]<br>
# begin = [0]<br>
<br>
print &#39;both: &#39;<br>
for s1 in s1ev:<br>
     for s2 in s2ev:<br>
         if s1[0] &gt; s2[0] and s1[1] &lt; s2[1] \<br>
         or s1[0] &lt; s2[0] and s1[1] &gt; s2[1] \<br>
         or s1[0] &lt; s2[0] and s1[1] &lt; s2[1] \<br>
         or s1[0] &gt; s2[0] and s1[1] &gt; s2[0]:<br>
             begin = max(s1[0],s2[0])<br>
             finish = min(s1[1],s2[1])<br>
             if (finish &gt; begin):<br>
                 print str(begin) + &#39;-&#39; + str(finish)<br>
In questo modo ottengo:<br>
both:<br>
9154-9307<br>
9340-10442<br>
<br>
che sono gli istanti (inizio, fine) in cui entrambi gli eventi sono attivi.<br>
<br>
Tentando di implementare il punto b), mi sono accorto di un problema:<br>
print &#39;only one: &#39;<br>
for s1 in s1ev:<br>
     for s2 in s2ev:<br>
             if s1[0] &lt; s2[0] and s1[1] &lt; s2[1] \<br>
             or s1[0] &gt; s2[0] and s1[1] &gt; s2[1]:<br>
<br>
tecnicamente: se s1 è iniziato prima o dopo di s2 (cioè hanno<br>
intersezione vuota), allora dovremmo avere che s1 è evento singolo<br>
(cioè soddisfa la condizione del punto b)). Tuttavia, la condizione<br>
non funziona, visto che (1723, 18550) soddisfa la condizione, ma<br>
sappiamo che da 9154 in avanti gli eventi sono entrambi presenti...<br>
<br>
Quindi chiedo a voi, come impostereste la condizione di verifica del punto b)?<br>
Per il punto c), invece, non ho ancora pensato ad una strategia.<br>
Dove sto sbagliando?<br></blockquote><div><br>Non lo so, io il tutto lo farei cosi`:<br><br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">s1ev = [(1723, 18550), (100000, 101000)]</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">s2ev = [(9154, 9307), (9340, 10442), (87361, 98214)]</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">starts = sorted(s[0] for s in s1ev + s2ev)</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">ends = sorted(s[1] for s in s1ev + s2ev)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">actives = [[] for x in range(3)]</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">actives[0] = [[0, 0]]</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">actives_count = 0</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">while ends:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    if starts and starts[0] &lt; ends[0]:</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        x = starts.pop(0)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        inc = 1</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    else:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        x = ends.pop(0)</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">        inc = -1</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    actives[actives_count][-1][1] = x</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    actives_count += inc</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    actives[actives_count].append([x, 0])</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">for n, active in enumerate(actives):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    print n, active</span><br>

</div><br>Se lo eseguo viene fuori questo:<br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">0 [[0, 1723], [18550, 87361], [98214, 100000], [101000, 0]]</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">1 [[1723, 9154], [9307, 9340], [10442, 18550], [87361, 98214], [100000, 101000]]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">2 [[9154, 9307], [9340, 10442]]</span><br>

</div> <br></div>Il numero a inizio riga dice quanti eventi sono attivi.<br>Può andarti bene?<br><br>Se ti va bene puoi anche generalizzare a n eventi contemporanei cambiando le prime righe.<br><br>Ciao.<br>Marco.<br><br>

</div>-- <br><a href="http://thinkcode.tv">http://thinkcode.tv</a> - Prossimamente su questi schermi<br><a href="http://beri.it">http://beri.it</a> - Blog di una testina di vitello<br><a href="http://stacktrace.it">http://stacktrace.it</a> - Aperiodico di resistenza informatica<br>

<br>