Files
AiSD/projekt 2/main.cpp

395 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <iostream>
#include <algorithm>
#include <chrono>
#include <random>
#include <iomanip>
//#include <limits>
//#include <algorithm>
//#include <string>
//#include <iomanip>
//#include <fstream>
//#include <clocale>
#define EMPTY -1 // puste miejsce w tablicy mieszajacej
#define REMOVED -2 // puste miejsce tablicy mieszajacej z ktorego usuniety zostal jakis element
long long int g_counter {0};
//Zad. 1 Wstawianie do tablicy mieszajacej (adresowanie liniowe)
/** Funkcja mieszająca wykorzystująca adresowanie liniowe
@param x element dla którego obliczamy wartość funkcji mieszającej
@param m rozmiar tablicy do której wstawiamy (parametr funki mieszajacej)
@param i która to próba wstawienia/które obliczenie funkcji mieszającej (parametr funki mieszajacej)
@return wartość f. mieszającej, pod ten indeks próbujemy wstawić potem x
*/
int h(int x, int m, int i){
g_counter++;
if (i==0) {
return x % m;
} else {
return (x % m + i) % m;
}
};
int h_kw(int x, int m, int i){
g_counter++;
int formula = ((x % m) + (2 * i * i) - (5*i)) % m;
return (formula<0) ? (m+formula)%m : formula;
};
int h_d(int x, int m, int i){
g_counter++;
int formula = ((x % m) + i*((((x/m)%(m/2))*2) + 1))%m;
return formula;
};
/*
*h(x, i, m) = (h1(x, m) + i*(h2(x, m)) mod m dla: i = 0, 1, 2, . . . , m 1,
h1(x, m) = x mod m,
h2(x, m) = (((x/m) mod (m/2)) * 2) + 1.
*
** Funkcja wstawiajaca jeden element x do tablicy mieszajacej tab o rozmiarze m
@param A tablica mieszajaca
@param m rozmiar tablicy mieszajacej
@param x element wstawiany do tablicy
@return true, jesli element zostal wstawiony; false, jesli nie udalo sie wstawic elementu (brak miejsca w tablicy)
*/
bool hash_al_wstaw(int * A, int m, int x)
{
// Zaimplementuj
//...
for (int i = 0; i < m-1; i++) {
int k = h(x, m, i);
if (A[k] == EMPTY || A[k] == REMOVED){
A[k]=x;
return true;
}
}
return false;
}
bool hash_al_szukaj(int * A, int m, int x){
for (int i = 0; i < m; i++) {
int k = h(x, m, i);
if (A[k] == x){ return true;}
if (A[k] == EMPTY){ return false;}
}
return false;
}
bool hash_al_wstaw_kw(int * A, int m, int x)
{
// Zaimplementuj
//...
for (int i = 0; i < m-1; i++) {
int k = h_kw(x, m, i);
if (A[k] == EMPTY || A[k] == REMOVED){
A[k]=x;
return true;
}
}
return false;
}
bool hash_al_szukaj_kw(int * A, int m, int x){
for (int i = 0; i < m; i++) {
int k = h_kw(x, m, i);
if (A[k] == x){ return true;}
if (A[k] == EMPTY){ return false;}
}
return false;
}
bool hash_al_wstaw_d(int * A, int m, int x)
{
// Zaimplementuj
//...
for (int i = 0; i < m-1; i++) {
int k = h_d(x, m, i);
if (A[k] == EMPTY || A[k] == REMOVED){
A[k]=x;
return true;
}
}
return false;
}
bool hash_al_szukaj_d(int * A, int m, int x){
for (int i = 0; i < m; i++) {
int k = h_d(x, m, i);
if (A[k] == x){ return true;}
if (A[k] == EMPTY){ return false;}
}
return false;
}
int main()
{
std::cout << "Zadanie 1 i 2:\n";
// Zad. 2 (rozgrzewka + test)
const int m1 = 8; //rozmiar tablicy mieszajacej
int t[m1]; //tablica mieszajaca
// Wyczyszczenie tablicy mieszajacej t (Wypelnienie pustymi miejscami)
for (int i = 0; i < m1; i++)
{
t[i] = EMPTY;
}
// Wstawianie elementów do tablicy mieszajacej t (uzyć funkcji hash_al_wstaw)
for(int x : {8,6,18,11,3,32,19,27})
{
hash_al_wstaw(t, m1, x);
}
// ...
// Wyswietlenie tablicy mieszajacej t o rozmiarze m1
std::cout << std::setw(7) << "indeks:";
for (int i = 0; i < m1; i++)
{
std::cout << std::setw(11) << i;
}
std::cout << std::endl;
std::cout << std::setw(8) << "|";
for (int i = 0; i < m1; i++)
{
std::cout << std::setw(10) << t[i] << "|" ;
}
std::cout << std::endl;
// Zad. 3 Pomiary
std::cout << "\nZadanie 3:\n";
// a) Tablica z danymi
// Tworzenie tablicy dane z danymi do wstawinia do tablicy mieszajacej
int rozm_dane = 20000000; //liczba elementow w tablicy dane
int* dane = new int[rozm_dane];
//wypelnienie tablicy dane kolejnymi liczbami od 0 do rozm_dane-1
for (int i = 0;i < rozm_dane;i++)
{
dane[i] = i;
}
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(dane, dane + rozm_dane, g); //losowa permutacja elementow w tablicy dane (wymieszanie tablicy)
// b) Tablica mieszajaca
// Utworz pusta tablice mieszajaca tab o rozmiarze m = 2097152 (2 do potegi 21)
const int m = 2097152;
int * tab = new int[m];
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
// ...
// c) Wstaw 10000 elemetow z tablicy dane do pustej tablicy mieszajacej tab (zapelnienie 0%). Na tej podstawie zmierz sredni czas wstawiania elementu oraz srednią liczbe wywolan funkcji mieszajacej przy wstawianiu elementu do pustej tablicy.
std::cout << "Pomiary:\n";
g_counter = 0;
// Mierzenie czasu, przyklad:
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
hash_al_wstaw(tab, m, dane[i]);
}
//tutaj mierzona operacja
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n";
// d) Zmierz sredni czas wstawiania elementu oraz srednią liczbe wywolan funkcji mieszajacej przy wstawianiu elementu do tablicy wypelnionej w 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% (dla próbki: 10000 elementów).
//UWAGA! Do tablicy mieszajacej nie wstawiac elementow, ktore juz w niej sa.
for(double range : {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
g_counter = 0;
for (int i = 0; i < range*m; i++) {
hash_al_wstaw(tab, m, dane[i]);
}
g_counter = 0;
// Mierzenie czasu, przyklad:
std::cerr << "Pomiar dla " << range*100 << "%\n";
auto start = std::chrono::high_resolution_clock::now();
for (int i = range*m; i < (range*m)+10000; i++) {
hash_al_wstaw(tab, m, dane[i]);
}
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n";
}
std::cerr << std::endl;
for(double range : {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
g_counter = 0;
for (int i = 0; i < range*m; i++) {
hash_al_wstaw(tab, m, dane[i]);
}
g_counter = 0;
// Mierzenie czasu, przyklad:
std::cerr << "Pomiar wyszukiwania dla " << range*100 << "%\n";
int idx=0;
int krok = (range*m)/10000;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
hash_al_szukaj(tab, m, dane[idx]);
idx = idx+krok;
}
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji szukającej: " << g_counter << "\n";
}
//...
std::cerr<<std::endl;
std::cerr<<std::endl;
std::cerr<<std::endl;
for(double range : {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
g_counter = 0;
for (int i = 0; i < range*m; i++) {
hash_al_wstaw_kw(tab, m, dane[i]);
}
g_counter = 0;
// Mierzenie czasu, przyklad:
std::cerr << "Pomiar wstawiania kwadratowego dla " << range*100 << "%\n";
auto start = std::chrono::high_resolution_clock::now();
for (int i = range*m; i < (range*m)+10000; i++) {
hash_al_wstaw_kw(tab, m, dane[i]);
}
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n";
}
std::cerr << std::endl;
for(double range : {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
g_counter = 0;
for (int i = 0; i < range*m; i++) {
hash_al_wstaw_kw(tab, m, dane[i]);
}
g_counter = 0;
// Mierzenie czasu, przyklad:
std::cerr << "Pomiar wyszukiwania kwadratowego dla " << range*100 << "%\n";
int idx=0;
int krok = (range*m)/10000;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
hash_al_szukaj_kw(tab, m, dane[idx]);
idx = idx+krok;
}
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji szukającej: " << g_counter << "\n";
}
std::cerr<<std::endl;
std::cerr<<std::endl;
std::cerr<<std::endl;
for(double range : {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
g_counter = 0;
for (int i = 0; i < range*m; i++) {
hash_al_wstaw_d(tab, m, dane[i]);
}
g_counter = 0;
// Mierzenie czasu, przyklad:
std::cerr << "Pomiar wstawiania podwójnego dla " << range*100 << "%\n";
auto start = std::chrono::high_resolution_clock::now();
for (int i = range*m; i < (range*m)+10000; i++) {
hash_al_wstaw_d(tab, m, dane[i]);
}
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n";
}
std::cerr << std::endl;
for(double range : {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){
for (int i = 0; i < m ; i++)
{
tab[i] = EMPTY;
}
g_counter = 0;
for (int i = 0; i < range*m; i++) {
hash_al_wstaw_d(tab, m, dane[i]);
}
g_counter = 0;
// Mierzenie czasu, przyklad:
std::cerr << "Pomiar wyszukiwania podwójnego dla " << range*100 << "%\n";
int idx=0;
int krok = (range*m)/10000;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
hash_al_szukaj_d(tab, m, dane[idx]);
idx = idx+krok;
}
auto stop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> czas = stop - start;
std::cerr << "Uplynelo: " << czas.count() << " us\n";
std::cerr << "Ilość wywołań funkcji szukającej: " << g_counter << "\n";
}
return 0;
}