ocena posortowania nazw

0

Mam listę nazw, dowolną ilość, powiedzmy że 1000 sztuk przynajmniej;
co jest zapisane na dysku, ale podczas ładowania jest sortowane, co może zbyt długo trwać
gdy to nie jest zbytnio posortowane fizycznie.

Tylko jak ocenić ten stopień posortowania - w procentach, od 0 - wcale, do 100% - posortowane idealnie.

Np. taka lista - 8 nazw może być tak ustawione:
e, f, g, h, a, b, c, d
albo tak:
a, e, b, f, c, g, d, h

i jak zmierzyć, ocenić to posortowanie?

Tak na trupa wydaje się że wystarczy policzyć tylko parki;
i gdy a[i] <= a[i+1] wtedy jest OK, a w przeciwnym razie niedobrze.
Wtedy dla tych dwóch przykładów otrzymamy:
e < f < g < h > a < b < c < d, czyli 7 na 8 stoi OK, a tylko jedna para nie pasuje: h > a
co daje aż: 7/8 = 87.5% współczynnik posortowania... lekka przesada chyba, bo to raczej wygląda na 50%.

drugi przypadek:
a < e > b < f > c < g > d < h; czyli tylko 4 na 8 są OK, co daje 50% posortowania... w zasadzie dobrze chyba.

Zatem ta metoda nie jest zbyt dobra do oceny posortowania.
Jak to się mierzy profesjonalnie?

0

To zależy co rozumiesz przez "ocenę posortowania". Co ten wskaźnik ma oceniać? To w jakim stopniu elementy są na poprawnych pozyjach? To jak szybko można dany ciąg posortować?

Opisany przez ciebie sposób to liczenie inwersji i miałby on sens gdybyś sortował na przykład listę, bo możesz wtedy przepinać całe ciągi danych. Jeśli dane są w tablicy to ten sposób przestaje być taki sensowny, chyba że liczyłbyś wszystkie inwersje, tzn nie tylko pary liczb obok siebie, ale porównywał każdą liczbę ze wszystkimi pozostałymi i na tej podstawie liczył ile dla danej liczby masz inwersji.
Możesz też po prostu policzyć ile jaki % elementów jest "na swoim miejscu", niemniej to wymagałoby posortowania danych.

Jeśli to co opisujesz to nazwy to może warto je jednak sortować za pomocą zliczania i sortowania pozycyjnego?

0

Możesz wziąć jakiś algorytm sortujący, dodać do niego liczenie operacji i ustalić maksymalną liczbę możliwych operacji.

Stopień posortowania to będzie:
A = (liczba_operacji / maks_liczba_operacji) * 100

Przez maks_liczba_operacji można rozumieć pesymistyczną złożoność algorytmu. Np. dla algorytmu bąbelkowego = n^2.

0

Ja to ładuję czytając kolejne nazwy z dysku, i wstawiając od razu w tablicę, tak aby była posortowana.

Nie sortuję tego po załadowaniu w całości, bo to trwa znacznie dłużej, chyba ponad 10 razy dłużej dla qsorta (sprawdzałem to).

Zatem moja metoda jest taka:

  1. czytam jeden rekord
  2. szukam go w tablicy metodą binarną, wtedy mam pozycję: k, na której ma być wsadzony
  3. wstawiam go do tablicy na pozycji k, przesuwając całość od k o jedną pozycję do przodu

złożoność jest tu mniejsza od qsorta:
porównania: ln1 + ln2 + ln3 + ... = ln (n!), natomiast qsort ma nln(n) = ln (n^n);
no i widać że n^n > n!, czyli qsort jest tu gorszy.

kopiowania: rzędu n^2/2, co jest chyba znacznie gorsze od qsorta,
tylko że ja sortuję tablicę wskaźników, więc to dla n = 100 tyś. = 10^5 elementów daje średnio:
10^10 = 10G sztuk, no ale ram jest dość szybki - w sekundę kopiuje kilka GB, więc tego praktycznie nie widać.

0

Jak trzymasz w pamięci i tam ciągle robisz wyszukiwania binarne, to może zainteresuj się drzewami BST? One od razu służą do tego, aby szybko w nich wyszukiwać i w nich przechowywać posortowane informacje, które będą dokładane w miarę ich odczytu.

0
Ktos napisał(a):

Jak trzymasz w pamięci i tam ciągle robisz wyszukiwania binarne, to może zainteresuj się drzewami BST? One od razu służą do tego, aby szybko w nich wyszukiwać i w nich przechowywać posortowane informacje, które będą dokładane w miarę ich odczytu.

Raczej byłoby niewygodne w praktycznym użyciu.
Ja tworzę także różne podzbiory, np. użytkownik chce wyszukać rekordy które zawierają jakieś tam słówka, albo wedle długości - od - do, lub innych danych rekordu, np. nazwa może mieć swój opis, więc szukamy po tych opisach.

Ostatecznie jest to wyświetlane w posortowanej liście.

Ogóle generowanie listy wygląda tak:

  1. czytaj kolejny rekord
  2. sprawdź czy on pasuje do wybranych kryteriów, jeśli tak to - wstawiaj do list, inaczej pomiń

pokaż listę... posortowaną.

0

@blahu ale w takim razie to może pomyślisz o jakichś indeksach na tych danych przynajmniej? Wyobraź sobie że obok danych trzymasz listę która przechowuje kolejność indeksów twoich danych posortowanych po zadanym polu. Taka lista będzie zajmowała bardzo względnie niewiele (na pewno znacznie mniej niż same dane) a czas odczytu z tych danych będzie szybszy. Poza tym pomyśl też o innych indeksach. Albo w ogóle o hurtowni danych z wielowymiarowymi kostkami, bo to właśnie piszesz...

0
Shalom napisał(a):

@blahu ale w takim razie to może pomyślisz o jakichś indeksach na tych danych przynajmniej? Wyobraź sobie że obok danych trzymasz listę która przechowuje kolejność indeksów twoich danych posortowanych po zadanym polu. Taka lista będzie zajmowała bardzo względnie niewiele (na pewno znacznie mniej niż same dane) a czas odczytu z tych danych będzie szybszy. Poza tym pomyśl też o innych indeksach. Albo w ogóle o hurtowni danych z wielowymiarowymi kostkami, bo to właśnie piszesz...

To jest wyszukiwanie wg literek w samych hasłach - kluczach, jak i dowolnych fraz w zdaniach, opisach... no i dowolnych innych danych rekordu, np. jakaś data, kategoria tematyczna, gramatyczna - jeden bit, itd.

Zatem nie da rady tego indeksować w żaden sensowny sposób.

Być może użycie drzewa, zamiast listy byłoby pomocne pod kątem sortowania tego szybciej o 10% lub coś koło tego zapewne,
czyli w zasadzie zerowy postęp, tylko że straciłbym możliwość prostego numerowania elementów typu:

x = t[numer_linii], i rysuj mi ten x.

od biedy można zrezygnować z numerowania, co zapewne robi się w bazach danych... wtedy tam jest tylko poprzedni lub następny element, ale numeru pozycji nie ma... tam często nawet nie wiemy ile mamy elementów;

w praktyce kod musiałby wyglądać jakoś tak:
e = next(e);
if e <> nil then jest coś... więc rysuj, else rysuj nic. :)

0

Ewentualnie coś takiego byłoby chyba niezłe:
http://www.chiark.greenend.org.uk/~sgtatham/algorithms/cbtree.html

Tylko że musiałbym chyba przerabiać cały programik od nowa... w zasadzie robić od zera - tworzyć te porąbane algorytmy drzewiaste, itd.

0

A jak te bazy w paskalu, np. z Delphi 7, się sprawują na nowych komputerach - Win7 i dalej?

1 użytkowników online, w tym zalogowanych: 0, gości: 1