Aaaaa988

33

Feb 21st, 2021
667
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package ru.lab1;
  2.  
  3. import java.io.*;
  4. import java.util.ArrayList;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. public class Main {
  9.     static String FILE_NAME1 = "F1.txt";
  10.     static String FILE_NAME2 = "F2.txt";
  11.  
  12.  
  13.     public static void main(String[] args) throws IOException {
  14.         Map<String, Integer> frequencyDictionary1 = new HashMap<>();
  15.         Map<String, Integer> frequencyDictionary2 = new HashMap<>();
  16.         Map<String, Integer> frequencyDictionaryPair1 = new HashMap<>();
  17.         Map<String, Integer> frequencyDictionaryPair2 = new HashMap<>();
  18.  
  19.         writeF1(frequencyDictionary1);
  20.         writeF2(frequencyDictionary2);
  21.         counterPair(FILE_NAME1, frequencyDictionaryPair1);
  22.         counterPair(FILE_NAME2, frequencyDictionaryPair2);
  23.  
  24.         System.out.println("Entropy for F1 = " + shennon(probabilityCalculate(frequencyDictionary1)));
  25.         System.out.println("Entropy for F2 = " + shennon(probabilityCalculate(frequencyDictionary2)));
  26.         System.out.println("Entropy for pair F1 = " + shennon(probabilityCalculate(frequencyDictionaryPair1)) / 2);
  27.         System.out.println("Entropy for pair F2 = " + shennon(probabilityCalculate(frequencyDictionaryPair2)) / 2);
  28.  
  29.         // Считаем теоретическую вероятность
  30.         ArrayList temp = new ArrayList();
  31.         for (int i = 0; i < 4; i++) temp.add(0.25);
  32.  
  33.         System.out.println("Theory entropy for F1 = " + shennon(temp));
  34.  
  35.         temp.clear();
  36.         temp.add(0.05);
  37.         temp.add(0.15);
  38.         temp.add(0.1);
  39.         temp.add(0.7);
  40.  
  41.         System.out.println("Theory entropy for F2 = " + shennon(temp));
  42.     }
  43.  
  44.     /**
  45.      * Считает вхождения всех пар символов (соседних друг с другом)
  46.      * @param filename файл из которого будут считываться данные
  47.      * @param frequencyDictionaryPair результат метода будет здесь
  48.      * @throws IOException
  49.      */
  50.     private static void counterPair(String filename, Map<String, Integer> frequencyDictionaryPair) throws IOException {
  51.         String s;
  52.         BufferedReader reader = new BufferedReader(new FileReader(filename));
  53.         s = reader.readLine();
  54.  
  55.         for (int i = 0; i < s.length() - 1; i++) {
  56.             merge(frequencyDictionaryPair, s.charAt(i) + "" + s.charAt(i + 1));
  57.         }
  58.     }
  59.  
  60.     /**
  61.      * Вычисляет фактические вероятности
  62.      * @param frequencyDictionary количество определенных символов или их последовательностей
  63.      * @return ArrayList полученных вероятностей
  64.      */
  65.     private static ArrayList probabilityCalculate(Map<String, Integer> frequencyDictionary) {
  66.         ArrayList<Double> probability = new ArrayList<>();
  67.         int generalCount = 0;
  68.  
  69.         for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
  70.             generalCount += symbol.getValue();
  71.         }
  72.  
  73.         for (Map.Entry<String, Integer> symbol : frequencyDictionary.entrySet()) {
  74.             probability.add(symbol.getValue().doubleValue() / generalCount);
  75.             //System.out.println(symbol.getKey() + " " + symbol.getValue() + " " + (symbol.getValue().doubleValue() / generalCount));
  76.         }
  77.  
  78.         return probability;
  79.     }
  80.  
  81.     private static double log2(double x){
  82.         return Math.log(x)/Math.log(2);
  83.     }
  84.  
  85.     private static double shennon(ArrayList<Double> probability) {
  86.         double entropy = 0;
  87.  
  88.         for (Double p : probability) {
  89.             entropy += p * log2(p);
  90.         }
  91.  
  92.         return -entropy;
  93.     }
  94.  
  95.     /**
  96.      * Генерирует в файл равновероятную последовательность из четырех символов
  97.      * @param frequencyDictionary1 словарь для посчета количества каждого символа
  98.      * @throws IOException
  99.      */
  100.     private static void writeF1(Map<String, Integer> frequencyDictionary1) throws IOException {
  101.         File file = new File(FILE_NAME1);
  102.         FileWriter writer = new FileWriter(file);
  103.  
  104.         int rnd;
  105.  
  106.         while (file.length() < 10000) {
  107.             for (int i = 0; i < 1024; i++) {
  108.                 rnd = (int) (Math.random() * 4);
  109.  
  110.                 writer.append((char) (rnd + 65));
  111.                 merge(frequencyDictionary1, (char) (rnd + 65) + ""); // счетчик символов
  112.             }
  113.             writer.flush();
  114.         }
  115.     }
  116.  
  117.     /**
  118.      * Последовательно и независимо генерирует символы с определенными вероятностями и записывает их в файл
  119.      * @param frequencyDictionary2 словарь для посчета количества каждого символа
  120.      * @throws IOException
  121.      */
  122.     private static void writeF2(Map<String, Integer> frequencyDictionary2) throws IOException {
  123.         File file = new File(FILE_NAME2);
  124.         FileWriter writer = new FileWriter(file);
  125.  
  126.         int rnd;
  127.         while (file.length() < 10000) {
  128.             for (int i = 0; i < 1024; i++) {
  129.                 rnd = (int) (Math.random() * 100 + 1);
  130.  
  131.                 if (rnd <= 5) {
  132.                     writer.append((char) 65); // вероятность 0.05
  133.                     merge(frequencyDictionary2, (char) 65 + "");
  134.                 } else if (rnd > 5 && rnd <= 20) {
  135.                     writer.append((char) 66); // вероятность 0.15
  136.                     merge(frequencyDictionary2, (char) 66 + "");
  137.                 } else if (rnd > 20 && rnd <= 30) {
  138.                     writer.append((char) 67); //вероятность 0.1
  139.                     merge(frequencyDictionary2, (char) 67 + "");
  140.                 } else if (rnd > 30) {
  141.                     writer.append((char) 68); // вероятноть 0.7
  142.                     merge(frequencyDictionary2, (char) 68 + "");
  143.                 }
  144.             }
  145.             writer.flush();
  146.         }
  147.     }
  148.  
  149.     private static void merge(Map<String, Integer> map, String symbol) {
  150.         if (map.containsKey(symbol)) {
  151.             int oldCount = map.get(symbol);
  152.             map.put(symbol, ++oldCount);
  153.         } else {
  154.             map.put(symbol, 1);
  155.         }
  156.     }
  157. }
  158.  
RAW Paste Data