Dzisiaj przetestujemy nasz algorytm po raz kolejny!

Zestaw testowy

Tym razem jako zestaw testowy posłużą nam kody źródłowe z kursu programowania z moich studiów. Podczas kursu trzeba było między innymi napisać programy, które rozłożą liczbę na czynniki pierwsze oraz wyliczą sito Eratostenesa. I właśnie kody źródłowe do tych dwóch zadań poddamy testom.

Udało mi się skolekcjonować po 5 różnych rozwiązań dla każdego z tych zadań. Wszystkie kody źródłowe są dostępne tutaj.

Testowanie

Przetestujmy kody źródłowe dla każdego zadania osobno.

Rozkład liczby na czynniki pierwsze

Zacznijmy najpierw od wczytania kodów źródłowych i wyliczenia prawdopodobieństw.

fun main(args: Array<String>) {
    val root = "C:\\kody_do_testow\\";

    val codes1: MutableList<String> = mutableListOf()
    for (i in 1..5) {
        codes1.add(FileInputStream(root + "RozkladLiczbyTest.java (" + i + ")").bufferedReader().use { it -> it.readText() })
    }

    for (i in codes1.indices) {
        for (j in i + 1..codes1.size - 1) {
            val calculate = PlagDetectorAlgorithm().calculate(LexerType.JAVA_8, codes1[i], codes1[j])
            println(String.format("compared codes %d-%d d=%.2f, px=%.2f, py=%.2f", i + 1, j + 1, calculate.d, calculate.px, calculate.py))
        }
    }
}

Po wywołaniu powyższego kodu otrzymaliśmy następujące wyniki:

compared codes 1-2 d=0.78, px=0.91, py=0.84
compared codes 1-3 d=0.51, px=0.67, py=0.67
compared codes 1-4 d=0.27, px=0.41, py=0.44
compared codes 1-5 d=0.30, px=0.46, py=0.47
compared codes 2-3 d=0.66, px=0.77, py=0.82
compared codes 2-4 d=0.27, px=0.39, py=0.45
compared codes 2-5 d=0.30, px=0.44, py=0.48
compared codes 3-4 d=0.26, px=0.40, py=0.43
compared codes 3-5 d=0.29, px=0.44, py=0.45
compared codes 4-5 d=0.87, px=0.96, py=0.91

Przeglądając wyniki możemy zauważyć, że kody źródłowe programów 4 i 5 zostały wskazane jako bardzo podobne do siebie. Zachęcam, aby przejrzeć te kody oraz porównać również z innymi. Łatwo możemy zauważyć, że te dwa kody źródłowe wykazują bardzo dużo cech wspólnych 😉

Podobnie sprawa wygląda w przypadku kodów 1 i 2, lecz podobieństwo jest już trochę mniej widoczne.

Sito Eratostenesa

Kolejnym zestawem będą programy, które implementują algorytm Sita Eratostenesa. Podobnie jak poprzednio zacznijmy od wczytania kodów źródłowych i wyliczenia podobieństw pomiędzy nimi.

fun main(args: Array<String>) {
    val root = "C:\\Users\\lantkowiak\\Downloads\\kody_do_testow-20170528T210254Z-001\\kody_do_testow\\test3\\lista2\\";

    val codes1: MutableList<String> = mutableListOf()
    for (i in 1..5) {
        codes1.add(FileInputStream(root + "SitoErastotenesaTest.java (" + i + ")").bufferedReader().use { it -> it.readText() })
    }

    for (i in codes1.indices) {
        for (j in i + 1..codes1.size - 1) {
            val calculate = PlagDetectorAlgorithm().calculate(LexerType.JAVA_8, codes1[i], codes1[j])
            println(String.format("compared codes %d-%d d=%.2f, px=%.2f, py=%.2f", i + 1, j + 1, calculate.d, calculate.px, calculate.py))
        }
    }
}

I wyniki, które otrzymaliśmy po uruchomieniu powyższego kodu:

compared codes 1-2 d=0.95, px=0.98, py=0.97
compared codes 1-3 d=0.53, px=0.67, py=0.72
compared codes 1-4 d=0.33, px=0.46, py=0.54
compared codes 1-5 d=0.37, px=0.54, py=0.55
compared codes 2-3 d=0.55, px=0.68, py=0.74
compared codes 2-4 d=0.32, px=0.45, py=0.53
compared codes 2-5 d=0.36, px=0.52, py=0.54
compared codes 3-4 d=0.37, px=0.52, py=0.56
compared codes 3-5 d=0.35, px=0.53, py=0.50
compared codes 4-5 d=0.68, px=0.86, py=0.76

Tutaj możemy dostrzec, że największe prawdopodobieństwo plagiatu zachodzi pomiędzy programami 1 i 2. I ponownie gdy obejrzymy oba kody źródłowe znajdziemy widoczne podobieństwo.

Podsumowanie

Dzisiaj przetestowaliśmy nasz algorytm na zestawie kodów źródłowych z moich studiów. Analizując wyniki mogliśmy wskazać kody, które wykazywały nieprzeciętne podobieństwo 😉 Wydaje się, że algorytm działa dosyć dobrze i całkiem nieźle wskazuję podobne kody źródłowe.