Diskuze: Machr na C# .NET - Nejrychlejší shuffle
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Vlastník

Zobrazeno 50 zpráv z 110.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Zkusil jsem si to jen tak nahrubo kolik by asi při normálním zpřeházení vyšel výsledek, ale na 20 intů to vrací počet tiků v rozmezí 100k - 200k, jak to chceš hodnotit když využití procesoru různě stoupá a kolísá?
Co přesně znamená, že původní prvky jsou zcela náhodně přeházené?
Výkonové testy se dělají na velkém množství náhodně generovaných dat. Když změříš seřazení milionu polí a ještě uděláš průměr z několika měření, je to přesné. Samozřejmě si musíš vypnout spuštěné aplikace a měřit to na stejném stroji.
Že to pole vypadá vždy jinak a je proházené po celé své délce. Můžeme tu filosofovat o tom, co to znamená náhodně a dojdeme k tomu, že náhodné není nikdy nic.
Ještě dodám že je nutné to pole uchovávat, tedy předgenerovat si je třeba do listu. Jinak VM udělá optimalizaci a tu metodu třeba ani nespustí, protože se její výsledek nepoužije.
Aha, tak to asi na mém stroji ne, to bych se těch milionů nedočkal radši budu trochu realista a
maximálně tak 10k
Omlouvám se, ale stále příliš nerozumím zadání.
Řekněme, že vstupem je pole a1, a2, ..., an.
Můj program vrátí pole b1, b2, ... bn.
Aby můj program vyhověl zadání "pole vypadá vždy jinak", musí platit a[i]!=b[i] pro nějaký index i. Je to tak?
Myslím, že pokud třeba v poli o 100 prvcích bude náhodou jeden prvek na stejném místě, tak se vůbec nic neděje, tohle bych nehlídal, jde asi hlavně o to, aby pořadí bylo po promíchání opravdu (pseudo)náhodné.
Tak nad tím teď přemýšlím a něco jsem vyplodil, nevím zda se pletu, ale to může být tak variabilní a dosáhnout různých výsledků?
Jetšě se chci zeptat, je nějáké minimum kolik ta metoda musí zvládnout? Protože jsem zkoušel 100M a vyhodilo mi to chybu "Out of memory"
Dal bych třeba nějaké pravidlo, třeba že o nové pozici každého prvku musí nějak rozhodnout metoda Next() třídy Random apod., aby byla u všech řešení ta náhodnost stejná.
100M mi prošlo vpohodě a doba kolem 5s
škoda že nemůžeme dělat v ASM, to bych se ho i naučil.
Asi mám málo operační paměti, nebo jsem zvolil špatný způsob, jinak mám 10M asi za 4 vteřiny
To by bylo fajn, nicméně ani příklad ze zadání toto nesplňuje.
Já bych to asi nechal, když si někdo udělá svůj random a bude fungovat,
tak je to jeho plus
To metoda přece neovlivňuje, do pole se vejde tolik, kolik máš paměti. Určitě budu dělat pole s tisíci, možná desetitisíci prvky. Delší ale asi ne.
Také nerozumím, o co vlastně jde...
Navrhnout vlastní náhodný generátor, který bude rychlejší než
Random?
Napsat algoritmus, který prohází pouze část pole (viz příklad v zadání
pro pole liché délky) a doufat, že bude o něco rychlejší než řešení
ostatních?
Procvičit se v psaní vícevláknových aplikací?
To je na Tobě jak to implementuješ. Rozhodující je čas.
Rozhodující by mělo být, aby program dělal přesně to, co má dělat. Pokud se neřekne, co to má dělat, není možné napsat program.
Pokud bych upravil podmínku v příkladu takto:
for (int i = 0; i < input.Length / 3; i++)
splnil bych zadání nebo ne?
Klidně nepoužívej žádný cyklus. Prostě máš náhodně uspořádat pole, aby v tom nebyla logika. ( = aby jsi logicky nemohl rozshufflovat to pole zpátky)
Zadání je aby to pole vypadalo náhodně přeházené. Představ si to třeba jako že mícháš karty. S mým algoritmem se teoreticky může stát že pole bude vypadat úplně stejně a je korektní. Jde o to, aby to ve většině případů fungovalo. Občas něco může zůstat kde to je, nemělo by se ale stát, že ti to bude ve většině případů shufflovat jen polovinu pole a druhá bude stejná. Nebo že tam bude nějaký hodně viditelný pattern.
Zajimavé, 5M mám skoro ihned (ani ne 1s), ale jakmile navrším data na
50M, tak to už je jiná písnička...
Jasně, ale kde je ta hranice mezi tím, co vypadá náhodně a co už ne? Co už je hodně viditelný pattern a co ne?
Statisticky by průměrně jeden prvek pole měl zůstat na svém původním místě. Někdy žádný, jindy třeba pět. Není to tak těžké udělat. Algoritmus, který použil David Hartinger, je úmyslně chybný.
prostě projeď všechno nebo vynechej jen vyjmečné, ne že vynecháš každý čtvrtý. Nijak se z toho nevymotávej.
V sdracově příkladu nevidím chybu, protože šplňuje to že se položky náhodně přehází.
To jo, ale 2× použít random není nejlepší, random.next je dost pomalá metoda
To jsem nevěděl, ale tak potom trochu pokulhávám v tom jak vygenerovat náhodný shuffle, protože bez Random to bude asi těžší
Zkus si jako výstup udělat obrázek třeba 1000×1000 bodů. Pokud budu považovat a[0], a[1], a[2], ... jako hodnoty na indexech 0, 1, 2, ..., tak si jako dvojice [x, y] nakresli bod na souřadnice
[a[0], a[1]]
[a[1], a[2]]
[a[2], a[3]]
atd.
Testuji na tom generátory náhodných čísel. Měla by vzniknout "hvězdná obloha". Pokud na ní budeš nacházet mohutné galaxie, je to špatně.
Random není zakázaný, ale jde to udělat i s jedním použitím random.next
Já tam tu chybu vidím a David Hartinger o ní zcela jistě ví a dal ji tam záměrně. Máme za úkol vymyslet algoritmus, který bude správný.
Je to opravdu chyba? Spíše to algoritmus omezuje v rychlosti. Alespoň podle toho co vidím já.
Teď jsem docílil 1,2s na 100M záznamech, ale problém je že se tam
objevil vzorec
To už je asi moc do detailů Neplánuji to takhle zkoumat. Budu asi jen porovnávat jak se to
liší od původního pole + nějaký test stejného pole a porovnání
výsledků mezi sebou.
Není zde zadáno to, kolik se z pole musí projet. Určil bych to alespoň na polovinu. Jinak je výsledek malo promychany. Zároveň si myslím, ze to bude spis soutěž o nejrychlejší random metodě, ale kdo ví. Třeba někdo vymyslí něco revolučního.
Pole projíždím vždy 1×. Mám tak jistotu, že pole je správně promícháno.
Jsem na 600ms(400 - 800) pro 100M, bez vzorce!
Jsou to milisekundy. Navíc závisí dost na tom, co mám spuštěné za procesy. Když zrovna oteviram photoshop, asi to bude vice + release mode oproti normálnímu spuštění bez VS
Při měření se snažím udržovat stálé podmínky, aby měření bylo co nejpřesnější. Nejhorší a nejlepší měření škrtám, zbytek průměruji nebo vyberu nejlepší.
Tu metodu jsem dal do zadání proto, abyste použili její hlavičku
Aha ty to mas bodobne, tak pocky, vymyslim neco jineho.
Jsem si nevsiml
Ono jde něco jiného? Já to mám taky podobné, jen jsem si udělal svůj
Random. Je to profláklý
algoritmus (Fisher-Yates shuffle), už od roku 1964 se nevymyslelo nic lepšího
Má to časovou
náročnost O(n). Co jiného by jsi chtěl?
Možná změnit pole na něco
jiného, ale pod tuhle časovou náročnost se myslím ani nedá dostat, pokud
chci manipulovat s celým polem. Tím, že projdu jen část, se samozřejmě
dostanu níže a můžu použít multi-threading, ale samotný algoritmus
zůstane z větší části nezměněný.
Zobrazeno 50 zpráv z 110.