Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Anagramacja (permutacja), scrabble i zapytanie MySQL
altruista2
post 8.02.2010, 17:05:23
Post #1





Grupa: Zarejestrowani
Postów: 127
Pomógł: 32
Dołączył: 8.02.2010

Ostrzeżenie: (0%)
-----


Na początek chciałbym przywitać wszystkich, jestem tu nowy smile.gif

Oto problem:

Tworzę stronę o scrabble i chcę zrobić narzędzie anagramator takie jak tu:
http://www.pfs.org.pl/anagramator.php
Chcę osiągnąć jak największą wydajność przy anagramacji i nie potrafię wymyślić dobrej struktury tabeli MySQL ze słówkami jak i samego zapytania. (W bazie znajduje się >1.000.000 słów)

Jedyna rozwiązanie na jakie wpadłem to takie, że tabela składa się ze słowa i 26 kolumn odpowiadającym ilości danej litery w słowie oraz jedej kolumna odpowiadająca ilościom liter w słowie - czyli np. [b]TRAMWAJ[b] to:
Cytat
T - 1
R - 1
A - 2
M - 1
W - 1
J - 1
Długość - 7


zapytanie SQL wygląda tak:
Kod
SELECT Słowo FROM Tabela WHERE T=1 AND R=1 AND A=2 AND M=1 AND W=1 AND J=1 AND Dlugosc=7


Niestety takie zapytanie zajmuje ok. 2-3 sekundy, co jest kompletnie niewydajne.
Próbowałem też z RLIKE, REGEXP itd. ale to wychodzi jeszcze gorzej...

Czy ma ktoś "szybszy" pomysł? smile.gif)


--------------------
Jeśli Ci pomogłem kliknij pomógł. W ten sposób temat zaświeci się na żółto i użytkownicy którzy pomagają nie będą musieli niepotrzebnie klikać. Dziękuję.

"Pomaganie"
Go to the top of the page
+Quote Post
Crozin
post 8.02.2010, 17:25:29
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Nie robiłem żadnych testów, ale wydaje mi się, że lepiej jest najpierw posortować alfabetycznie litery wyszukiwanego zwrotu:
Kod
Crozin -> cinorz (chyba dobrze to zrobiłem)
I wyszukiwać właśnie takiego zwrotu. Oczywiście w bazie danych musiałbyś mieć tabelę ze słowami, kolejną z posortowanymi literami słów oraz ostatnią łączącą obie.

Problem stanowią jedynie te blanki. Jednakże tutaj ograniczyłbyś się ponownie jedynie do wybrania odpowiednich ID z tabeli posegregowanych liter (no cholera zapomniałem jak się to normalnie nazywa biggrin.gif).

Później wystarczy już tylko wybrać listę słów, które są powiązane (tabela powiązań) z danymi posegregowanymi literami. winksmiley.jpg
Go to the top of the page
+Quote Post
altruista2
post 8.02.2010, 17:42:26
Post #3





Grupa: Zarejestrowani
Postów: 127
Pomógł: 32
Dołączył: 8.02.2010

Ostrzeżenie: (0%)
-----


Też myślałem o tym, ale spójrz:

TRAMWAJ =
AAJMWRT

będę chciał zaanagramować AA*MWRT czyli AAMWRT i mi nie znajdzie:

AAJMWRT
AAMWRT


--------------------
Jeśli Ci pomogłem kliknij pomógł. W ten sposób temat zaświeci się na żółto i użytkownicy którzy pomagają nie będą musieli niepotrzebnie klikać. Dziękuję.

"Pomaganie"
Go to the top of the page
+Quote Post
Aztech
post 11.02.2010, 10:39:56
Post #4





Grupa: Zarejestrowani
Postów: 276
Pomógł: 3
Dołączył: 22.10.2003
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Proponuję zapoznanie się z pracą Daniela Janusa na temat systemu Pliquarp, który służy do wyszukiwania słów w Korpusie języka Polskiego (używanego w PWN), no i przede wszystkim polecam przeczytanie książki Knutha o generowaniu wszystkich krotek i permutacji.
Po tej lekturze na pewno przyjdzie Ci jakieś rozwiązanie do głowy biggrin.gif.
Co możesz zrobić (ja tak zrobiłem w swoim programie działającym a'la OSPS/Anagramator to:
I1) stworzyć dodatkową indeksowaną kolumnę zawierającą informację o długości słowa
I2) stworzyć dodatkową indeksowaną kolumnę zawierająca pierwszą literę wyrazu
I3) stworzyć dodatkową kolumnę zawierającą wszystkie litery z wyrazu posortowane od A do Z
Zadawanie zapytania do bazy wyglądałoby następująco:
Z1) Bierzesz wszystkie litery (bez blanków) i tworzysz z nich wszystkie permutacje
Z2) Bierzesz blanki podstawiasz po kolei literki A-Z, tworząc permutacje
Z3) Robisz permutacje obu tych zbiorów, a następnie usuwasz duplikaty, sortujesz litery od A-Z
Z4) Przesyłasz zapytanie do bazy, korzystając z indeksów: I1 oraz I3

Mój programik, napisany w podobny, do powyższego algorytmu, sposób generuje losowo 100 słów 7 literowych a następnie przeszukuje całą bazę, czy nie ma w nim przypadkiem innych słów z tych samych liter. Cały proces, PHP + baza MySQL (MyISAM) + framework PRADO wykonują to zadanie (bez żadnych cache'ów i akceleratorów) w ok 1,5 minuty (1 słowo wraz z permutacjami ok 0,5 sek).

P.S. Proponuję również zapoznać się z tym wątkiem
P.S.2. Aby zoptymalizować twoje zapytanie, dodaj indeks do kolumn z ilością wystąpień danej litery
P.S.3 Aha, jest jeszcze algorytm Knutja-Morrisa-Pratta

Ten post edytował Aztech 11.02.2010, 10:42:25
Go to the top of the page
+Quote Post
altruista2
post 28.02.2010, 17:27:08
Post #5





Grupa: Zarejestrowani
Postów: 127
Pomógł: 32
Dołączył: 8.02.2010

Ostrzeżenie: (0%)
-----


Wielkie dzięki za pomoc!

Patrząc na Twój awatar widzę że jesteś głęboko w temacie smile.gif


--------------------
Jeśli Ci pomogłem kliknij pomógł. W ten sposób temat zaświeci się na żółto i użytkownicy którzy pomagają nie będą musieli niepotrzebnie klikać. Dziękuję.

"Pomaganie"
Go to the top of the page
+Quote Post
scrabblemania.pl
post 4.04.2010, 08:40:29
Post #6





Grupa: Zarejestrowani
Postów: 1
Pomógł: 0
Dołączył: 4.04.2010

Ostrzeżenie: (0%)
-----


mnie się udało osiągnąć całkiem przyzwoite wyniki na mssql wykorzystując zwykle indeksy.

tu można znaleźć gotowe rozwiązanie

scrabble słownik szukanie wyrazów

jeśli jest wystarczająca wydajność chętnie pokaże środek.


pozdrawiam

scrabblemania.pl
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 21.06.2025 - 06:04