/
merge.py
174 lines (117 loc) · 4.78 KB
/
merge.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
from tools import *
import pymprog # Import the module
## TODO :
## - devo riuscire a fare il coverage, ovvero a riuscire a capire come controllare che uno dei due sub-pattern
## - devo riuscire anche a fare il volume
##
## NOZIONI :
## - in generale ho un vettore di variabili x. Il problema di ottimizzazione P e' del tipo
## min { c(x) | Ax<= b } dove A e b sono vettori di numeri reali
##
def merge ( Y, W ):
import operator
import sys
N = 4
M = 4
# index and data
patternid, yid, wid, rid = range(N*M), range(N*M), range(N*M), range(2)
#problem definition
pymprog.beginModel('basic')
pymprog.verbose(True)
# Stiamo facendo uno split, il pattern precedente e' P, e noi vogliamo creare due pattern figli Y e W
# P, Y, e W sono delle matrici NxM, rappresentate come vettori, di bit.
# N sono i layer, mentre M sono le hit in quel layer
P = pymprog.var(patternid, 'P', bool) # Parent Pattern
Y = pymprog.var(range(3), 'Y', bool) # First sub-pattern
W = pymprog.var(range(3), 'W', bool) # Second sub-pattenr
# Queste tre relazioni logiche impongono che per ogni traccia k, questa venga riconosciuta da almeno un sub-pattern
# e traducono la relazione
# covered[k] = coveredY[k] V coveredW[k] | k = {1,2,3}
# con
# covered[k] = 1 | k = {1,2,3}
covered = pymprog.var(range(3), 'covSubTot', bool)
r = pymprog.st( covered[k] >= Y[k] for k in range(3) )
r += pymprog.st( covered[k] >= W[k] for k in range(3) )
r += pymprog.st( covered[k] <= Y[k] + W[k] for k in range(3) )
r += pymprog.st( covered[k] == 1 for k in range(3) )
#
# # # # # # #
totY = pymprog.var( range(1), 'totY', bounds=(1, 3) )
totW = pymprog.var( range(1), 'totW', bounds=(1, 3) )
r += pymprog.st( sum ( Y[k] for k in range(3) ) == totY[i] for i in range(1) )
r += pymprog.st( sum ( W[k] for k in range(3) ) == totW[i] for i in range(1) )
AY = pymprog.var(range(N*M), 'AY', int)
AW = pymprog.var(range(N*M), 'AW', int)
## Ora voglio fare che *per ogni punto* nella griglia 2D,
r += pymprog.st ( AY[ i ] >= Y[k] * myTracks[k][ i ] for i in range(N*M) for k in range(3) )
r += pymprog.st ( AY[ i ] <= sum( Y[k] * myTracks[k][ i ] for k in range(3) ) for i in range(N*M) )
r += pymprog.st ( AW[ i ] >= W[k] * myTracks[k][ i ] for i in range(N*M) for k in range(3) )
r += pymprog.st ( AW[ i ] <= sum( W[k] * myTracks[k][ i ] for k in range(3) ) for i in range(N*M) )
# Le ampiezze nei vari layer ... poi si potra' semplificare
AmpY = pymprog.var(range(N), 'AmpY', int)
AmpW = pymprog.var(range(N), 'AmpW', int)
r += pymprog.st ( sum( AY[i*N+j] for j in mRange ) == AmpY[i] for i in nRange )
r += pymprog.st ( sum( AW[i*N+j] for j in mRange ) == AmpW[i] for i in nRange )
VolTotY = pymprog.var(range(1), 'VolTotY', int) # Second sub-pattenr
VolTotW = pymprog.var(range(1), 'VolTotW', int) # Second sub-pattenr
#r += st ( sum( AY[i*N+j] for j in mRange ) == AmpY[i] for i in nRange )
r += pymprog.st ( sum( AmpY[j] for j in nRange ) == VolTotY[i] for i in range(1) )
r += pymprog.st ( sum( AmpW[j] for j in nRange ) == VolTotW[i] for i in range(1) )
pymprog.minimize( VolTotY[0] + VolTotW[0] , 'Total Volume')
sys.stdout.write("\nSolving ...")
pymprog.solve()
sys.stdout.write(" done.\n\n")
print("Total Volume = %g"% pymprog.vobj())
print 'Y'
print Y
print 'W'
print W
print AmpY
print AmpW
print 'AY'
print_variables_matrix_primal(AY)
print 'AW'
print_variables_matrix_primal(AW)
print 'Y'
print_variables_matrix_cross(AY)
print 'W'
print_variables_matrix_cross(AW)
print 'Volume Y : '
print VolTotY[0].primal
print 'Volume W : '
print VolTotW[0].primal
print 'Volume Tot : '
print sum( tracks[i] for i in range(N*M) )
# test code
tracks = (
1, 0, 1, 1,
1, 0, 1, 1,
1, 1, 0, 0,
1, 1, 0, 0)
print 'Pattern Originale:'
print_values_matrix(tracks)
##
## Ora vorrei fare un modello PL per il massimo split in due
##
# Facciamo una matrice per ogni traccia
track_1 = ( 0, 0, 0, 1,
0, 0, 1, 0,
0, 1, 0, 0,
0, 1, 0, 0)
print 'Track_1:'
print_values_matrix(track_1)
track_2 = ( 1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0)
print 'Track_2:'
print_values_matrix(track_2)
track_3 = ( 0, 0, 0, 1,
0, 0, 0, 1,
0, 0, 0, 1,
0, 0, 0, 1)
print 'Track_3:'
print_values_matrix(track_3)
myTracks = [track_1, track_2, track_3 ]
split(myTracks)
# Funzione di massimo