BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

11
T.C. İSTANBUL AYDIN ÜNİVERSİTESİ -BİLGİSAYAR MÜHENDİSLİĞİ YÜKSEK LİSANS- -BYL563 İleri Algoritma Analizi- BRUTEFORCE VE HORSPOOL ALGORİTMALARININ KARŞILAŞTIRMALI ANALİZİ Hazırlayan: Veysi ERTEKİN (YL1213.010020)

description

BruteForce ve Horspool algoritmalarının Java Dilinde yazılmış örenekleriyle performansa dayalı karşılaştırılması.

Transcript of BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Page 1: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

T.C. İSTANBUL AYDIN ÜNİVERSİTESİ

-BİLGİSAYAR MÜHENDİSLİĞİ YÜKSEK LİSANS--BYL563 İleri Algoritma Analizi-

BRUTEFORCE VE HORSPOOLALGORİTMALARININ

KARŞILAŞTIRMALIANALİZİ

Hazırlayan: Veysi ERTEKİN (YL1213.010020)

Page 2: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

İçindekilerİçindekiler........................................................................................................................................................................2

Problemin Tanımı............................................................................................................................................................3

Arama Algortimaları........................................................................................................................................................3

Bruteforce Search:.......................................................................................................................................................3

Horspool Search:.........................................................................................................................................................4

Algoritmaların Analizi......................................................................................................................................................5

1.Test Çıktısı................................................................................................................................................................5

Sonuç...........................................................................................................................................................................7

Ekler................................................................................................................................................................................8

1.TestCase.java:...........................................................................................................................................................8

Main.java:....................................................................................................................................................................8

AAlgorithm.java (Abstract Class):................................................................................................................................9

BruteForce.java:..........................................................................................................................................................9

Horspool.java:...........................................................................................................................................................10

Kaynakça.......................................................................................................................................................................11

Page 3: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Problemin Tanımı

Oluşturulmuş bir veri havuzundan (yazı, ikilik data, veritabanında saklanan bir blok vs olabilir) verilen bir şablonun elde edilmesi gerekmektedir. Bu tür işlemlerde elde bulunan veri kümesinden belirli özelliklere sahip bir öğeyi bulmak adına arama algoritmaları kullanılır.

Arama Algortimaları

Bruteforce Search:Algoritma işleyiş sırası şu şekildedir:

1. Yazıdan ve şablondan birer karakter al. Yazının sonuna gelindiyse 4. adıma geç.

2. Karakterler eşleşiyorsa 4. adıma git. Eşleşmiyorsa yazının bir sonraki karakteri, şablonun ise ilk karkterini al ve 3. adımı tekrar et.

3. Şablonda bir sonraki karteri ve yazıdan bir sonraki karakteri al. Karakterler eşleşiyor ve şablonun sonuna gelindiyse 4. adıma, şablon bitmemiş ise 2. adımdan devam et.

4. Bulunan index’i (bulunmadıysa yazının son index’i) ni belirlenen şekilde çıktıya bas.

En iyi Ortalama En kötün*m n*m n*m

(Genel algoritma yapısı)

do if (yazı karakteri== şablon karakteri) bir sonraki karakterlere geç else yazıyı bir artır ve şablonun başındaki karakterden tekrar başlawhile (yazının sonuna gelene kadar veya şablon bulunana kadar)

Page 4: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Horspool Search:Nigel Horspool tarafından 1980’lerde bulunmuştur. Yazı tabanlı bir algoritma olmakla birlikte BruteForce algoritmasına nazaran uzun vadede daha performanslı bir algoritmadır.

En iyi Ortalama En kötün ~n n*m

• Aşağıdaki gibi bir karakter kaydırma değerlerinin bulunduğu bir tablo hazırlanır:

• Şablon elimizdeki yazı içerisinde şablonun son karakterinden başlayarak karşılaştırırız, karakter uyuşmazlığı oluşursa yazı içerisinden en son karşılaştırma yapmakta olduğumuz karakterin yukarıdaki kaydırma değerlikleri tablosundaki değeri kadar kaydırma yaparız(şablon içerisinde yer almayan karakterlerde şablon boyu kadar kaydırma gerçekleşir):

(Genel algoritma yapısı)

Horspool (P = p1p2…pm,T = t1t2…tn)Ön İşleme

c ; d[c] ← m (karakter kaydırma değerliklerini şablonun boyutu olarak ata) j ; 1…m-1 ; d[pj] ← m – j (şablon içerisinde yer alan karakterlerin right-most

değerliklerini bul, not: son karakter göz ardı edilir)Arama

index←0For index ≤ n-m Do

j ←mfor j > 0 ve (index +j) = p*j Do j ← j-1If j = 0 -> (index+1). konumda sonuç bulunduindex ← index +d[tpos+m]

For Sonu

Page 5: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Algoritmaların Analizi

Algoritmalar Java programlama dilinde soldaki resimde gözüken hiyerarşik yapıda yazıldı.(Kaynak kodlarını eklerde bulabilirsiniz)

JUNIT tabanlı TestCase.java’da algoritmalara hız testi uygulanacak biçimde her biri için bir test hazırlandı.

“Main.java” da ise solda belirtilen TestCase 10000000 karakterlik yazı ile 1’den 100’e kadar karakter içeren şablon yazı

için tekrarlı olarak çalıştırıldı.

1. Test Çıktısı

Yazı Boyutu Şablon BoyutuBruteForce Eşleşen

KonumBruteForce Geçen Süre

Horspool Eşleşen Konum

Horspool Geçen Süre

10000000 1 80 0.015395 80 0.11545810000000 2 973 0.035407 973 0.17190410000000 3 23407 0.669144 23407 0.73841810000000 4 404426 1.41526 404426 4.05129610000000 5 9022507 25.066208 9022507 64.97263110000000 6 8697733 24.203095 8697733 54.69224210000000 7 9652870 26.750357 9652870 52.70020510000000 8 7777683 21.695859 7777683 37.11541510000000 9 7717201 21.269434 7717201 34.29105410000000 10 8701330 24.161018 8701330 34.09297910000000 11 8051443 22.223374 8051443 31.1336610000000 12 9175457 25.43824 9175457 31.46925810000000 13 9375920 26.022715 9375920 31.14084410000000 14 8685293 23.734079 8685293 26.33470910000000 15 7720784 21.190409 7720784 23.17064310000000 16 8249263 23.063909 8249263 23.33690310000000 17 9670253 26.437851 9670253 26.23772410000000 18 9534411 26.298788 9534411 22.4281210000000 19 8116247 22.569748 8116247 20.72755110000000 20 7563326 20.78143 7563326 18.36912610000000 21 8523191 23.24659 8523191 19.50677410000000 22 7930522 21.734858 7930522 18.48407210000000 23 9097249 24.69777 9097249 19.56424610000000 24 7692704 21.335117 7692704 15.72077410000000 25 8125680 22.399384 8125680 17.17092810000000 26 9972953 27.660167 9972953 18.65597510000000 27 8259860 22.577445 8259860 16.5679810000000 28 9309122 25.638368 9309122 17.68407510000000 29 7757384 21.227868 7757384 15.04085410000000 30 9562744 26.303919 9562744 17.943214

Page 6: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Yazı Boyutu Şablon BoyutuBruteForce Eşleşen

KonumBruteForce Geçen Süre

Horspool Eşleşen Konum

Horspool Geçen Süre

10000000 31 9895385 26.885315 9895385 18.24545710000000 32 8499140 23.492899 8499140 15.62430210000000 33 7583286 20.731142 7583286 12.23907110000000 34 9531987 25.865692 9531987 16.46945510000000 35 7761371 21.084701 7761371 14.33527710000000 36 7712962 21.164751 7712962 13.41520410000000 37 9559433 25.884678 9559433 16.90717110000000 38 7515724 20.847113 7515724 13.31616710000000 39 9050593 24.96871 9050593 14.00634910000000 40 9526825 26.384484 9526825 15.33899310000000 41 8054999 22.556406 8054999 12.65010210000000 42 8306592 22.907912 8306592 12.52848610000000 43 8385770 23.07725 8385770 13.87395810000000 44 8530273 23.676607 8530273 13.3818510000000 45 9128265 25.072879 9128265 13.09910610000000 46 9193643 25.125734 9193643 13.71077710000000 47 8237723 22.903806 8237723 13.67023810000000 48 8636092 24.018876 8636092 12.47563210000000 49 7983668 22.350634 7983668 12.70141710000000 50 7950437 21.61786 7950437 11.41085110000000 51 8904124 24.447354 8904124 14.55028510000000 52 8311936 22.947424 8311936 13.93040410000000 53 9231711 25.213482 9231711 14.25522610000000 54 9062756 24.445814 9062756 12.24112410000000 55 9110324 25.15293 9110324 14.23418710000000 56 9820924 26.808343 9820924 12.38223910000000 57 9590341 26.165883 9590341 12.77838810000000 58 7629241 20.339611 7629241 9.53478610000000 59 9985700 27.63451 9985700 14.01866510000000 60 7703704 21.367957 7703704 11.77877810000000 61 8104215 22.281873 8104215 11.93477510000000 62 8788878 23.822853 8788878 12.15286210000000 63 8481886 23.539596 8481886 11.73105610000000 64 9498661 25.657867 9498661 13.41982310000000 65 7980693 22.148454 7980693 11.75209510000000 66 8610630 23.591937 8610630 11.06345110000000 67 8625892 23.588859 8625892 11.89577610000000 68 9104906 25.228363 9104906 13.20840610000000 69 9040568 24.182057 9040568 10.81098310000000 70 7767272 21.46289 7767272 10.62830210000000 71 7560120 20.852759 7560120 11.01470310000000 72 8105025 22.276741 8105025 10.95312510000000 73 9198056 25.224258 9198056 12.26216210000000 74 9455268 25.90777 9455268 12.89282110000000 75 9752805 27.049009 9752805 14.15567510000000 76 8417312 23.144473 8417312 11.58788810000000 77 8752620 23.951653 8752620 11.16556710000000 78 9884949 27.13727 9884949 11.5801910000000 79 7724351 21.230947 7724351 10.97159810000000 80 8493743 22.738574 8493743 9.792899

Page 7: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Yazı Boyutu Şablon BoyutuBruteForce Eşleşen

KonumBruteForce Geçen Süre

Horspool Eşleşen Konum

Horspool Geçen Süre

10000000 81 8728844 23.997836 8728844 12.52899910000000 82 9614302 26.811422 9614302 12.24830810000000 83 8294439 23.162433 8294439 11.15376510000000 84 7770644 21.387457 7770644 9.48039210000000 85 8285835 22.852492 8285835 10.378410000000 86 9872020 26.732911 9872020 11.93836710000000 87 9612393 26.128423 9612393 15.83315410000000 88 9554464 25.821049 9554464 11.75773910000000 89 8443063 23.362561 8443063 12.01533910000000 90 8338894 22.852492 8338894 10.36557110000000 91 8431209 22.93357 8431209 12.72040310000000 92 9056025 24.866082 9056025 12.11848210000000 93 8174466 22.633892 8174466 10.28500710000000 94 7963535 22.167955 7963535 11.26922310000000 95 7525507 20.973348 7525507 11.21072410000000 96 8614163 23.963455 8614163 10.29321710000000 97 9589647 26.58769 9589647 13.71334310000000 98 8685110 23.649409 8685110 10.67448610000000 99 9375489 25.935993 9375489 10.73349710000000 100 7595301 20.566422 7595301 9.549155

Sonuç

BruteForce algoritması sürekli aynı karmaşıklıkta veri ararken, Horspool algoritması ilk aşamalarda yüksek karmaşıklıkta arama yapmasının ardından yazı şablonunun boyutunun birkaç karakter artmasından sonra yaklaşık %50 oranında daha az kaynak tüketimi ile daha performanslı olarak çalışmıştır.

Page 8: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Ekler

1. TestCase.java: package com.hw02;

import java.util.HashMap;import java.util.Map;

import org.junit.After;import org.junit.Before;import org.junit.Rule;import org.junit.Test;import org.junit.rules.TestName;

public class TestCase {AAlgorithm algorithm;@Rulepublic TestName name = new TestName(); // Çalıştırılan her algoritmanın adını almak için “Kural” tanımladık

public static char[] text; // Yazı ‘Main’ sınıfında oluşturuluyorpublic static char[] pattern; // Yazı ‘Main’ sınıfında oluşturuluyorpublic static Map<String, Double> map = new HashMap<String, Double>();

long start;

@Beforepublic void setUp() throws Exception { // burası her algoritma başlamadan önce çalışıyor

algorithm = createObject(Class.forName("com.hw02.algorithm." + name.getMethodName())); // Hangi algoritma çalıştırılacağını belirledik

start = System.nanoTime(); // başlangıç saatini aldık}@Afterpublic void tearDown() throws Exception { // burası her algoritma bitince çalışıyor

double duration = (System.nanoTime() - start) / 1000000D;map.put(name.getMethodName(), duration);

}@Testpublic void BruteForce() {

exec();}@Testpublic void Horspool() {

exec();}

private void exec() {try { // Elimizdek yazı içinde şablonu belirlenmiş algoritma ile çalıştırıyoruz ve bulunan index’i

saklıyoruzmap.put(name.getMethodName() + "_INDEX", Double.valueOf(algorithm.sort(text, pattern)));

}catch (Exception e) {

e.printStackTrace(); // hata alırsak loga basıyoruz}

}

public static AAlgorithm createObject(Class<?> klass) { // algoritmaların Sınıf’ı ile nesnesini oluşturan kısım

try {return (AAlgorithm) klass.newInstance();

}catch (Exception e) {

e.printStackTrace();// Hata alırsak görmek adına loga basıyoruzreturn null;

}}

}

Main.java:package com.hw02;

import java.io.File;import java.io.FileNotFoundException;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.security.SecureRandom;import java.util.Arrays;

import org.junit.runner.JUnitCore;

Page 9: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

public class Main {private static SecureRandom random = new SecureRandom();

public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {int patternSize = 1; // Şablonun başlangıç boyutufinal int textSize = 10000000; // Yazı boyutufinal int MAX_PATTERN_SIZE = 100; // En fazla şablon boyutuint startIndex; // Başlangıç konumuchar line = '\0'; // ilk test çalıştırılmasında ilk başa “enter” basmayacağız sonrasında her test

çalıştırılmasından sonra

StringBuilder builder = new StringBuilder();

TestCase.text = generateArray(textSize);

for (; patternSize <= MAX_PATTERN_SIZE; patternSize++) {startIndex = (TestCase.text.length / 4) * 3 + random.nextInt((TestCase.text.length / 4) -

patternSize); // Şablonun yazıda olduğundan emin olmak adına,// bi altta elimizdeki yazıyı 4’e böldüğümüzdeki son çeyreğinden örnek şablon aldıkTestCase.pattern = Arrays.copyOfRange(TestCase.text, startIndex, startIndex + patternSize);

JUnitCore.runClasses(TestCase.class); // Testi çalıştır// Aşağıdaki gibi sırasıyla “TestCase” sınıfında oluşan test çıktılarını önbelleğe alif (line == '\n')

builder.append(line);builder.append(textSize);builder.append('\t'); // her bir veri kolonu arasına “tab” karakteri koydukbuilder.append(patternSize);builder.append('\t');builder.append(TestCase.map.get("BruteForce_INDEX").intValue());builder.append('\t');builder.append(TestCase.map.get("BruteForce"));builder.append('\t');builder.append(TestCase.map.get("Horspool_INDEX").intValue());builder.append('\t');builder.append(TestCase.map.get("Horspool"));line = '\n';

TestCase.map.clear();System.gc();

}

PrintWriter print = new PrintWriter(System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "out.txt", "UTF-8"); // Masaüstünde bir “out.txt” adında bir dosya oluşturduk

print.print(builder); // Testlerden elde ettiğimiz veriyi dosyaya yazdıkprint.close(); // dosyayı kapattık

}

public static char[] generateArray(int size) {char[] array = new char[size];for (int i = size - 1, j = 0; i >= 0; i--, j++) {

array[j] = AAlgorithm.ALPHABET[random.nextInt(AAlgorithm.ALPHABET.length)];}return array;

}}

AAlgorithm.java (Abstract Class):package com.hw02;

public abstract class AAlgorithm {public static final char[] ALPHABET = "abcçdefgğhıijklmnoöprsştuüvyz".toCharArray();

/** * bulunan index’i döndürür */public abstract int sort(char[] text, char[] pattern);

}

BruteForce.java:package com.hw02.algorithm;

import com.hw02.AAlgorithm;

public class BruteForce extends AAlgorithm {

@Overridepublic int sort(char[] text, char[] pattern) {

Page 10: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

int i, j; for (i = 0, j = 0; i < text.length && j < pattern.length; i++) { // yazı boyutu kadar gitmeliyiz, şablon

boyutu kadar kontrol ettiysek demekki sonuca ulaşmışız.if (text[i] == pattern[j]) // eşleşen karakter varsa bir sonrakini kontrol et

j++;else {

i -= j;j = 0;

}}if (j == pattern.length)

return i - pattern.length;else

return -1;}

}

Horspool.java:package com.hw02.algorithm;

import com.hw02.AAlgorithm;

public class Horspool extends AAlgorithm {private static int[] shiftTable = new int[ALPHABET.length];@Overridepublic int sort(char[] text, char[] pattern) {

prepareTable(pattern); // kaydırma boyutlarının tutulduğu tabloyu oluştur// şablonun boyutuyla başlaint i = pattern.length - 1, k;

// bulundu mu?isMatch: while (i < text.length) {

k = i;for (int j = pattern.length - 1; j >= 0; j--) {

if (pattern[j] == text[k]) {// karakter uyuşuyorsa bir sonrakine geçk--;continue;

}else {

i += shiftTable[getCharIndex(text[i])]; // karakterin kaydırma değerliği kadar kaydır

continue isMatch;}

}return k + 1; // yukarıdaki “for” döngüsünde eğer “j” sıfırandıysa buraya gelecek ve şablonun

tamamen eşleşmiş olduğu anlaşılacak, bu yüzden bulduğumuz konumu döndürüyoruz.}return -1;

}public void prepareTable(char[] pattern) {

for (int i = 0; i < shiftTable.length; i++) {shiftTable[i] = pattern.length; // ilk başta bütün karakter değerliklerini şablon byutu yap

}for (char c : pattern) {

shiftTable[getCharIndex(c)] = shiftCount(c, pattern); // şablon karakterlerini sırasıyla değerliklerini hesapla

}}private Integer shiftCount(char c, char[] pattern) {

for (int i = pattern.length - 2/* şablonun son karakterini yoksay */; i >= 0; i--) {if (pattern[i] == c)

return pattern.length - 1 - i; // m-1-n formülüyle right-most index’i bul}return pattern.length;

}

public int getCharIndex(char i) { // karakterin alfabedeki konumunu bulint j = 0;for (char ch : ALPHABET) {

if (ch == i)return j;

j++;}return -1;

}}

Page 11: BruteForce ve Horspool Algoritmalarının Karşılaştırılmalı Analizi

Kaynakça1. http://en.wikipedia.org/wiki/Search_algorithms

2. http://en.wikipedia.org/wiki/Category:Search_algorithms

3. http://en.wikipedia.org/wiki/Linear_search

4. http://en.wikipedia.org/wiki/Brute-force_search

5. http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm

6. http://alg.csie.ncnu.edu.tw/course/StringMatching/Horspool.ppt

7. String matching Boyer Moore's and Horspool Algorithm, https://www.youtube.com/watch?v=rDPuaNw9_Eo