001.
import
math
002.
import
random
003.
import
cTurtle
004.
import
operator
005.
006.
def
dist_euclidiana(p1,p2):
007.
return
math.sqrt(sum([(p[
1
]
-
p[
0
])
*
*
2
for
p
in
zip(p1,p2)]))
008.
009.
def
centroide(pontos):
010.
011.
012.
013.
014.
015.
cent
=
[sum(ponto)
/
len(ponto)
for
ponto
in
zip(
*
pontos)]
016.
return
tuple(cent)
017.
018.
def
cria_dicio_dados(ficheiro):
019.
020.
021.
022.
023.
f_in
=
open(ficheiro,
'r'
)
024.
dicio_dados
=
dict()
025.
026.
chave
=
0
027.
linha
=
f_in.readline()
028.
while
linha !
=
'':
029.
chave
=
chave
+
1
030.
tuplo
=
tuple([int(valor)
for
valor
in
linha[:
-
1
].split()])
031.
dicio_dados[chave]
=
tuplo
032.
linha
=
f_in.readline()
033.
return
dicio_dados
034.
035.
036.
def
cria_dicio_dados_terramoto(ficheiro):
037.
038.
039.
040.
f_in
=
open(ficheiro,
'r'
)
041.
dicio_dados
=
dict()
042.
043.
chave
=
0
044.
linha
=
f_in.readline()
045.
while
linha !
=
'':
046.
chave
=
chave
+
1
047.
latitude
=
float(linha[:
-
1
].split()[
3
])
048.
longitude
=
float(linha[:
-
1
].split()[
4
])
049.
dicio_dados[chave]
=
(longitude,latitude)
050.
linha
=
f_in.readline()
051.
return
dicio_dados
052.
053.
def
cria_centroides(k,dicio_dados):
054.
055.
056.
057.
058.
centroides
=
[]
059.
conta_centroides
=
0
060.
chaves_centroides
=
[]
061.
while
conta_centroides < k:
062.
chave_alea
=
random.randint(
1
,len(dicio_dados))
063.
if
chave_alea
not
in
chaves_centroides:
064.
centroides.append(dicio_dados[chave_alea])
065.
chaves_centroides.append(chave_alea)
066.
conta_centroides
=
conta_centroides
+
1
067.
return
centroides
068.
069.
070.
def
cria_agrupamentos(k,centroides,dicio_dados,repete):
071.
072.
073.
074.
075.
076.
077.
078.
for
passo
in
range(repete):
079.
print
"----- Passagem:\t {0}\t-----"
.format(passo)
080.
081.
agrupamentos
=
[]
082.
for
conta
in
range(k):
083.
agrupamentos.append([])
084.
085.
086.
for
chave
in
dicio_dados:
087.
distancias
=
[]
088.
for
indice_agrupamento
in
range(k):
089.
dist
=
dist_euclidiana(dicio_dados[chave],centroides[indice_agrupamento])
090.
distancias.append(dist)
091.
menor
=
min(distancias)
092.
indice
=
distancias.index(menor)
093.
094.
agrupamentos[indice].append(chave)
095.
096.
097.
for
indice
in
range(k):
098.
agrupa
=
[dicio_dados[chave]
for
chave
in
agrupamentos[indice]]
099.
centroides[indice]
=
centroide(agrupa)
100.
101.
102.
103.
if
agrupamento_vazio(agrupamentos):
104.
agrupamentos
=
consolida_agrupamentos(centroides,agrupamentos,dicio_dados)
105.
106.
107.
mostra_agrupamentos(agrupamentos,dicio_dados)
108.
109.
return
agrupamentos
110.
111.
def
mostra_agrupamentos(agrupamentos,dicio_dados):
112.
113.
114.
115.
for
indice,agrupamento
in
enumerate(agrupamentos):
116.
print
"AGRUPAMENTO %d: "
%
(indice
+
1
)
117.
for
chave
in
agrupamento:
118.
print
dicio_dados[chave],
119.
print
120.
121.
def
agrupamento_vazio(agrupa):
122.
123.
return
any([len(elem)
=
=
0
for
elem
in
agrupa])
124.
125.
def
indices_agrupa_vazios(agrupa):
126.
127.
return
[indice
for
indice
in
range(len(agrupa))
if
len(agrupa[indice])
=
=
0
]
128.
129.
def
indice_max_dist(centroides, agrupamentos, dicio_dados):
130.
131.
132.
133.
max_dist
=
[]
134.
for
indice,agrupa
in
enumerate(agrupamentos):
135.
if
len(agrupa) >
0
:
136.
lista_dist
=
[]
137.
for
elemento
in
agrupa:
138.
lista_dist.append((elemento,dist_euclidiana(centroides[indice], dicio_dados[elemento])))
139.
lista_dist.sort(key
=
operator.itemgetter(
1
), reverse
=
True
)
140.
maior
=
(indice,lista_dist[
0
][
0
])
141.
max_dist.append(maior)
142.
max_dist.sort(key
=
operator.itemgetter(
1
),reverse
=
True
)
143.
return
max_dist[
0
]
144.
145.
146.
147.
def
consolida_agrupamentos(centroides, agrupamentos,dicio_dados):
148.
149.
indice_vazios
=
indices_agrupa_vazios(agrupamentos)
150.
151.
while
indice_vazios:
152.
153.
154.
155.
maximo
=
indice_max_dist(centroides,agrupamentos,dicio_dados)
156.
157.
agrupamentos[indice_vazios[
0
]].append(maximo[
1
])
158.
159.
agrupamentos[maximo[
0
]].remove(maximo[
1
])
160.
indice_vazios
=
indice_vazios[
1
:]
161.
return
agrupamentos
162.
163.
164.
def
main(ficheiro,numero_grupos):
165.
166.
167.
168.
dicio_dados
=
cria_dicio_dados(ficheiro)
169.
centroides
=
cria_centroides(numero_grupos, dicio_dados)
170.
agrupamentos
=
cria_agrupamentos(numero_grupos,centroides, dicio_dados,
3
)