как вычислить среднюю длину пробника для определения успеха и неудачи - Линейный пробник (хэш-таблицы) [закрыт]

StackOverflow https://stackoverflow.com/questions/2564090

  •  23-09-2019
  •  | 
  •  

Вопрос

Я выполняю задание для своего класса Data Structures.нас попросили изучить линейное зондирование с коэффициентами нагрузки .1, .2 , .3, .... и .9.Формула для тестирования такова:

Средняя длина зонда при использовании линейного зондирования составляет примерно

Успех--> ( 1 + 1/(1- L)**2)/2
или
Сбой -> (1+1(1-L))/2.

от нас требуется найти теоретическое значение, используя приведенную выше формулу, которую я сделал (просто включите коэффициент загрузки в формулу), затем мы должны вычислить эмпирическое значение (что я не совсем уверен, как это сделать).вот остальные требования

** Для каждого коэффициента загрузки - 10 000 случайно сгенерированных положительных целых чисел. от 1 до 50000 (включительно) будут вставлены в таблицу с "правильным" размером, где "правильный" - это строго в зависимости от коэффициента загрузки вы тестируете.Повторы разрешены.Убедитесь, что ваша формула для случайно сгенерированных целых чисел верна.Существует класс, называемый Random в java.util.ИСПОЛЬЗУЙ это!После того, как таблица правильного (основанного на L) размера загрузится с 10 000 целыми числами, выполните 100 поисков по вновь сгенерированным случайным целым числам из диапазона от 1 до 50000.Вычислите среднее значение длины зонда для каждой из двух формул и укажите знаменатели используемые в каждом расчете Так, например, каждый тест для нагрузки .5 будет иметь таблицу > > размера приблизительно 20 000 (скорректировано на простое значение) и аналогично каждый тест для нагрузки .9 будет иметь таблицу приблизительного размера 10 000 / .9 (снова скорректировано на простое значение).

Программа должна запуститься, отображая проверенные различные коэффициенты нагрузки, среднее значение для каждого поиска (два знаменателя, используемые для вычисления средних значений, прибавят к 100) и теоретические ответы с использованием формулы выше..**

как мне рассчитать эмпирический успех?

вот мой код на данный момент:

import java.util.Random;
/**
 *
 * @author Johnny
 */
class DataItem
{
    private int iData;
    public DataItem(int it)
    {iData = it;}
    public int getKey()
    {
        return iData;
    }
}

class HashTable
{
private DataItem[] hashArray;
private int arraySize;
public HashTable(int size)
{
    arraySize = size;
    hashArray = new DataItem[arraySize];
}
public void displayTable()
{
    int sp=0;
    System.out.print("Table: ");
    for(int j=0; j<arraySize; j++)
{
    if(sp>50){System.out.println("");sp=0;}

    if(hashArray[j] != null){
        System.out.print(hashArray[j].getKey() + " ");sp++;}
    else
    {System.out.print("** "); sp++;}
}
    System.out.println("");
}

public int hashFunc(int key)
{
    return key %arraySize;
}

public void insert(DataItem item)
{
    int key = item.getKey();
    int hashVal = hashFunc(key);

    while(hashArray[hashVal] != null &&
                    hashArray[hashVal].getKey() != -1)
    {
        ++hashVal;
        hashVal %= arraySize;
    }
    hashArray[hashVal]=item;
}
public int hashFunc1(int key)
{
    return key % arraySize;
}

public int hashFunc2(int key)
{
// non-zero, less than array size, different from hF1
// array size must be relatively prime to 5, 4, 3, and 2
    return 5 - key % 5;
}


public DataItem find(int key) // find item with key
// (assumes table not full)
    {
    int hashVal = hashFunc1(key); // hash the key
    int stepSize = hashFunc2(key); // get step size
    while(hashArray[hashVal] != null) // until empty cell,
    { // is correct hashVal?
        if(hashArray[hashVal].getKey() == key)
            return hashArray[hashVal]; // yes, return item
        hashVal += stepSize; // add the step
        hashVal %= arraySize; // for wraparound
    }
    return null; // can’t find item
    }
}
public class n00645805 {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    double b=1;
    double L;
    double[] tf = new double[9];
    double[] ts = new double[9];
    double d=0.1;
    DataItem aDataItem;
    int aKey;
    HashTable h1Table = new HashTable(100003); //L=.1
    HashTable h2Table = new HashTable(50051);  //L=.2
    HashTable h3Table = new HashTable(33343);  //L=.3
    HashTable h4Table = new HashTable(25013);  //L=.4
    HashTable h5Table = new HashTable(20011);  //L=.5
    HashTable h6Table = new HashTable(16673);  //L=.6
    HashTable h7Table = new HashTable(14243);  //L=.7
    HashTable h8Table = new HashTable(12503);  //L=.8
    HashTable h9Table = new HashTable(11113);  //L=.9

    fillht(h1Table);
    fillht(h2Table);
    fillht(h3Table);
    fillht(h4Table);
    fillht(h5Table);
    fillht(h6Table);
    fillht(h7Table);
    fillht(h8Table);
    fillht(h9Table);
    pm(h1Table);
    pm(h2Table);
    pm(h3Table);
    pm(h4Table);
    pm(h5Table);
    pm(h6Table);
    pm(h7Table);
    pm(h8Table);
    pm(h9Table);

    for (int j=1;j<10;j++)
    {
        //System.out.println(j);
        L=Math.round((b-d)*100.0)/100.0;
        System.out.println(L);
        System.out.println("ts "+(1+(1/(1-L)))/2);
        System.out.println("tf "+(1+(1/((1-L)*(1-L))))/2);
        tf[j-1]=(1+(1/(1-L)))/2;
        ts[j-1]=(1+(1/((1-L)*(1-L))))/2;
        d=d+.1;
    }
    display(ts,tf);
}
public static void fillht(HashTable a)
{
    Random r = new Random();
    for(int j=0; j<10000; j++)
    {
        int aKey;
        DataItem y;
        aKey =1+Math.round(r.nextInt(50000));
        y = new DataItem(aKey);
        a.insert(y);

    }
}
public static void pm(HashTable a)
{
    DataItem X;
    int numsuc=0;
    int numfail=0;
    int aKey;
    Random r = new Random();
    for(int j=0; j<100;j++)
    {
        aKey =1+Math.round(r.nextInt(50000));
        X = a.find(aKey);
        if(X != null)
        {
            //System.out.println("Found " + aKey);
            numsuc++;
        }
        else
        {
            //System.out.println("Could not find " + aKey);
            numfail++;
        }

    }
    System.out.println("# of succ is "+ numsuc+" # of failures is "+ numfail);
}
public static void display(double[] s, double[] f)
{

}

}

Это было полезно?

Решение

Вы должны принять во внимание, что Java HashTable использует реализацию закрытой адресации (без зондирования), поэтому у вас есть отдельные сегменты, в которые можно поместить много элементов.Это не то, что вы ищете в своих бенчмарках.Я не уверен насчет HashMap реализация, но я думаю, что она также использует открытую адресацию.

Так что забудьте о классах JDK..поскольку вы хотите вычислить эмпирические значения, вам следует написать свою собственную версию хэш-таблицы, которая использует открытое обращение реализация с линейное зондирование но вам следует позаботиться о подсчете длины зонда всякий раз, когда вы пытаетесь получить значение из hashmap..

Например, вы можете написать свою хэш-карту, а затем позаботиться о том, чтобы

class YourHashMap
{
   int empiricalGet(K key)
   {
     // search for the key but store the probe length of this get operation

     return probeLength;
   }
}

Затем вы можете легко сравнить его, выполнив поиск нужного количества клавиш и рассчитав среднюю длину зонда.

В противном случае вы можете просто предоставить hasmap возможность сохранять общую длину зонда и количество запрошенных запросов и извлекать их после выполнения теста для вычисления среднего значения.

Такого рода упражнения должны доказать, что эмпирическая ценность согласуется с теоретической.Поэтому примите также во внимание тот факт, что вам может понадобиться много тестов, а затем рассчитайте среднее значение по всем из них, убедившись, что отклонение не слишком велико.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top