VedatMSA 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vedatmsa-1.0.0/PKG-INFO +47 -0
- vedatmsa-1.0.0/README.md +36 -0
- vedatmsa-1.0.0/VedatMSA.egg-info/PKG-INFO +47 -0
- vedatmsa-1.0.0/VedatMSA.egg-info/SOURCES.txt +11 -0
- vedatmsa-1.0.0/VedatMSA.egg-info/dependency_links.txt +1 -0
- vedatmsa-1.0.0/VedatMSA.egg-info/top_level.txt +1 -0
- vedatmsa-1.0.0/pyproject.toml +20 -0
- vedatmsa-1.0.0/setup.cfg +4 -0
- vedatmsa-1.0.0/vedatmsa/__init__.py +4 -0
- vedatmsa-1.0.0/vedatmsa/align.py +91 -0
- vedatmsa-1.0.0/vedatmsa/distance.py +38 -0
- vedatmsa-1.0.0/vedatmsa/muscle.py +92 -0
- vedatmsa-1.0.0/vedatmsa/tree.py +69 -0
vedatmsa-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: VedatMSA
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MUSCLE algoritmasıyla Çoklu Dizi Hizalaması
|
|
5
|
+
Author: Vedat Ersoy
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ersoy0710-tech/VedatMSA
|
|
8
|
+
Keywords: bioinformatics,MSA,MUSCLE,alignment
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# VedatMSA
|
|
13
|
+
|
|
14
|
+
MUSCLE algoritmasıyla Çoklu Dizi Hizalaması (Multiple Sequence Alignment)
|
|
15
|
+
|
|
16
|
+
Vedat Ersoy — İstanbul Rumeli Üniversitesi Yazılım Mühendisliği
|
|
17
|
+
|
|
18
|
+
## Kurulum
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install VedatMSA
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Kullanım
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from vedatmsa import muscle
|
|
28
|
+
|
|
29
|
+
diziler = [
|
|
30
|
+
("Insan", "ATCGATCGTTGCA"),
|
|
31
|
+
("Fare", "ATCGTTCGTTGCA"),
|
|
32
|
+
("Tavuk", "ATCGAACGTTGTA"),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
sonuc = muscle(diziler, verbose=True)
|
|
36
|
+
|
|
37
|
+
for isim, hizalanmis in sonuc:
|
|
38
|
+
print(f"{isim:10} {hizalanmis}")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Algoritma
|
|
42
|
+
|
|
43
|
+
MUSCLE 3 aşamada çalışır:
|
|
44
|
+
|
|
45
|
+
1. **Aşama 1** — k-mer mesafe matrisi + UPGMA ağacı + progressive alignment
|
|
46
|
+
2. **Aşama 2** — Hizalanmış dizilerle yeni mesafe matrisi + yeni ağaç + tekrar hizalama
|
|
47
|
+
3. **Aşama 3** — Refinement: hizalamayı bölerek iteratif iyileştirme
|
vedatmsa-1.0.0/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# VedatMSA
|
|
2
|
+
|
|
3
|
+
MUSCLE algoritmasıyla Çoklu Dizi Hizalaması (Multiple Sequence Alignment)
|
|
4
|
+
|
|
5
|
+
Vedat Ersoy — İstanbul Rumeli Üniversitesi Yazılım Mühendisliği
|
|
6
|
+
|
|
7
|
+
## Kurulum
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install VedatMSA
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Kullanım
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from vedatmsa import muscle
|
|
17
|
+
|
|
18
|
+
diziler = [
|
|
19
|
+
("Insan", "ATCGATCGTTGCA"),
|
|
20
|
+
("Fare", "ATCGTTCGTTGCA"),
|
|
21
|
+
("Tavuk", "ATCGAACGTTGTA"),
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
sonuc = muscle(diziler, verbose=True)
|
|
25
|
+
|
|
26
|
+
for isim, hizalanmis in sonuc:
|
|
27
|
+
print(f"{isim:10} {hizalanmis}")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Algoritma
|
|
31
|
+
|
|
32
|
+
MUSCLE 3 aşamada çalışır:
|
|
33
|
+
|
|
34
|
+
1. **Aşama 1** — k-mer mesafe matrisi + UPGMA ağacı + progressive alignment
|
|
35
|
+
2. **Aşama 2** — Hizalanmış dizilerle yeni mesafe matrisi + yeni ağaç + tekrar hizalama
|
|
36
|
+
3. **Aşama 3** — Refinement: hizalamayı bölerek iteratif iyileştirme
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: VedatMSA
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MUSCLE algoritmasıyla Çoklu Dizi Hizalaması
|
|
5
|
+
Author: Vedat Ersoy
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ersoy0710-tech/VedatMSA
|
|
8
|
+
Keywords: bioinformatics,MSA,MUSCLE,alignment
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# VedatMSA
|
|
13
|
+
|
|
14
|
+
MUSCLE algoritmasıyla Çoklu Dizi Hizalaması (Multiple Sequence Alignment)
|
|
15
|
+
|
|
16
|
+
Vedat Ersoy — İstanbul Rumeli Üniversitesi Yazılım Mühendisliği
|
|
17
|
+
|
|
18
|
+
## Kurulum
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install VedatMSA
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Kullanım
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from vedatmsa import muscle
|
|
28
|
+
|
|
29
|
+
diziler = [
|
|
30
|
+
("Insan", "ATCGATCGTTGCA"),
|
|
31
|
+
("Fare", "ATCGTTCGTTGCA"),
|
|
32
|
+
("Tavuk", "ATCGAACGTTGTA"),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
sonuc = muscle(diziler, verbose=True)
|
|
36
|
+
|
|
37
|
+
for isim, hizalanmis in sonuc:
|
|
38
|
+
print(f"{isim:10} {hizalanmis}")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Algoritma
|
|
42
|
+
|
|
43
|
+
MUSCLE 3 aşamada çalışır:
|
|
44
|
+
|
|
45
|
+
1. **Aşama 1** — k-mer mesafe matrisi + UPGMA ağacı + progressive alignment
|
|
46
|
+
2. **Aşama 2** — Hizalanmış dizilerle yeni mesafe matrisi + yeni ağaç + tekrar hizalama
|
|
47
|
+
3. **Aşama 3** — Refinement: hizalamayı bölerek iteratif iyileştirme
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
VedatMSA.egg-info/PKG-INFO
|
|
4
|
+
VedatMSA.egg-info/SOURCES.txt
|
|
5
|
+
VedatMSA.egg-info/dependency_links.txt
|
|
6
|
+
VedatMSA.egg-info/top_level.txt
|
|
7
|
+
vedatmsa/__init__.py
|
|
8
|
+
vedatmsa/align.py
|
|
9
|
+
vedatmsa/distance.py
|
|
10
|
+
vedatmsa/muscle.py
|
|
11
|
+
vedatmsa/tree.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
vedatmsa
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "VedatMSA"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "MUSCLE algoritmasıyla Çoklu Dizi Hizalaması"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [{ name = "Vedat Ersoy" }]
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
keywords = ["bioinformatics", "MSA", "MUSCLE", "alignment"]
|
|
14
|
+
|
|
15
|
+
[project.urls]
|
|
16
|
+
Homepage = "https://github.com/ersoy0710-tech/VedatMSA"
|
|
17
|
+
|
|
18
|
+
[tool.setuptools.packages.find]
|
|
19
|
+
where = ["."]
|
|
20
|
+
include = ["vedatmsa*"]
|
vedatmsa-1.0.0/setup.cfg
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Needleman-Wunsch global alignment
|
|
2
|
+
# İki diziyi en iyi şekilde hizalar (gap ekleyerek)
|
|
3
|
+
|
|
4
|
+
ESLEME = 1 # aynı karakter
|
|
5
|
+
UYUMSUZ = -1 # farklı karakter
|
|
6
|
+
GAP = -2 # boşluk cezası
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def needleman_wunsch(dizi1, dizi2):
|
|
10
|
+
m, n = len(dizi1), len(dizi2)
|
|
11
|
+
|
|
12
|
+
# DP tablosunu olustur
|
|
13
|
+
tablo = [[0] * (n + 1) for _ in range(m + 1)]
|
|
14
|
+
for i in range(m + 1):
|
|
15
|
+
tablo[i][0] = i * GAP
|
|
16
|
+
for j in range(n + 1):
|
|
17
|
+
tablo[0][j] = j * GAP
|
|
18
|
+
|
|
19
|
+
# Tabloyu doldur
|
|
20
|
+
for i in range(1, m + 1):
|
|
21
|
+
for j in range(1, n + 1):
|
|
22
|
+
eslesme = ESLEME if dizi1[i-1].upper() == dizi2[j-1].upper() else UYUMSUZ
|
|
23
|
+
capraz = tablo[i-1][j-1] + eslesme
|
|
24
|
+
yukari = tablo[i-1][j] + GAP
|
|
25
|
+
sol = tablo[i][j-1] + GAP
|
|
26
|
+
tablo[i][j] = max(capraz, yukari, sol)
|
|
27
|
+
|
|
28
|
+
# Geri izleme
|
|
29
|
+
hiz1, hiz2 = [], []
|
|
30
|
+
i, j = m, n
|
|
31
|
+
while i > 0 or j > 0:
|
|
32
|
+
if i > 0 and j > 0:
|
|
33
|
+
eslesme = ESLEME if dizi1[i-1].upper() == dizi2[j-1].upper() else UYUMSUZ
|
|
34
|
+
if tablo[i][j] == tablo[i-1][j-1] + eslesme:
|
|
35
|
+
hiz1.append(dizi1[i-1])
|
|
36
|
+
hiz2.append(dizi2[j-1])
|
|
37
|
+
i -= 1; j -= 1
|
|
38
|
+
elif tablo[i][j] == tablo[i-1][j] + GAP:
|
|
39
|
+
hiz1.append(dizi1[i-1])
|
|
40
|
+
hiz2.append('-')
|
|
41
|
+
i -= 1
|
|
42
|
+
else:
|
|
43
|
+
hiz1.append('-')
|
|
44
|
+
hiz2.append(dizi2[j-1])
|
|
45
|
+
j -= 1
|
|
46
|
+
elif i > 0:
|
|
47
|
+
hiz1.append(dizi1[i-1]); hiz2.append('-'); i -= 1
|
|
48
|
+
else:
|
|
49
|
+
hiz1.append('-'); hiz2.append(dizi2[j-1]); j -= 1
|
|
50
|
+
|
|
51
|
+
return ''.join(reversed(hiz1)), ''.join(reversed(hiz2))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def iki_grubu_hizala(grup1, grup2):
|
|
55
|
+
# Her iki grubun ilk dizisini temsil olarak kullan
|
|
56
|
+
temsilci1 = grup1[0]
|
|
57
|
+
temsilci2 = grup2[0]
|
|
58
|
+
|
|
59
|
+
hiz1, hiz2 = needleman_wunsch(temsilci1, temsilci2)
|
|
60
|
+
|
|
61
|
+
# Hizalamayı tüm gruba uygula (aynı gap pozisyonlarını ekle)
|
|
62
|
+
def gap_ekle(diziler, referans_oncesi, referans_sonrasi):
|
|
63
|
+
sonuc = []
|
|
64
|
+
for dizi in diziler:
|
|
65
|
+
yeni = []
|
|
66
|
+
dizi_idx = 0
|
|
67
|
+
for c in referans_sonrasi:
|
|
68
|
+
if c == '-':
|
|
69
|
+
yeni.append('-')
|
|
70
|
+
else:
|
|
71
|
+
yeni.append(dizi[dizi_idx] if dizi_idx < len(dizi) else '-')
|
|
72
|
+
dizi_idx += 1
|
|
73
|
+
sonuc.append(''.join(yeni))
|
|
74
|
+
return sonuc
|
|
75
|
+
|
|
76
|
+
yeni_grup1 = gap_ekle(grup1, temsilci1, hiz1)
|
|
77
|
+
yeni_grup2 = gap_ekle(grup2, temsilci2, hiz2)
|
|
78
|
+
|
|
79
|
+
return yeni_grup1, yeni_grup2
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def progressive_hizala(agac, dizi_sozlugu):
|
|
83
|
+
# Ağacın yapraklarından köküne doğru hizala
|
|
84
|
+
if agac.yaprak_mi():
|
|
85
|
+
return [dizi_sozlugu[agac.isim]]
|
|
86
|
+
|
|
87
|
+
sol_diziler = progressive_hizala(agac.sol, dizi_sozlugu)
|
|
88
|
+
sag_diziler = progressive_hizala(agac.sag, dizi_sozlugu)
|
|
89
|
+
|
|
90
|
+
yeni_sol, yeni_sag = iki_grubu_hizala(sol_diziler, sag_diziler)
|
|
91
|
+
return yeni_sol + yeni_sag
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# k-mer mesafe hesabı
|
|
2
|
+
# İki dizi arasındaki benzerliği hızlıca ölçmek için kullanılır
|
|
3
|
+
# Örnek: k=3 ise "ATCG" -> ["ATC", "TCG"]
|
|
4
|
+
|
|
5
|
+
def kmer_mesafe(dizi1, dizi2, k=3):
|
|
6
|
+
def kmer_bul(dizi, k):
|
|
7
|
+
kmers = {}
|
|
8
|
+
for i in range(len(dizi) - k + 1):
|
|
9
|
+
parca = dizi[i:i+k]
|
|
10
|
+
kmers[parca] = kmers.get(parca, 0) + 1
|
|
11
|
+
return kmers
|
|
12
|
+
|
|
13
|
+
kmers1 = kmer_bul(dizi1.upper(), k)
|
|
14
|
+
kmers2 = kmer_bul(dizi2.upper(), k)
|
|
15
|
+
|
|
16
|
+
tum_kmers = set(kmers1) | set(kmers2)
|
|
17
|
+
ortak = sum(min(kmers1.get(kmer, 0), kmers2.get(kmer, 0)) for kmer in tum_kmers)
|
|
18
|
+
toplam = sum(kmers1.values()) + sum(kmers2.values())
|
|
19
|
+
|
|
20
|
+
if toplam == 0:
|
|
21
|
+
return 1.0
|
|
22
|
+
|
|
23
|
+
benzerlik = (2 * ortak) / toplam
|
|
24
|
+
return 1.0 - benzerlik # mesafe = 1 - benzerlik
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def mesafe_matrisi_olustur(diziler, k=3):
|
|
28
|
+
# diziler: [("isim", "ATCG..."), ...]
|
|
29
|
+
n = len(diziler)
|
|
30
|
+
matris = [[0.0] * n for _ in range(n)]
|
|
31
|
+
|
|
32
|
+
for i in range(n):
|
|
33
|
+
for j in range(i + 1, n):
|
|
34
|
+
d = kmer_mesafe(diziler[i][1], diziler[j][1], k)
|
|
35
|
+
matris[i][j] = d
|
|
36
|
+
matris[j][i] = d
|
|
37
|
+
|
|
38
|
+
return matris
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# MUSCLE - Multiple Sequence Alignment
|
|
2
|
+
# 3 aşama: kaba hizalama -> iyileştirilmiş ağaç -> refinement
|
|
3
|
+
|
|
4
|
+
from .distance import mesafe_matrisi_olustur
|
|
5
|
+
from .tree import upgma
|
|
6
|
+
from .align import progressive_hizala, iki_grubu_hizala
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def hizalama_skoru(diziler):
|
|
10
|
+
# Toplam match sayısını skor olarak kullan
|
|
11
|
+
if not diziler or len(diziler) < 2:
|
|
12
|
+
return 0
|
|
13
|
+
skor = 0
|
|
14
|
+
uzunluk = len(diziler[0])
|
|
15
|
+
for pos in range(uzunluk):
|
|
16
|
+
sutun = [dizi[pos] for dizi in diziler if pos < len(dizi)]
|
|
17
|
+
en_sik = max(set(sutun), key=sutun.count)
|
|
18
|
+
if en_sik != '-':
|
|
19
|
+
skor += sutun.count(en_sik)
|
|
20
|
+
return skor
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def refine(isimler, diziler, tekrar=3):
|
|
24
|
+
# Aşama 3: hizalamayı ikiye bölüp tekrar hizala, iyileşiyorsa güncelle
|
|
25
|
+
guncel = list(diziler)
|
|
26
|
+
guncel_skor = hizalama_skoru(guncel)
|
|
27
|
+
|
|
28
|
+
for _ in range(tekrar):
|
|
29
|
+
n = len(guncel)
|
|
30
|
+
if n < 2:
|
|
31
|
+
break
|
|
32
|
+
ortadan = n // 2
|
|
33
|
+
grup1 = guncel[:ortadan]
|
|
34
|
+
grup2 = guncel[ortadan:]
|
|
35
|
+
|
|
36
|
+
yeni1, yeni2 = iki_grubu_hizala(grup1, grup2)
|
|
37
|
+
yeni = yeni1 + yeni2
|
|
38
|
+
yeni_skor = hizalama_skoru(yeni)
|
|
39
|
+
|
|
40
|
+
if yeni_skor > guncel_skor:
|
|
41
|
+
guncel = yeni
|
|
42
|
+
guncel_skor = yeni_skor
|
|
43
|
+
|
|
44
|
+
return guncel
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def muscle(diziler, verbose=False):
|
|
48
|
+
"""
|
|
49
|
+
MUSCLE ile çoklu dizi hizalaması yapar.
|
|
50
|
+
|
|
51
|
+
diziler: [("isim", "ATCG..."), ...]
|
|
52
|
+
Döndürür: [("isim", "hizalanmis_dizi"), ...]
|
|
53
|
+
"""
|
|
54
|
+
if len(diziler) < 2:
|
|
55
|
+
raise ValueError("En az 2 dizi gerekli.")
|
|
56
|
+
|
|
57
|
+
isimler = [isim for isim, _ in diziler]
|
|
58
|
+
dizi_sozlugu = {isim: dizi for isim, dizi in diziler}
|
|
59
|
+
|
|
60
|
+
# --- AŞAMA 1: k-mer mesafesiyle kaba hizalama ---
|
|
61
|
+
if verbose:
|
|
62
|
+
print("Aşama 1: k-mer mesafe matrisi hesaplanıyor...")
|
|
63
|
+
matris = mesafe_matrisi_olustur(diziler)
|
|
64
|
+
|
|
65
|
+
if verbose:
|
|
66
|
+
print("Aşama 1: UPGMA ağacı oluşturuluyor...")
|
|
67
|
+
agac = upgma(isimler, matris)
|
|
68
|
+
|
|
69
|
+
if verbose:
|
|
70
|
+
print("Aşama 1: Progressive hizalama yapılıyor...")
|
|
71
|
+
hizalanmis = progressive_hizala(agac, dizi_sozlugu)
|
|
72
|
+
|
|
73
|
+
# --- AŞAMA 2: Hizalanmış dizilerle yeni mesafe matrisi ---
|
|
74
|
+
if verbose:
|
|
75
|
+
print("Aşama 2: Yeni mesafe matrisi hesaplanıyor...")
|
|
76
|
+
hizalanmis_diziler = list(zip(isimler, hizalanmis))
|
|
77
|
+
matris2 = mesafe_matrisi_olustur(hizalanmis_diziler)
|
|
78
|
+
|
|
79
|
+
if verbose:
|
|
80
|
+
print("Aşama 2: Yeni UPGMA ağacı ve hizalama...")
|
|
81
|
+
agac2 = upgma(isimler, matris2)
|
|
82
|
+
hizalanmis = progressive_hizala(agac2, dizi_sozlugu)
|
|
83
|
+
|
|
84
|
+
# --- AŞAMA 3: Refinement ---
|
|
85
|
+
if verbose:
|
|
86
|
+
print("Aşama 3: Refinement yapılıyor...")
|
|
87
|
+
hizalanmis = refine(isimler, hizalanmis)
|
|
88
|
+
|
|
89
|
+
if verbose:
|
|
90
|
+
print(f"Tamamlandı! Skor: {hizalama_skoru(hizalanmis)}")
|
|
91
|
+
|
|
92
|
+
return list(zip(isimler, hizalanmis))
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# UPGMA algoritması ile rehber ağaç oluşturma
|
|
2
|
+
# En yakın iki diziyi bulup birleştirir, ta ki tek ağaç kalana kadar
|
|
3
|
+
|
|
4
|
+
import copy
|
|
5
|
+
|
|
6
|
+
class Dugum:
|
|
7
|
+
def __init__(self, isim=None, sol=None, sag=None):
|
|
8
|
+
self.isim = isim # yaprak dugum ise dizi adi
|
|
9
|
+
self.sol = sol
|
|
10
|
+
self.sag = sag
|
|
11
|
+
|
|
12
|
+
def yaprak_mi(self):
|
|
13
|
+
return self.sol is None and self.sag is None
|
|
14
|
+
|
|
15
|
+
def yapraklari_getir(self):
|
|
16
|
+
if self.yaprak_mi():
|
|
17
|
+
return [self.isim]
|
|
18
|
+
yapraklar = []
|
|
19
|
+
if self.sol:
|
|
20
|
+
yapraklar += self.sol.yapraklari_getir()
|
|
21
|
+
if self.sag:
|
|
22
|
+
yapraklar += self.sag.yapraklari_getir()
|
|
23
|
+
return yapraklar
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def upgma(isimler, matris):
|
|
27
|
+
dugumler = [Dugum(isim=isim) for isim in isimler]
|
|
28
|
+
mat = copy.deepcopy(matris)
|
|
29
|
+
kume_boyutlari = [1] * len(isimler)
|
|
30
|
+
|
|
31
|
+
while len(dugumler) > 1:
|
|
32
|
+
n = len(dugumler)
|
|
33
|
+
|
|
34
|
+
# En kucuk mesafeyi bul
|
|
35
|
+
min_dist = float('inf')
|
|
36
|
+
min_i, min_j = 0, 1
|
|
37
|
+
for i in range(n):
|
|
38
|
+
for j in range(i + 1, n):
|
|
39
|
+
if mat[i][j] < min_dist:
|
|
40
|
+
min_dist = mat[i][j]
|
|
41
|
+
min_i, min_j = i, j
|
|
42
|
+
|
|
43
|
+
# Yeni ic dugum olustur
|
|
44
|
+
yeni = Dugum(sol=dugumler[min_i], sag=dugumler[min_j])
|
|
45
|
+
boy_i = kume_boyutlari[min_i]
|
|
46
|
+
boy_j = kume_boyutlari[min_j]
|
|
47
|
+
yeni_boy = boy_i + boy_j
|
|
48
|
+
|
|
49
|
+
# Yeni mesafeleri hesapla (agirlikli ortalama)
|
|
50
|
+
yeni_mesafeler = []
|
|
51
|
+
for k in range(n):
|
|
52
|
+
if k == min_i or k == min_j:
|
|
53
|
+
continue
|
|
54
|
+
d = (boy_i * mat[min_i][k] + boy_j * mat[min_j][k]) / yeni_boy
|
|
55
|
+
yeni_mesafeler.append(d)
|
|
56
|
+
|
|
57
|
+
# Guncelle
|
|
58
|
+
kalan = [k for k in range(n) if k != min_i and k != min_j]
|
|
59
|
+
dugumler = [dugumler[k] for k in kalan] + [yeni]
|
|
60
|
+
kume_boyutlari = [kume_boyutlari[k] for k in kalan] + [yeni_boy]
|
|
61
|
+
|
|
62
|
+
yeni_mat = []
|
|
63
|
+
for i, ki in enumerate(kalan):
|
|
64
|
+
satir = [mat[ki][kj] for kj in kalan] + [yeni_mesafeler[i]]
|
|
65
|
+
yeni_mat.append(satir)
|
|
66
|
+
yeni_mat.append(yeni_mesafeler + [0.0])
|
|
67
|
+
mat = yeni_mat
|
|
68
|
+
|
|
69
|
+
return dugumler[0]
|