2 from networkx.algorithms import isomorphism
5 from optparse import OptionParser
8 from combinaisons import *
11 # Implemantation of the balanced gray code algorithm,construction B
12 # detailled in "Totally Balanced and exponentially Balanced Gray codes",
13 # A J. van Zanten, I.N. Suparta 2004
18 """Convertit un nombre en binaire"""
20 res =[0 for i in range(n)]
35 acc = acc + 2**(n-i-1)
42 if hasattr(el, "__iter__") and not isinstance(el, basestring):
43 result.extend(flatten(el))
50 def genereToutesLesSousListes(n,su):
51 # specificique puisque la taille mini est 2 et commence par [0,1]
54 for j in xrange(su-2):
58 for el in range(li[-1]+1,n):
67 def extraitSousListe(Snm2,sublisIndex,n):
70 indexOfSnm2 = xrange(nm2)
71 # l is an even positive number
72 #assert l >= 0 and l%2 == 0 and l<= nm2
74 #print "l",l,"n",n,"len(Snm2)",nm2
75 # we have to select l elements, but the two first are always selected
76 #Silindex = [0,1]+rd.sample(xrange(2,nm2),l-2)
77 Silindex = sublisIndex
79 Sil = [Snm2[x] for x in Silindex]
81 dif = list(set(indexOfSnm2)-set(Silindex))
89 Uinitial += [[Snm2[x] for x in range(cur,Silindex[k])]]
90 UinitialIndex = [[x for x in range(cur,Silindex[k])]]
92 v = [Snm2[x] for x in range(cur,nm2)]
94 #print "Snm2",Snm2,"Silindex",Silindex,"Sil",Sil,"dif",dif,"Uinitial",Uinitial,"UinitialIndex",UinitialIndex,"v",v
95 return (Silindex,Sil,Uinitial,v)
100 def replace(Silindex,Sil,u,n,l,v):
101 def uExtended(u,j,n):
102 # If j is odd, we are in u(n-1,n), and u(n,n-1) otherwise
103 (X,Y) = (n-1,n) if i%2 == 1 else (n,n-1)
105 uir = [_ for _ in u[i]]
107 R = [_ for _ in u[i]]+ [X] + uir + [Y] + [_ for _ in u[i]]
112 Up = [n-1]+[uExtended(u,i,n) for i in range(1,lu)]
115 for j in xrange(l-2+1):
123 def generateGrayCode(Snm2,sublistdindices):
125 #Snm2 = [3,2,3,1,3,2,3,1]
126 n= int(log(len(Snm2))/log(2))+2
129 (Silindex,Sil,Uinitial,v) = extraitSousListe(Snm2,sublistdindices,n)
132 #step 2 : replace in Snm2 and genereate U
133 U = replace(Silindex,Sil,Uinitial,n,l,v)
135 #step 3 : compute V and W
138 V += [n] + [_ for _ in v]
139 W = [n-1] + [_ for _ in Snm2] +[n]
141 #step 4 : swap value n-1 and s1 in W
142 Wp = [W[1]] + [n-1] + [_ for _ in W[2:]]
144 #step 5 : generate Sn
152 def is_totallyBalanced(l):
153 res = [0 for _ in range(max(l))]
156 return (max(res) == min(res))
158 def is_onlyBalanced(l):
159 res = [0 for _ in range(max(l))]
162 return max(res)- min(res) < 3
165 def grapheToList(G,n):
166 l2n = range(int(pow(2,n)))
168 images = range(int(pow(2,n)))
175 if (o,dec(epb,n)) in edges:
182 n= int(log(len(l))/log(2))
189 chemin=[dec(x,n) for x in cheminb]
191 enl=[(chemin[i%lc],chemin[(i+1)%lc]) for i in range(lc)]
192 assert len(set(range(int(pow(2,n))))-set(chemin)) == 0
193 # cheminp est le chemin hamiltonien correspondant a l
194 # on construit la fonction sans ce chemin hamiltonien
196 for i in range(2**n):
199 ibp = [_ for _ in ib]
201 # si l'arrete ne doit pas etre enlevee
202 if (i,dec(ibp,n)) not in enl :
203 G.add_edge(i,dec(ibp,n))
205 #resl = grapheToList(G,n)
206 return (G,grapheToList(G,n))
215 #snm2 = [[4, 5, 6, 2, 6, 5, 1, 5, 6, 2, 6, 5, 3, 5, 6, 1, 6, 5, 4, 5, 6, 1, 3, 2, 3, 4, 1, 4, 6, 4, 1, 4, 3, 2, 3, 5, 3, 2, 3, 4, 1, 4, 3, 5, 2, 6, 2, 5, 3, 4, 1, 4, 3, 2, 3, 1, 4, 1, 3, 2, 1, 2, 4, 6]]
219 print "taille de snm2", len(snm2)
222 n= int(log(len(sn))/log(2))+2
224 #subls = genereToutesLesSousListes(int(pow(2,n-2)),ln)
226 ll = range(int(pow(2,n-2)))
229 for l in xuniqueCombinations(ll[2:], ln-2):
232 nouveauCode = generateGrayCode(sn,l)
237 (G,nc) = Sn2map(nouveauCode)
238 #on verifie que la fonction est nouvelle
239 if nx.is_strongly_connected(G):
244 def isomorphic(g1,g2):
245 GM = isomorphism.DiGraphMatcher(g1,g2)
246 return GM.is_isomorphic()
247 if all([not(isomorphic(G,g2)) for g2 in resG]):
250 if is_onlyBalanced(nouveauCode) :
251 snm2p +=[nouveauCode]
252 if is_totallyBalanced(nouveauCode) :
266 parser = OptionParser()
267 parser.add_option("-i", "--input", dest="i",
268 help="file of sequences")
269 (options, args) = parser.parse_args()
270 if (options.i != None):
274 if __name__ == "__main__":