Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

СиАОД_1-4.docx

.pdf
Скачиваний:
7
Добавлен:
23.01.2025
Размер:
1.33 Mб
Скачать

Вывод

​ Реализовали генерацию фрактала «Дерево Пифагора» с применением рекурсивных функций. Из результатов тестов сделали вывод, что

«Дерево Пифагора» несложный фрактал на низких глубинах, и становится сложнее с большими глубинами.

41

задание 4 Поиск подстроки в строке ​

Цель работы

Реализовать заданный метод поиска подстроки в строке в соответствии с индивидуальным заданием. Для всех вариантов добавить реализацию добавления строк, ввода подстроки и поиска подстроки. Предусмотреть возможность существования пробела. Ввести опцию чувствительности / нечувствительности к регистру. Оценить время работы каждого алгоритма поиска и сравнить его со временем работы стандартной функции поиска, используемой в выбранном языке программирования.​

Вариант 18

Метод Кнута Морриса Пратта​

Ход работы

В ходе выполнения напишем реализацию Метода поиска подстроки в строке ​

std::vector<std::size_t> KMP(const std::string &text, const std::string &pattern) {

std::vector<std::size_t> res; int m = text.length();

int pattern_length = pattern.length(); // if pattern is an empty string

if (pattern_length == 0) {

std::cout << "The pattern occurs with shift 0"; return res;

}

// if text's length is less than that of pattern's if (m < pattern_length) {

std::cout << "Pattern not found"; return res;

}

42

//next[i] stores the index of the next best partial match std::vector<int> next(pattern_length + 1, 0);

//Preprocessing the pattern to calculate the LPS (Longest Prefix Suffix)

//array

for (int i = 1, len = 0; i < pattern_length;) { if (pattern[i] == pattern[len]) {

next[i++] = ++len;

}else if (len > 0) { len = next[len - 1];

}else { next[i++] = 0;

}

}

// Searching the pattern in the text using the LPS array for (int i = 0, j = 0; i < m;) {

if (text[i] == pattern[j]) { i++;

j++;

if (j == pattern_length) { res.push_back(i - j);

j = next[j - 1]; // Continue searching for next match

}

}else if (j > 0) { j = next[j - 1];

}else { i++;

}

}

return res;

}

#if 0

Для сравнения возьмем алгоритм стандартной библиотеки языка C++ libstdc++

43

int countOccurrences(const std::vector<unsigned char> &data, const std::string &pattern) {

int count = 0;

std::string dataStr(data.begin(), data.end());

std::size_t pos = dataStr.find(pattern); while (pos != std::string::npos) {

count++;

pos = dataStr.find(pattern, pos + pattern.length());

}

return count;

}

а также алгоритм для решения задачи k-nucleotide ​ (приводить его не буду) ​

https://benchmarksgame-team.pages.debian.net/benchmarksgame/description/knucl eotide.html#knucleotide

https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/knuc leotide.html

Для проверки работы нашего алгоритма, придумаем задачу приближенную к реальности, а также же такую на которой КМП должен давать более хорошие результаты по сравнению с другими методами.​

с сайта: ​ https://www.ncbi.nlm.nih.gov/​

были загружены секвенированные геномы 5 (184.1) MB и 11 (58.2 MB) хромосом. 5 хромосома 11 миллионов пар оснований​

были установлены праймеры гена рецептора дофамина в 11 хромосоме​ https://www.jstage.jst.go.jp/article/jes/13/2/13_2_57/_pdf

44

например :​ (декодированный пример, праймерный участок выделен цветом) ​

>lcl|NC_000011.10_cds_NP_000788.2_142 [gene=DRD4] [db_xref=CCDS:CCDS7710.1,Ensembl:ENSP00000176183.5,GeneID:1815] [protein=D(4) dopamine receptor] [protein_id=NP_000788.2] [location=join(637305..637589,639433..639545,639648..640306,640401..640603)] [gbkey=CDS]

ATGGGGAACCGCAGCACCGCGGACGCGGACGGGCTGCTGGCTGGGCGC GGGCCGGCCGCGGGGGCATCTGCGGGGGCATCTGCGGGGCTGGCTGGGC AGGGCGCGGCGGCGCTGGTGGGGGGCGTGCTGCTCATCGGCGCGGTGCT CGCGGGGAACTCGCTCGTGTGCGTGAGCGTGGCCACCGAGCGCGCCCTG CAGACGCCCACCAACTCCTTCATCGTGAGCCTGGCGGCCGCCGACCTCCT CCTCGCTCTCCTGGTGCTGCCGCTCTTCGTCTACTCCGAGGTCCAGGGTG GCGCGTGGCTGCTGAGCCCCCGCCTGTGCGACGCCCTCATGGCCATGGA CGTCATGCTGTGCACCGCCTCCATCTTCAACCTGTGCGCCATCAGCGTGG ACAGGTTCGTGGCCGTGGCCGTGCCGCTGCGCTACAACCGGCAGGGTGG GAGCCGCCGGCAGCTGCTGCTCATCGGCGCCACGTGGCTGCTGTCCGCG GCGGTGGCGGCGCCCGTACTGTGCGGCCTCAACGACGTGCGCGGCCGCG ACCCCGCCGTGTGCCGCCTGGAGGACCGCGACTACGTGGTCTACTCGTCC GTGTGCTCCTTCTTCCTACCCTGCCCGCTCATGCTGCTGCTCTACTGGG CCACGTTCCGCGGCCTGCAGCGCTGGGAGGTGGCACGTCGCGCCAAGCT GCACGGCCGCGCGCCCCGCCGACCCAGCGGCCCTGGCCCGCCTTCCCCC ACGCCACCCGCGCCCCGCCTCCCCCAGGACCCCTGCGGCCCCGACTGTG CGCCCCCCGCGCCCGGCCTTCCCCGGGGTCCCTGCGGCCCCGACTGTGC GCCCGCCGCGCCCAGCCTCCCCCAGGACCCCTGCGGCCCCGACTGTGCG CCCCCCGCGCCCGGCCTCCCCCCGGACCCCTGCGGCTCCAACTGTGCTCC CCCCGACGCCGTCAGAGCCGCCGCGCTCCCACCCCAGACTCCACCGCAG ACCCGCAGGAGGCGGCGTGCCAAGATCACCGGCCGGGAGCGCAAGGCC ATGAGGGTCCTGCCGGTGGTGGTCGGGGCCTTCCTGCTGTGCTGGACGC CCTTCTTCGTGGTGCACATCACGCAGGCGCTGTGTCCTGCCTGCTCCGTG CCCCCGCGGCTGGTCAGCGCCGTCACCTGGCTGGGCTACGTCAACAGCG CCCTCAACCCCGTCATCTACACTGTCTTCAACGCCGAGTTCCGCAACGTC TTCCGCAAGGCCCTGCGTGCCTGCTGCTGA

были установлены праймеры гена рецептора адреналина в 5 хромосоме​ https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5859892/

Праймеры для ПЦР — это короткие фрагменты одноцепочечной ДНК, обычно около 20 нуклеотидов в длину. В каждой реакции ПЦР используются два праймера, и они сконструированы так, чтобы фланкировать целевой участок

45

(который необходимо скопировать). Таким образом, праймеры представляют собой последовательности, которые связываются с цепями матричной ДНК точно по краям копируемой области. Праймеры связываются с матрицей, образуя пары комплементарных оснований.

В нашем случае Праймер будет использоваться как способ уникальной идентификации наличия гена. ​

Итак приступим, общая схема тестирования.

timer.start();

int occurrences = countOccurrences(data, pattern); timer.stop();

std::cout << "The pattern '" << pattern << "' occurs " << occurrences

<<" times in the input data." << timer.elapsedMicrosec() << " microseconds

"<< std::endl;

libstdc++ find algorithm

Компилируем простой поиск :

46

компиляция :​

g++ src/main.cpp -std=c++17 -march=native -msse -msse2 -msse3 -O3 -o simple_find​

ищем дофамин в геноме 11 хромосомы

./simple_find -p CCGCTCATGCTGCTGCTCTACTGG < sequence_11_full.fasta

The pattern 'CCGCTCATGCTGCTGCTCTACTGG' occurs 1 times in the input data: 100109 microseconds

можем проверить что данный паттерн не встречается в другой хромосоме​

./simple_find -p CCGCTCATGCTGCTGCTCTACTGG < sequence_5chomosome_full.fasta

The pattern 'CCGCTCATGCTGCTGCTCTACTGG' occurs 0 times in the input data: 296673 microseconds (время больше так как данных больше)

попробуем поискать рецепторы адреналина ​

./simple_find -p AGGCAGCTCCAGAAGATTG < sequence_11_full.fasta

The pattern 'AGGCAGCTCCAGAAGATTG' occurs 0 times in the input data: 129443 microseconds

в 11 хромосоме праймер не найден

/simple_find -p AGGCAGCTCCAGAAGATTG < sequence_5chomosome_full.fasta

The pattern 'AGGCAGCTCCAGAAGATTG' occurs 1 times in the input data: 413622 microseconds

найден 1 праймер в 11 хромосоме.

The Knute Morris Pratt search method find :

Компиляция : ​

g++ src/kmp.cpp -O3 -o kmp_find

ищем дофамин в геноме 11 хромосомы ​

./kmp_find -p CCGCTCATGCTGCTGCTCTACTGG < sequence_11_full.fasta

The pattern 'CCGCTCATGCTGCTGCTCTACTGG' occurs 1 times in the input data: 180918 microseconds

47

Проверяем что этого праймера нет в другой хромосоме​

./kmp_find -p CCGCTCATGCTGCTGCTCTACTGG < sequence_5chomosome_full.fasta

The pattern 'CCGCTCATGCTGCTGCTCTACTGG' occurs 0 times in the input data: 571367 microseconds

праймера рецептора адреналина не найдено в 11 хрмосоме

./kmp_find -p AGGCAGCTCCAGAAGATTG < sequence_11_full.fasta

The pattern 'AGGCAGCTCCAGAAGATTG' occurs 0 times in the input data: 271423 microseconds

праймер найден в 5 хромосоме :

./kmp_find -p AGGCAGCTCCAGAAGATTG < sequence_5chomosome_full.fasta

The pattern 'AGGCAGCTCCAGAAGATTG' occurs 1 times in the input data: 887541 microseconds

Замеры времени

метод

размер

найден

мкс

прим

поиска

файла

о

 

 

 

MB

 

 

 

 

 

 

 

 

48

libstdc++

58

1

100109

ген рецептора дофамина в 11 хромосоме

 

 

 

 

DRD4 праймер

kmp

58

1

180918

CCGCTCATGCTGCTGCTCTACTGG

 

 

 

 

 

libstdc++

184

0

296673

тот же праймерный участок но в другой

 

 

 

 

хромосоме.

kmp

184

0

571367

 

 

 

 

 

 

libstdc++

184

1

413622

ген ADRB2 рецептора адреналина в 5

 

 

 

 

хромосоме​

kmp

184

1

887541

 

 

 

 

 

 

libstdc++

58

0

129443

ген ADRB2 рецептора адреналина в 11

 

 

 

 

хромосоме​

kmp

58

0

271423

 

 

 

 

 

 

Выводы

​ Реализовали заданный метод поиска подстроки в строке в соответствии с индивидуальным заданием. Оценили время работы алгоритма поиска и сравнили его со временем работы стандартной функции поиска, используемой в выбранном языке программирования. И в результате получилось, что встроенный алгоритм получился немного быстрее, чем реализованный. И, скорее всего, при увеличении строки, в которой будет осуществляться поиск, разница в скорости поиска будет увеличиваться, и наилучший результат будет показывать встроенный алгоритм поиска, т.к они спроектированы для производительности в больших объемах.

Список Литературы

1.​ Ахо Альфред В. Структуры данных и алгоритмы:

2.​ Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ.

49

3.​ Кнут Д.Э. Искусство программирования: в 4-x томах. 4.​ Тим Рафгаден Algorithms Illuminated в 4 х томах

5.​ Andrii Gakhov probabilistic data structures and algorithms for big data applications

6.​ Thomas Mailund The Joys of Hashing

7.​ Stepanov, Alexander; Kershenbaum, Aaron Using Tournament Trees to Sort

8.​ Determination and Variability of Nucleotide Sequences for D4 Dopamine Receptor Genes (DRD4) in Genus Equus

9.​ www.geeksforgeeks.org

10.​www.ncbi.nlm.nih.gov

50