Nizozemská vláda ve snaze šetřit a zvyšovat efektivitu s využitím umělé inteligence (AI) hodlá zrušit asi 25.000 pracovních míst ve státní správě. Cílem je postupně dosáhnout ročních úspor až 3,5 miliardy eur (85,2 miliardy Kč). Na konci loňského roku ve státní správě pracovalo rekordních 160.000 lidí. „Nemůžeme pokračovat v tom, co jsme dělali dosud,“ uvedl státní tajemník pro efektivní fungování vlády Eric van den Burg. „Proto
… více »Příspěvek na blogu PRUSA 3D představuje fotoaparát CAIM1 (Counter Artificial Intelligence Machine 1). Uměle vytvořený obsah je každým dnem těžší rozeznat od skutečných záběrů či fotografií, což podrývá důvěryhodnost žurnalistiky, archivních materiálů i každodenní tvorby obsahu. Fotoaparát CAIM1 byl vyvinut právě k tomu, aby ověřoval původ fotografií a videí přímo během jejich pořizování. Uvnitř fotoaparátu se nachází hardwarová Web3 peněženka se zabezpečovacím čipem Tropic Square TROPIC01.
Jonathan Thomas oznámil vydání nové verze 4.1 video editoru OpenShot (Wikipedie). Zdrojové kódy OpenShotu jsou k dispozici na GitHubu. Ke stažení je i balíček ve formátu AppImage. Stačí jej stáhnout, nastavit právo na spouštění a spustit.
Při běžné migraci virtuálního stroje mezi hypervizory se jeho MAC adresa přesune na jiný leaf switch. EVPN tuto změnu distribuuje pomocí BGP Type-2 route a MAC mobility sequence number. Problém nastává, pokud útočník podvrhne zdrojovou MAC adresu jiného zařízení. Leaf může změnu interpretovat jako legitimní přesun MAC a rozšířit ji přes BGP do celé fabric. Výsledkem může být přesměrování provozu určeného původnímu zařízení. Autor článku rozebírá možnosti detekce pomocí sledování MAC moves, BGP route reflektorů a kontroly na přístupové vrstvě.
Vývojáři desktopového prostředí Enlightenment (Wikipedie) a souvisejících knihoven Enlightenment Foundation Libraries (EFL) vydali nové verze. Enlightenment byl vydán ve verzi 0.28.0 a Enlightenment Foundation Libraries ve verzi 1.29.
Cloudflare zjistil, že některé odpovědi modelu GLM-5.3 obsahovaly části dat z předchozích požadavků jiných zákazníků. Příčinou byla kombinace chybné konfigurace a chyby v inference enginu SGLang. Model podporoval kontextové okno 1 048 576 tokenů, ale GPU KV cache pool měl kapacitu pouze 681 280 tokenů. Při překročení kapacity docházelo k nesprávnému zpracování odmítnutého požadavku. Decode část systému následně pracovala se starými
… více »Vývojáři Knot Resolver vysvětlují, jak změnili rozhodování o tom, které DNS záznamy ponechat v cache a které odstranit. Článek obsahuje skutečná měření: devět hodin DNS provozu při 2 000 QPS, srovnání cache o velikosti 25 MB a 40 GB a také porovnání s BIND 9, kromě algoritmů obsahuje konkrétní doporučení pro konfiguraci a diagnostiku.
Největší kryptoměnová burza světa Binance se stala terčem útoku, při kterém podvodníci odcizili během několika minut kryptoměny v hodnotě přibližně 6,3 miliardy dolarů. Jedná se o největší kryptoměnovou krádež v historii, přibližně čtyřikrát větší než loňský útok na burzu Bybit. Binance se podařilo ve spolupráci s partnery zmrazit aspoň aktiva v hodnotě zhruba 3 miliard dolarů a slíbila, že veškeré ztráty pokryje z vlastních prostředků.
Zranitelnost CVE-2026-98432 s CVSS 9.8 odhalila AI od společnosti Anthropic. Jedná se o kritickou chybu v implementaci MPTCP (multipath TCP). Debian vydal patche 16.10. a 22.10., ale např. Ubuntu je zatím bez opravy. Více informací na The Hacker News.
Na Slovensku vznikla úplne nová rally hra, ktorá je zadarmo a funguje vo Windowse, Linuxe či na Macu. Greenie Rally má viac ako 50 tratí a vozidiel, šampionáty či turnaje. Má retro feeling a imituje automobilové hry z prelomu tisícročí. Vyskúšate prejsť všetky mapy na Škode 130RS?
Tak už jsem dlouho nenapsal žádný blog, tak jsem se rozhodl, že spojím užitečné se zábavou. Takže jelikož jsem v poslední době byl někým žádán abych mu poskytl svůj program pro názorný výpočet determinantu (Python a PyQt vše je v dokumentaci), tak ho vložím i sem. Třeba se to taky někomu bude hodit. Dál se pokusím najít Salxeso (pexeso psané v Javě, samozřejmě psané jako semestrálka, takže to není žádný zázrak) do kterého mi tady někdo taky dělal hrací karty.
A teď se konečně dostáváme k věcem, na které jsem se zdejších odborníků chtěl zeptat, zda jsou vůbec proveditelné. Takže dostali jsme za úkol na C/C++ abychom napsali spojoví seznam. Na tom není nic těžkého podmínky byly jasně stanoveny, aby byl jednosměrný a aby obsahoval určité metody a to konkrétně: head(), first(), last(), isEmpty(), popFront(), pushFront(SItem), pushBack(SItem), insertAfter(SHandle *, SItem), concat(SList *), makeEmpty,moveAfter(SHandle *,SHandle *), moveToFront(SHandle *), moveToBack(SHandle *), remove(SHandle *). Na tom by nebylo nic složitého, ale máme další podmínku a to aby tyto metody měli konstantní časovou složitost, ale zde již narážím. Skoro všechny metody lze udělat s konstantní časovou složitostí ale pouze s dvousměrným seznamem (alespoň se tak domnívám). Konkrétně mi jde o tyto metody: insertAfter(SHandle *, SItem), makeEmpty, moveAfter(SHandle *,SHandle *), moveToFront(SHandle *), moveToBack(SHandle *), remove(SHandle *). U těchto metod totiž potřebujeme vědět předchůdce objektu (prvku) a jedinou možností, která mě napadá je si celý seznam projít a nalézt hledaného předchůdce, tudíž se dostáváme na časovou složitost algoritmu O(n). Navíc třeba metoda makeEmpty, která má celý spojoví seznam zahodit nelze v C++ realizovat, pokud používáme dynamické přidělování paměti, protože by nám objekty zůstali vyset v paměti, ale nevím jestli se i tohle počítá do časové složitosti toho algoritmu, ale řekl bych, že ano.
Tak co jaký názor na to mát? Myslíte si někdo, že to půjde, nebo je to pouze špatně zadané? Nebo jsem úplný blbec (to jsem
)?
Tiskni
Sdílej:
IMHO se ty operace dají udělat i s jednosměrně zřetězeným seznamem v konstantním čase, jenom to neni zrovna obvyklé řešení (to s "přesměrovánim" ukazatelů).
Operaci vyjmout prvek lze totiž udělat i tak, že si zapamatuješ "obsah" prvku a ten nahradíš "obsahem" jeho následníka (včetně ukazatele na následující prvek).
tak by to šlo.
, protože tam mám ukazatele na ty prvky, takže je stačí jenom prohodit a nemusím nic kopírovat. Takže dík.
2) Nepůjde smazat poslední prvek. I kdyby typ datové položky měl nějakou speciální "prázdnou" hodnotu, nebude jak správně aktualizovat ukazatel na konec seznamu, který je potřeba pro jiné operace.
Místo ukazatele na poslední prvek seznamu můžeš udržovat ukazatel na předposlední prvek.
.
?! Ukazatel na předposlední prvek si právě budeš pamatovat. A jestli si myslel "poslední" místo "předposlední", tak k tomu se z předposledního lehce dostaneš v konstantnim čase...
Máš pravdu, teorie s předposlednim prvkem je blbost. Nicméně by to mělo jít udělat přes "fixní" poslední prvek seznamu. Tzn. poslední prvek seznamu by byl "speciální" prvek, který by se nikdy nemazal.
Myslim to tak, že ten poslední prvek nebude navenek součástí seznamu. Seznam prostě pro N "uživatelskejch" prvků bude mít interně N + 1 prvků.
.
insertAfter(SHandle *, SItem), makeEmpty, moveAfter(SHandle *,SHandle *), moveToFront(SHandle *), moveToBack(SHandle *), remove(SHandle *). U těchto metod totiž potřebujeme vědět předchůdce objektu (prvku)Předpokládám, že předchůdce je právě ten první parametr. Čili hledat ho nepotřebuješ:
insertAfter(SHandle *item, SItem) {item->next = /*novej prvek*/;}moveToFront je jednoduché.remove konstatně moc nejde, leda že bys hodnotu následujícího překopíroval do toho k odebrání, napojil ten následující za následujícím a uvolnil následující.moveToBack a moveAfter imho konstatně nepůjdou.makeEmpty nevím co znamená, ale jestli to zahrnuje uvolňování paměti všech, konstatní složitost to určitě mít nebude...
moveToFront vlastně jednoduché není, ledaže bys zase přehazoval hodnoty, což by se týkalo všech move* a pak by to bylo konstatní.
že se ten další prvek nakopíruje na místo prvku, který chci přesunout.Jj, tak jsem to myslel. Dalo by se to udělat tak, že bys ty hodnoty do toho seznamu nevkládal přímo, ale přes pointer - "kopírování" by pak bylo jednoduchý. Ono s nějakým nasazením třeba templatů nebo něčeho by to v podstatě takhle dopadlo tak jako tak...
takže jsem to měl už připravené jenom jsem to upravil
.
Taky to jde, když pro seznam použiješ jeden "buffer" (kterej budeš třeba exponenciálně zvětšovat) a nebudeš alokovat paměť pro každý prvek zvlášť.
Správnou odpověď ti dá asi jenom zadavatel, tedy cvičící. Já bych to tipoval, že operace smazat seznam konstantní bejt nemusí, jenom to neni v zadání explicitně napsaný. V nejhoršim případě můžeš prostě jenom "vynulovat" ukazatel na začátek seznamu a argumentovat tim, že o uvolňování paměti se v zadání nic nepíše
.
.
a nebo si ten Garbage collector můžeš implementovat sám. Udělat ještě jeden seznam prvky alokované, ale jinak úplně na h*vn*, v případě že budeš chtít alokovat, tak můžeš mrknout do toho druhého seznamu a prvky už alokované jen znova přidělíš a ještě si do toho napíšeš nějakou čistící rutinu, která po nějaké časové periodě mrkne do toho druhého seznamu a pokud v něm bude nějaký prvek, tak ho podle pointerů projede a celý uvolní. U procedur z vnějšího rozhraní dodržíš zadání a jak se to dělá uvnitř už nikoho nemusí zajímat.
Ale to makeEmpty konstantně nejdeJde, ale ne standardní alokaci paměti. Je třeba použít jiný typ alokace, tj. buď si jí dělat osobně (např. přes
mmap()), nebo použít nějaký hiearchický alokator, jako třeba obstack nebo talloc. Když pak chcete zahodit celý seznam, tak stačí jen zrušit kontajner, ve kterém jsou jednolivé objekty alokovány.
mmap() má konstantní časovou složitost, což (1) Vám nikdo neslibuje, (2) není pravda.
mmap()uje /dev/zero, což je metoda, jakou používají používají i standardní knihovny (vedle brk()/sbrk()). Za optimálních podmínek je odmapování otázka jediného volání jádra, takže v praxi nemá uživatelský program stejně žádnou rychlejší metodu, jak navrátit paměť operačnímu systému.
V moderních OS je dokonce možné ještě dále snížit režii jádra použitím stránek větších než 4KB (běžně 1MB, u nejnovějších procesorů až 1GB), což má i kladný vliv na rychlost přístupu k této paměti (lepší využitím TBL cache). V ultimativním případě se dá celá komplikovaná struktura uvolnit v čase velmi blízkém O(1), tedy pokud se do takovéto olbřímí stránky vejde celá.
Bohužel opravdu konstantí časová složitost opravdu zajistit nejde, ale dá se jí dost přiblížit zamknutím stránek v paměti a naplánování se jako realtime proces. Jenže pravé realtimové procesy stejně většinou nepoužívají klasickou dynamickou alokaci, buď mají všechny struktury statické, nebo přidělují bloky pevné velikosti.
mmap() zdaleka nezávisí jenom na stránkách, ale (zrovna v případě Linuxu, jiné systémy na tom jsou podobně) i na režii VMA-listů, které mají logaritmickou složitost vzhledem k počtu prvků – jsou to ve skutečnosti vyhledávací stromy, protože je potřeba umět pro nový blok paměti najít volné místo v adresním prostoru. Zamykání stránek od toho nepomůže.
Implementujte třídy SHandle, SItem a SList, reprezentující prvky jednosměrně zřetězeného seznamu. SList - samotný spojový seznam, SHandle - ukazatel na SItem, SItem - prvek seznamu Implementujte operace pro SList head(), first(), last(), isEmpty(), popFront(), pushFront(SItem), pushBack(SItem), insertAfter(SHandle *, SItem), concat(SList *), makeEmpty,moveAfter(SHandle *,SHandle *), moveToFront(SHandle *), moveToBack(SHandle *), remove(SHandle *) s konstantní složitostí a findNext(SItem *, SHandle *) se složitostí O(n).
found=false;
for (c=str;*c; c++)
if (*c=='a')
{
found=true;
}
for (c=str;*c;c++)
if (*c=='a')
{
found=true;
break;
}
printf("found %d\n",found);
if next == end free (end); end = this; end;to ti zaruci, ze spojak stale ukazuje spravne.
def remove (link)
if link.next == List.last
data = link.data
List.last = link
else
#normalni remove
end
return data
end
To přece není až tak složité. Trik je v rozdílu mezi SHandle a SItem.
SHandle je datová struktura pro uživatele transparentní; je to nějaký pointer do seznamu, s nímž uživatel nebude nic provádět, jen ho může podstrčit tomu API. (Tedy obdoba C++ iterátoru.) Takové věci se většinou ve veřejných headerech nechávají jako incomplete type, aby se je nikdo nesnažil nějak „instanciovat“ nebo kopírovat. (Ale to není podstatné.)
No a když mám přímo pointer na prvek toho seznamu, je implementace insertAfter(SHandle *, SItem) v O(1) triviální.
Pro jednoduchost (a odstranění zbytečných ifů) je dobré mít v seznamu vždy alespoň jeden prvek, tedy jakousi hlavu, která v případě prázdného seznamu bude ukazovat sama na sebe. Implementaci to výrazně zjednoduší. A co je ještě důležitější — umožní to navíc implementaci insertBefore(SHandle *, SItem) v O(1). Struktura SHandle jednoduše nebude ukazovat přímo na referencovaný prvek seznamu, ale na jeho předchůdce. Implementace insertBefore() i insertAfter() v O(1) je pak snadná.
Ještě jednou základní pointa:
insertAfter(SItem where, SItem newItem) lze u seznamu provést pouze v O(n).insertAfter(SHandle * where, SItem newItem) lze provést v O(1).insertBefore() platí totéž.Zapomněl jsem to explicitně napsat, ale požadované moveAfter(), moveBefore(), moveToBack() či moveToFront() se vyřeší obdobným způsobem. Když potřebuješ znát předchůce, ukazuj prostě pomocí SHandle * na předchůce a ne přímo na referencovaný prvek.