Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 29. 04. 2011 00:05

hessyk
Příspěvky: 86
Reputace:   
 

rozlozeni abecedy na tlacitka mobilniho telefonu

ahoj, nevite nekdo jak rozlozit abecedu na tlacitka mobilniho telefonu tak aby se zachovalo poradi procemz vime cetnosti znaku...a mame to rozlozit tak aby se co nejmene mackalo...v abecede je 1 az n znaku
jestli mate nekdo napad jaky algoritmus by se mel tady uplatnit tak prosim napiste
dekuji moc

Offline

 

#2 29. 04. 2011 09:16 — Editoval Honzc (29. 04. 2011 12:31)

Honzc
Příspěvky: 4592
Reputace:   243 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:
To bude asi nejdříve chtít si sehnat četnost výskytu písmen v psaném textu viz.


a potom ty s největším počtem výskytů dát na tlačítko na první místo (aby stačilo zmáčknout klávesu pouze jednou)

Offline

 

#3 29. 04. 2011 12:16 — Editoval FailED (29. 04. 2011 13:00)

FailED
Příspěvky: 1255
Reputace:   42 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:

Co třeba dynamicky podle počtu mezer mezi tlačítky? Když přidáš mezeru, levou a pravou část sestavíš z menších bloků písmen s menším počtem mezer.


Víš jakou by to mělo mít složitost?

Offline

 

#4 01. 05. 2011 19:46

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

jo cetnost zname...a nevim jak to myslis... o slozitosti nepadla vubec rec...

Offline

 

#5 01. 05. 2011 22:10 — Editoval FailED (02. 05. 2011 14:12)

FailED
Příspěvky: 1255
Reputace:   42 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

Nejjednodušeji pomocí dynamického programování by se to dělalo takhle:

Pro všechny posloupnosti po sobě jdoucích písmen najdeme nejlepší rozmístění na k tlačítek, začneme s posloupnostmi délky 1 a jedním tlačítkem, pro daný počet tlačítek vždycky vypočítáme optimální rozmístění pro všechny posloupnosti.

Optimální rozmístění posloupnosti délky k s l mezerami získáme tak, že budeme postupně vkládat mezery mezi dvojice písmen a počítat optimální rozmístění pomocí už vypočítaných hodnot -  z posloupnosti po novou mezeru a od nové mezery, přitom jedné dáme i mezer, druhé l-i-1.

Takhle dojdeme až k požadovanému počtu tlačítek a délce abecedy.



Je dobré si rozmyslet, že v tom postupu nemusíme zkoušet pro každou vybranou mezeru přidělovat mezery levé a pravé straně, stačí jít od začátku, za prvním písmenem buď mezera bude, nebo nebude.

Tím se dostáváme na něco jako O(t*n^3) s O(n^2) paměti, kde t je počet tlačítek, asi to půjde ještě vylepšit.


Doufám že to není moc zmatené, jestli si s dynamickým programováním moc nerozumíš, zkus nejdřív nějaké jednodušší příklady.



EDIT: Tak by to mělo být v O(t*n^2), kdyžtak si to zkusím ještě rozmyslet a poradím.

Offline

 

#6 04. 05. 2011 19:55

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

tak to jsem vubec nepochopil...mohl bzs mi to prosim ukazat na nejakem priklade?

Offline

 

#7 09. 05. 2011 23:56

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

diskutoval jsem to i se svym spoluzakem ale nijak na to nemuzeme prijit a ani on nepochopil tvuj algoritmus...jestli nekdo vite jak na to tak prosim napiste, dekuju moc

Offline

 

#8 10. 05. 2011 00:48 — Editoval OiBobik (13. 05. 2011 22:48)

OiBobik
Moderátor
Místo: Brno/Praha
Příspěvky: 1013
Škola: MFF UK Mat. struktury
Pozice: student
Reputace:   82 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:

Já možná jen zopakuju jinými slovy postup (případně popíšu obdobný), který popsal ↑ FailED::

Mějme k tlačítek a n písmen

Předvýpočet:

(četnost j-tého tlačítka budu značit w(j) )

Vytvoříme matici s políčky Cij - kde Cij bude cena, kterou nás bude stát vytvořit tlačítko, na kterém budou písmena i, i+1, ... j

Tedy Cij=1*w(i)+2*w(i+1)+3*w(i+2)...+(j-i+1)*w(j)
(když chci první písmeno z klávesy, musím ji zmáčknout jednou, když druhé, dvakrát, třetí třikrát... atd)

Hledání optimálního rozložení:

Budu vyplňovat další tabulku, a sice o rozměrech k x n - kde políčko Sij bude značit "optimální konfigurace i tlačítek taková, že i-té tlačítko končí na j-té klávese" (v políčku bude uložena vždy optimální cena)

První řádek (tedy políčka S1j pro j=1...n) lze zřejmě vyplnit for cyklem - je vždy jen jedna konfigurace, která se k tomu hodí, a ta odpovídá předvypočítaným číslům C1j pro j=1...n.
První políčko druhého řádku pro nás zřejmě nebudemít smysl (nemůžu použít dvě klávesy tak, aby druhá končila prvním písmenem).
Druhé políčko druhého řádku (S22) získám zřejmě tak, že vezmu S11 a přičtu k němu C22 (jinou možnost nemám - lze snadno rozmyslet)
Obecné políčko (tj. takové, kterým nezačíná řádek - rozuměj políčka tvaru Sii) Sij vyplním následovně:

někam si ukládej pomocnou proměnnou min; na začátku nechť je min=nekonečno (MaxInt apod)

(EDIT:chyba v řídící proměnné cyklu, opravena)

Pro m:=(i-1) do (j-1) dělej:

Vezmi S(i-1)m a přičti k němu C(m+1)j //// (oprava z m na m+1)
Je-li tato hodnota menší než min, pak min změn na tuto hodnotu

(konec cyklu)

Ulož min do Sij

(proč to funguje? při tvorbě optimální konfigurace takové, že i-té tlačítko končí j-tým písmenem, využijeme toho, že máme už spočítány optimální konfigurace pro rozložení (i-1) tlačítek tak, že (i-1)-té tlačítko končí písmenem (i-1), i, ... (j-1). K tomu máme spočteno, kolik nás bude ke každé této volbě stát "dodělat" potřebné tlačítko a minimum z těchto možností je optimálním řešením pro rozvržení, kde i-té tlačítko končí j-tým písmenem)

Takto postupně vyplníme celou tabulku. Protože nás zajímá optimum pro k tlačítek, kde k-té tlačítko končí n-tým písmenem, bude hledaná optimální cena rovna hodnotě Skn .

Pokud nás nezajímá jenom cena, ale i konkrétní rozložení, stačí jenom lehce upravit algoritmus - nebudu si pamatovat jenom dosavadní optimální cenu, ale zároveň s ní i políčko z předchozího řádku, kterého jsem pro výpočet tohoto optima využil. Pak stačí projít z Snk na políčko, které si pamatujeme u Snk, z toho políčka na políčko, které si pamatujeme tam atd až na nějaké políčko na prvním řádku. Tato políčka nám udávají, kterým písmenem bude která klávesa při optimálním rozložení končit.


"The first rule of Tautology Club is the first rule of Tautology Club." [xkcd]

Offline

 

#9 11. 05. 2011 19:52

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

dekuji moc, skvele to vysvetlujes a uz to chapu, ted si to vyzkousim naprogramovat:)

Offline

 

#10 12. 05. 2011 11:13

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

ahoj, tak jsem si myslel ze jsem to pochopil ale nejak mi to nevychazi...mohl bys mi to prosim ukazat na nejakem jednoduchem priklade?treba ze mame a-f a cetnosti jsou 3,4,8,1,7,4 a mame to dat na 3 tlacitka...diky moc

Offline

 

#11 12. 05. 2011 14:20 — Editoval OiBobik (12. 05. 2011 19:06)

OiBobik
Moderátor
Místo: Brno/Praha
Příspěvky: 1013
Škola: MFF UK Mat. struktury
Pozice: student
Reputace:   82 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:

OK.

Doufejme tedy, že tam nemám nějakou numerickou chybu (počítám to jen tak v ruce, nemám to napsané ten program):

Tabulka Sij, i=1,2,3, j=1...6:



(indexy vždy značí, kolikátým písmenem končí předchozí klávesa; nekonečno je na pozicích, které pro nás nemají smysl (tj. situace, kdy na i tlačítek dám méně než i písmen, nebo naopak, kdy dám na i tlačítek tolik písmen, že se mi už zbylá tlačítka nepodaří nikdy nijak zaplnit - nezbudou mi písmena) )

Tedy v tomto případě je nejmenší možná cena na zmáčknutí tlačítek 36 a splňuje je rozložení:

a b | c d | e f

(Když už jsem to tu tak vypisoval - když si to člověk opravdu takto vypíše ručně, zjistí, že je možné algoritmus trochu optimalizovat, aby nedělal tolik různých porovnání - všimni si, že indexy u optimálních rozložení v jednom řádku nikdy neklesají; když si to zkusíš ručně spočítat, bude ti i jasné, proč)


EDIT: opraveno dle upozornění ↑ Lumikodlak:


"The first rule of Tautology Club is the first rule of Tautology Club." [xkcd]

Offline

 

#12 12. 05. 2011 18:32

Lumikodlak
Místo: Praha
Příspěvky: 212
Pozice: Programator nebo tak neco :-)
Reputace:   19 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

Omlouvam se, ze do toho vstupuju, vsimnul jsem si, ze by melo podle me vyjit spis rozlozeni  a b | c d | e f ktere ma vahu 36, ale nechci do toho rypat :-)

Offline

 

#13 12. 05. 2011 18:46 — Editoval OiBobik (12. 05. 2011 19:07)

OiBobik
Moderátor
Místo: Brno/Praha
Příspěvky: 1013
Škola: MFF UK Mat. struktury
Pozice: student
Reputace:   82 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ Lumikodlak:

Děkuji, já to počítal na papíře, ale to koukám, že jsem hodně přestřelil : )) Asi bych si měl zopakovat sčítání.

/// už i vidím proč, prohodil jsem ceny dvou písmen (počítal jsem s cenami 3,4,8,7,1,4)

Jdu to opravit. Opraveno


"The first rule of Tautology Club is the first rule of Tautology Club." [xkcd]

Offline

 

#14 13. 05. 2011 17:01

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

prosimte promin, ale ja porad nechapu jak si prisel na tu tabulku...ty indexy a pak na tu 36..muzes se mi to prosim pokusit nejak vysvetlit?dekuju moc

Offline

 

#15 13. 05. 2011 20:31

OiBobik
Moderátor
Místo: Brno/Praha
Příspěvky: 1013
Škola: MFF UK Mat. struktury
Pozice: student
Reputace:   82 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:

Tak já rozeberu třeba to poslední políčko, to je takové demonstrativní.


Hledáme optimální rozložení a cenu pro 3. tlačítko tak, aby končilo 6. písmenem (tedy vyplňujeme S36), celý předchozí řádek máme vyplněný (známe tedy optimální rozložení a ceny pro 2 tlačítka, ať už končí, kterýmkoli písmenem, které má smysl)

Když to udělám neoptimalizovaně, tak to bude probíhat následovně:

Min:=nekonečno;

Podívám se na S21... tam vidím nekonečno, takže vím, že je to nepřístupné rozložení, tak jdu dál

Podívám se na S22... tam je cena 7
- S22 je rozložení, kdy druhá klávesa končí na druhém písmeně, tedy musel bych dodělat tlačítko s písmeny 3-6, to by odpovídalo předvypočítané ceně C36, spočítejme to ručně:
C36=1*8+2*1+3*7+4*4=47 , celková cena je tedy 7+47=54.... to je menší než min (nekonečno), takže do min:=54; (pamatuji si prozatím, že jsem min získal použitím pozice 2 předchozího řádku)

Podívám se na S23 ... tam je cena 19
analogicky bych musel dodělat tlačítko o ceně C46 = 1*1+2*7+3*4=27, celková cena by tedy byla 27+19=46; to je menší než min a tedy min:=46 (pamatujeme si 3)

Podívám se na S24 ... cena 21
Dodělat bych musel tlačítko o ceně C56 = 1*7+2*4=15, celkově by to tedy bylo za 21+15=36, tedy min:=36 (pamatuju si 4)

Podívám se na S25 ... cena je 42, když budu ten program mít chytře napsanej, tak to ani nedopočítává, protože míň jak min to nakonec být nemůže (42+něco kladnýho > 36)

Konec cyklu a já svoje vypočítané min uložím do políčka S36. pokud tam mám nějakou strukturu, kam napsat, kolikátým písmenem končí předchozí tlačítko, uložím tam 4.

Takto by to vyplňovalo každé políčko. na konci by si to přečetlo hodnotu v S36 a tu vypsalo, pak by si to (do pole nebo někam) ukládalo "to druhé číslo" u políčka S36, poté podle něj skočilo na políčko S24 a tam si přečetlo "to druhé číslo" a to taky uložilo - tedy máš teď v poli nějakou posloupnost 4,2, a nakonec to podle ní vypíše děliče mezi ta písmena (tj jeden na 2., druhej na 4. pozici).


"The first rule of Tautology Club is the first rule of Tautology Club." [xkcd]

Offline

 

#16 15. 05. 2011 19:57

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

Ahoj,

dekuju ti za radu, je hezky ze se mi snazite pomoct. Chapu tuhletu cast jak jsi naposled vysvetloval a chapu i vytvoreni te tabulky "C" ale rozhodne nechapu jak tvoris tabulku "S". Nemohl bys mi sem napsat kusy kodu jak vyplnujes tabulku "S" nebo to nejak vysvetlit pro ten priklad co se tu resi. Zkousel jsem si to napsat ale ztratim se na tom ze nevim odkud nakonec nektere hodnoty beres a jak je mozny ze ti vznikne ta hodnota co je zrovna v tabulce.

Predem dekuju ze nejake rady a reakce.

Offline

 

#17 15. 05. 2011 22:54 — Editoval OiBobik (15. 05. 2011 23:03)

OiBobik
Moderátor
Místo: Brno/Praha
Příspěvky: 1013
Škola: MFF UK Mat. struktury
Pozice: student
Reputace:   82 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:

Toto bylo vytvoření jednoho políčka z tabulky S, konkrétně tedy posledního, kde předpokládám, že mám všechny vyšší řádky vyplněné. Ty jsem vyplňoval obdobně s předpokladem, že řádky před nimi mám již vyplněné. Takto jsem to dělal od druhého řádku, přičemž první řádek jsem vyplnil for cyklem (viz výše)

ještě to zkusme graficky:



F... vyplněno for cyklem
V... vyplněno dříve v programu algoritmem
X... právě vyplňovaný prvek
U... políčka, na základě nichž se X vypočítává

Zkrátka dodělávám i-tou klávesu. Tak se podívám, jak za co nejmenší cenu rozmístit (i-1) kláves a kolik mě bude stát dodělat to i-té tlačítko (to se liší podle toho, kde bude končit ta (i-1)-tá klávesa - proto postupně procházíme všechna možná písmena, na která může ta (i-1)-tá klávesa končit, no a nakonec vezmeme nejmenší celkovou sumu - tedy nejmenší z hodnot (cena pro i-1 tlačítek)+(cena dodělání i-tého tlačítka))


"The first rule of Tautology Club is the first rule of Tautology Club." [xkcd]

Offline

 

#18 30. 05. 2011 15:23

hessyk
Příspěvky: 86
Reputace:   
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

tak mam tu tuhle ulohu:

Na 50 klavesách (čínskeho) mobilního telefonu ma být rozloženo 2000 znaků (písmen) v pevně danem pořadí (podle abecedy). Písmeno, které je na nejake klávese uvedeno jako k-te,
se zapíše k stisky této klávesy. Přitom víte, jak často se které písmeno používa
(třeba jako pravděpodobnost nebo jako počet výskytů písmene v průmerné zpráve).
Program ma určit, na které klávese budou která písmena,
aby k napsáni průmerné zprávy byl potřeba nejmenší možný počet stisků.

Na vstupu váš program dostane:
počet kláves
počet znaků, které je nutno rozdelit
seznam četností jednotlivých znaků v průměrné zpravě.

Na výstup program vypíše vážený součet všech četností znaků.

Příklad:
3 //počet kláves
5 //počet znaků
1 //četnost prvního znaku
1 //četnost druhého znaku
1 //četnost třetího znaku
1 //četnost čtvrtého znaku
1 //četnost páteho znaku

Výstup:
Jedno z rešení je rozložit znaky nasledovně:
1 2 | 3 4 | 5
Pro první klávesu vypadá vážený součet takto:
1*1 + 2*1 = 3
Pro druhú:
1*1 + 2*1 = 3
Pro třetí:
1*1 = 1
Celkový výstup je tedy: 3+3+1=7
Program na výstup vypíše číslo: 7


napsal jsem tenhle program:
Program mobil;
var
klavesy,znaky,min,i,konec,j,vysledek:longint;
cetnost,mezery,pomoc:array[0..3000] of longint;

Procedure start;
var i:longint;
Begin
     For i:=0 to znaky do
       BEGIN
        mezery[i]:=1;
        pomoc[i]:=0;
       END;
     pomoc[1]:=0;
     For i:=2 to znaky do
        Begin
             pomoc[i]:=cetnost[i]*2;
        end;
End;

Function minimum:longint;
var i,min:longint;
Begin
     min:=0;
     For i:=1 to znaky do
        If pomoc[i]>0 then
          Begin
             If min>1 then
                Begin;
                      If pomoc[i]<pomoc[min] then min:=i;
                End
             else min:=i;
          End;
     minimum:=min;
end;

Procedure prepocet;
var i,stupen:longint;
begin


For i:=2 to znaky do
        Begin
        If mezery[i-1]=1 then
                Begin
                stupen:=mezery[i-2]+1;
                pomoc[i]:=stupen*cetnost[i];
                j:=i;
                while mezery[j-1]<mezery[j] do
                        Begin
                        stupen:=stupen+1;
                        pomoc[i]:=pomoc[i]+stupen*cetnost[j+1];
                        j:=j+1;
                        end;
                End;
        End;
pomoc[1]:=0;
For i:=2 to znaky do
        If mezery[i-1]>1 then pomoc[i]:=0;
End;

Procedure vypis(pole:array of integer);
var i:longint;
Begin
     For i:=1 to znaky do
        write(pole[i],' ');
     writeln;
End;

Begin
readln(klavesy);
readln(znaky);
For i:=1 to znaky do
    readln(cetnost[i]);
cetnost[znaky+1]:=0;
start;
While znaky-klavesy>0 do
        Begin

        min:=minimum;
        If min>1 then mezery[min-1]:=mezery[min-2]+1 else mezery[min-1]:=2;
        j:=min;
        If min=znaky then konec:=0 else konec:=1;
        While konec=1 do
                Begin

                If mezery[j]>1 then mezery[j]:=mezery[j-1]+1 else konec:=0;
                if j=znaky then konec:=0;
                j:=j+1;
                End;
        prepocet;
        klavesy:=klavesy+1;

        End;
vysledek:=0;
For i:=1 to znaky do
        vysledek:=vysledek+cetnost[i]*mezery[i-1];
writeln(vysledek);
readln;
readln;
End.


porad mi to ale vypisuje spatnou odpoved muzete mi prosim nekdo tedy ukazat jak by mel vypadat spravny program nebo mi prepsat v tom mem programu chybu?nemuzu totiz na nic prijit...dekuju moc

Offline

 

#19 01. 06. 2011 10:27 — Editoval FailED (01. 06. 2011 10:30)

FailED
Příspěvky: 1255
Reputace:   42 
 

Re: rozlozeni abecedy na tlacitka mobilniho telefonu

↑ hessyk:

Tak jsem se k tomu taky dostal, paměť není moc omezená takže si můžu předpočítat ceny všech úseků a nechat si celou tabulku na dynamiku. Můžeš si rozmyslet jak by se to dalo upravit aby program používal jen lineárně mnoho paměti.


Tabulku vyplňuji tak, že postupně přidávám písmena, když přidám písmeno, zkusím všechny možné délky posledního úseku, rozdělení zbytku si přečtu z předchozího řádku (tam jsou ceny pro úseky s o jednu míň mezerami). - složitost je tedy v O(P^2*T) (Písmena, Tlačítka)

Můžeš se na to podívat, třeba pak najdeš chybu ve svém programu.



Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson