Archivy řešení problémů – Garáž

Abstrakt (ruština):
V roce 1935 byla v Jaroslavli postavena garážová budova v postkonstruktivistickém stylu podle projektu I. N. Dubova, absolventa leningradského VKHUTEINU. Rysy architektonického a plánovacího řešení jsou analyzovány v kontextu ekonomických předpokladů pro vzhled tohoto typu budovy ve struktuře města, vlivu evropských a domácích představ avantgardních tvůrců, jakož i direktiv čas na vývoj kreativního konceptu. Úkolem bylo hledat objektivní důkazy o historické a kulturní hodnotě objektu s cílem zachovat unikátní typologický příklad ilustrující programové a stylové etapy vývoje nového typu stavby v SSSR. Jsou uvedeny nové informace o historii architektury sovětské éry a díle architekta I. N. Dubova.
Klíčová slova:
architektura, typologický, vzorek, projekt, budova, automobil, garáž, postkonstruktivismus, Jaroslavl, I. N. Dubov
2. Saprykina N.S. Sovětská architektura Jaroslavle. Yaroslavl: YAGTU Publishing House, 2006. 496 s.
3. Ikonnikov A.V. Architektura 2. století. Utopie a realita: ve 2001 svazcích M.: Tradice pokroku, 2002-1. T. 2001. 656. 2 s., T. 2002. 672. XNUMX s.
4. Konstantin Stepanovič Melnikov: Architektura mého života. Kreativní koncept. Tvůrčí praxe / Komp. A.A. Strigalev a I.V. Kokkinaki. M.: Umění, 1985. 311 s.
5. Khan-Magomedov S.O. Architektura sovětské avantgardy. Ve 2 knihách. Rezervovat 1. Problémy tvarování: mistři a trendy. M.: Stroyizdat, 1996. 709 s.
6. Khan-Magomedov S.O. Konstantin Melnikov. M.: Architecture-S, 2007. 296 s. (Masters of Architecture).
7. Garážové příběhy. Prostor auta je jako architektonické mistrovské dílo. Bachmetevsky garáž // Kommersant. URL: https://www.kommersant.ru/doc/3637878#id1599294
8. Garážové příběhy. Prostor auta je jako architektonické mistrovské dílo. Bachmetěvskij garáž (plán) // Kommersant. URL: https://www.kommersant.ru/doc/3637878#id1599295
9. Garážové příběhy. Prostor auta je jako architektonické mistrovské dílo. Nákladní garáž MKH // Kommersant. URL: https://www.kommersant.ru/doc/3637878#id1599301
10. Garážové příběhy. Prostor auta je jako architektonické mistrovské dílo. Nákladní garáž MKH (plán) // Kommersant. URL: https://www.kommersant.ru/doc/3637878#id1600521
11. Garážové příběhy. Prostor auta je jako architektonické mistrovské dílo. Garáž Gosplan // Kommersant. URL: https://www.kommersant.ru/doc/3637878#id1599310
12. Garážové příběhy. Prostor auta je jako architektonické mistrovské dílo. Garáž “Intourist” // Kommersant. URL: https://www.kommersant.ru/doc/3637878#id1599314
13. Evgeny Chesnokov (2018) “Město pro paměť.” 360. Suščevskij Val. 31. října 2017. Fotografický projekt „Město v paměti“. 360. Suščevskij Val. URL: https://rblogger.ru/2018/12/22/gorod-na-pamyat-360-sushhyovskiy-val/
14. Selivanová A.N. Postkonstruktivismus. Moc a architektura ve 1930. letech 2019. století v SSSR. M.: BooksMART, 320. XNUMX s.
15. Ze sbírek Harvard Art Museum Factory. Výstava Deutscher Werkbund (Německé sdružení řemeslníků) 1914, Kolín nad Rýnem | Walter Gropius a Adolf Meyer. URL: https://harvardartmuseums.org/art/219402
16. Archivní soubory závodu SK-1 (nákresy, vysvětlivky) // Osobní archiv S. I. Taraeva
17. Goffman V.L. Tovární architektura. Část 1. Plánování a projektování budov a staveb průmyslových podniků. 3. vyd. L.: KUBUCH, 1932. 580 s.
18. Doporučení pro návrh parkovišť, garáží a garážových komplexů. Historie regulačních dokumentů pro projektování garáží // Projekty investiční výstavby. Design garáže. URL: https://www.project.bulgaria-burgas.ru/project-garage_advice.htm
20. Carskoye Selo Imperial Garage // Parky Carskoye Selo a okolní oblasti. Průvodce. 38. URL: http://xn—-7sbb4bxah.xn--p1ai/38-Tsarskiy_garag_Pushkin.html#! prettyPhoto[pp_gal]/4/
21. Mitková T.N. Prvorozený SK. Z historie závodu na výrobu syntetického kaučuku v Jaroslavli. Jaroslavl: Verkh.-Volzh. rezervovat nakladatelství, 1965. 120 s.
22. Ryazantsev N.P., Salova Yu.G. Historie Jaroslavlska (1930–2005): Učebnice pro středoškoláky. učebnice provozoven. Yaroslavl, Rybinsk: OJSC “Rybinsk Printing House”, 2005. 277 s.

Garáž Náš výkres ukazuje plán garáže pro auto s místem pro dvanáct aut. Ale prostory jsou tak nepohodlné, tak malé, že vedoucí garáže má neustále potíže. Tady je jeden z nich. Předpokládejme, že cena osmi vozů je znázorněna na obr. 3. Vozy 1,2, 3, 4 a 5 je třeba zaměnit za vozy 6, 7, 8 a 7.2.3. Jak to lze provést na co nejmenší počet tahů? Je třeba poznamenat, že dvě auta se nemohou pohybovat současně a že do každého garážového prostoru se vejde pouze jedno auto. Řešení musí být předloženo SWI-Prolog XNUMX. Pokusil jsem se problém vyřešit na základě vašeho řešení problému žárlivých manželů.
/*nodes (garážové boxy)*/ node(0). uzel(1). uzel(2). uzel(3). uzel(4). uzel(5). uzel(6). uzel(7). uzel(8). uzel(9). uzel(10). uzel(11). /* hrany (průchody mezi boxy) */ edge(0,1). hrana(1,0). okraj (1,2). hrana(2,1). okraj (1,4). okraj (4,1). okraj (2,3). okraj (3,2). hrana (4,5). okraj (5,4). hrana (5,6). hrana (6,5). hrana (5,7). hrana (7,5). hrana (7,9). hrana (9,7). hrana (8,9). hrana (9,8). okraj (9,10). okraj (10,9). hrana(10,11). hrana(11,10). /* první hledání hloubky (kontroluje, zda existuje cesta mezi vrcholy) */ dfs(A, B, _, [(A, B)], State):- edge(A, B),nth0(B,State, Bod ), Bod == 0. dfs(A, B, VN, [(A, X)|TR], Stav):- hrana(A, X),nth0(X,Stav, Bod), Bod == 0 , not(member(X, VN)), dfs(X, B, [A|VN], TR, State). swapCar(As,I,J,Cs):- stejná_délka(As,Cs), připojit(PředI,[AtI|PastI],Jak), připojit(Před,[AtJ|PastI],Bs), připojit(PředJ,[ AtJ|PastJ],Bs), připojit(PředJ,[AtI|MinulostJ],Cs), délka(PředI,I), délka(PředJ,J). checkPath(State,From,To):- dfs(From,To,[],Cesta,Stat), délka (cesta,Velikost),Velikost>0. createMoves(X,Y):- uzel(X), uzel(Y), X == Y. checkStartIsCar(State,Position):- nth0(Position,State,Car),Car == 0. checkEndIsEmpty(State,Position) ):- nth0(Pozice,Stav,Spot), Spot == 0. moveCar(PreviousState,NewState):- generujPohyby(Od,Do), zkontrolujStartIsAuto(Předchozí stav,Od), zkontrolujKonecPrázdný(Předchozí stav,Do), zkontroluj cestu (Předchozí stav,Od,Do), vyměň auto (Předchozí stav,Od,Do,Nový stav). /* V ideálním případě by zde měla být kontrola, kdy bychom měli ukončit rekurzi vyhledávání do hloubky (z nějakého důvodu to nefunguje), mělo by skončit, když aktuální stav = konečný. */ vyřešit([Hlava|Ocas],[Hlava|Ocas],_,_):-!. vyřešit(A,Konec, VN, [A|TR]):- posunoutAuto(A, X), ne(člen(X, VN)), vyřešit(X,Konec, [A|VN], TR).
Má to fungovat takto:
Počáteční a konečný stav garáže se zadává do predikátu solve, který musí postavit stavový strom a procházet jej za běhu. Nový stav je generován predikátem moveCar. Vygenerují se všechny permutace od 0 do 11 délky 2 – odsud a do tohoto auta přejíždíme a kontroluje se možnost takového přechodu z aktuálního stavu. Možná mi někde chybí cutoff, nebo jsem nějak špatně zorganizoval výstup z rekurze predikátu solve (chtěl jsem to udělat tak, že když náš aktuální vrchol (stav garáže), ve kterém už jsme poslední, pak odejít.
22.03.2016 ve 03:43 #2640
Obecně platí, že nejprve musíte popsat graf. Udělali jste to, ale z nějakého důvodu jste se místo písmen (jako na obrázku) rozhodli použít čísla. To ztěžuje ověření. Vidím, že máte popsaný graf, ale nerozumím tomu, kde jsou popsány vaše stroje (aktuální stav). Počáteční stav bych popsal jako seznam, který je v každém kroku předán funkci řešit. Počáteční graf je takový:
Graf = [node(a, 5), node(b, 6), node(c, 7), node(d, 8), node(i, 1), node(j, 2), node(k, 3 ), uzel(l, 4)].
S tímto přístupem si myslím, že byste neměli mít problémy s ukončením rekurze, protože Koncová podmínka by vypadala asi takto:
řešit([uzel(a, 1), uzel(b, 2), uzel(c, 3), uzel(d, 4), uzel(i, 5), uzel(j, 6), uzel(k, 7 ), uzel(l, 8)]):-!. A kromě toho se zdá, že máte správný přístup – musíte spustit prohledávání do šířky – v každém kroku vzít první stav z fronty, vygenerovat z něj nové stavy a přidat je na konec fronty.
22.03.2016 ve 08:04 #2641
Jako stav (aktuální a konečný, jednoduše používám pole [1,2,3,4,0,0,0,0,5,6,7,8] , kde index prvku je box (0-A, 11- L) a číslo na této pozici je auto v krabici, nebo 0, pokud je krabice prázdná, prakticky dojdu ke stejnému řešení, vizuálně to funguje stejně – prostě trvá to velmi dlouho a nejsem si jistý, zda to fungovalo. Existuje nějaký jiný způsob, jak odstranit zbytečné možnosti, nebo je to nejoptimálnější řešení?
22.03.2016 ve 12:52 #2642
Vlastně nerozumím vašemu algoritmu. Popište prosím, co každá funkce dělá. Nechápu, proč potřebujete generovat permutace. Snažil jsem se například přijít na to, že když váš program přesune auto 6 z buňky b do buňky f, pokusí se jej v dalším kroku přesunout zpět do buňky b? Pokud to váš program dělá, lze to opravit a může se objevit efekt. Například v určitém kroku může přesunout 4 auta, což znamená, že ve stromu hledání řešení na další úrovni budou 4 uzly, ale pokud je může také přesunout zpět, pak 8 uzlů. Pokud pak má váš strom např. 10 vrstev (problém je vyřešen v 10 tazích), pak program vyplýtvá 4^10 možností, což je hodně. Ale opakuji znovu, nerozuměl jsem vašemu kódu. Už jsem vás požádal, abyste to podrobně popsal. Zdá se mi, že komentáře ve vašem kódu jsou jen matoucí. Vaše funkce dfs tedy nekontroluje přítomnost cesty mezi vrcholy (nebo nejen to). Nechápu, proč máte všechny oblouky výslovně zaznamenané v databázi – popsat by se dala jen polovina, druhá část by se dala získat takto:
check_edge(A, B):- edge(A, B), !; hrana (B, A).
Připadá mi nepohodlné ladit program pomocí vašeho stavového pole. Čísla políček místo písmen (jako na obrázku) působí ještě více rušivě. Nechápu, proč a proč swapCar provádí připojení 4krát a co by měl dělat. Pokud jde o mě, abyste mohli přesunout auto X z boxu A do boxu B, musíte udělat něco takového:
select(node(A, X), State, StatePart), !, NextState = [node(B, X)|StatePart].
A určitě to bude fungovat rychleji než váš kód. Vůbec nechápu, co dělá funkce createMoves. Jen nerozumím tomu, proč potřebujeme generovat všechny možné dvojice vrcholů (stále se můžeme pohybovat pouze po úsecích grafu, kterých je mnohem méně), ačkoli se vaše funkce moveCar pokouší hýbat všemi auty náhodně – bez toho, aby brala v úvahu zohlednit oblouky grafu (pokud jsem to správně pochopil). Možná se pletu. Chci pomoci, ale nerozumím kódu. Žádám vás, abyste popsal, jak to z vašeho pohledu funguje (každá funkce).
22.03.2016 ve 15:13 #2643
Ahoj ještě jednou. Nyní program vypadá takto
:- dynamické stavy/2. /*nodes (garážové boxy)*/ node(0). uzel(1). uzel(2). uzel(3). uzel(4). uzel(5). uzel(6). uzel(7). uzel(8). uzel(9). uzel(10). uzel(11). /* hrany (průchody mezi boxy) */ edge(0,1). hrana(1,0). okraj (1,2). hrana(2,1). okraj (1,4). hrana (4,1). okraj (2,3). okraj (3,2). okraj (4,5). hrana (5,4). hrana (5,6). hrana (6,5). hrana (5,7). hrana (7,5). hrana (7,9). hrana (9,7). hrana (8,9). hrana (9,8). okraj (9,10). okraj (10,9). hrana(10,11). hrana(11,10). /* první hledání hloubky (kontroluje, zda existuje cesta mezi vrcholy) */ dfs(A, B, _, [(A, B)], State):- edge(A, B),nth0(B,State, Spot ), Spot == 0. dfs(A, B, VN, [(A, X)|TR], State):- hrana(A, X),nth0(X,State,Spot),Spot == 0 , not(member(X, VN)), dfs(X, B, [A|VN], TR, State). swapCar(As,I,J,Cs) :- stejná_délka(As,Cs), připojit (PředI,[AtI|PastI],Jak), připojit(Před,[AtJ|PastI],Bs), připojit(PředJ,[ AtJ|PastJ],Bs), připojit(PředJ,[AtI|MinulostJ],Cs), délka(PředI,I), délka(PředJ,J). checkPath(Stav,Od,Do):-dfs(Od,Do,[],Cesta,Stav),délka (Cesta,Velikost),Velikost>0. createMoves(X,Y):- uzel(X), uzel(Y), X == Y. checkStartIsCar(State,Position) :- nth0(Position,State,Car),Car == 0. checkEndIsEmpty(State,Position) ) :- nth0(Pozice,Stav,Spot), Spot == 0. moveCar(PreviousState):- generujPohyby(Od,Do),zkontrolujStartIsAuto(PředchozíStat,Od), zkontrolujKonecPrázdný(PředchozíStat,Do),Zkontroluj cestu (Předchozí stav,Od,Do), vyměnitCar (Předchozí stav,Od,Do,Nový stav), +(stavy(_, Nový stav)) , tvrdit (stavy (předchozí stav, nový stav)), selhat;!. cesta(Dokončit, [[Dokončit | Část cesty] | _], [Dokončit | Část cesty]):-!. cesta(Dokončit, [[X | Část cesty] | ProcList], Cesta):- moveCar(X), findall(Y, step(X, PathPart, Y), AdjNodes), append(ProcList, AdjNodes, NewProcList), !, cesta (Finish, NewProcList, Path). krok(X,T,[Y,X|T]):- stavy(X,Y), ne(člen(Y,T)). cesta(Start, Dokončit):- cesta(Dokončit, [[Start]], RPath), !, obrátit (RPath,Cesta), napsat (Cesta).
V současné době se k nalezení řešení používá vyhledávání do šířky. Nyní k funkcím.
Funkce DFS hledá cestu podél prázdných buněk od políčka k políčku a kontroluje, že po cestě procházíme pouze prázdnými políčky (zaškrtněte 0)
Funkce SwapCar přeskupí prvky s danými indexy ve stavovém poli, aby získal nový stav.
GenerateMoves se používá k vytváření všech druhů permutací, které jsou následně eliminovány kontrolami CheckStartIsCar, dfs, CheckEndIsEmpty.
CheckStartIsCar zkontroluje, že místo, odkud se budeme pohybovat, je obsazeno autem.
CheckEndIsEmpty zkontroluje, že bod, KDE se pohybujeme autem, je prázdný. Pohybujeme se tedy pouze po dříve určených hranách. Do moveCar bylo přidáno také přidávání nových stavů
not(states(_, NewState)), Claim(states(PreviousState, NewState)), selhání;!
protože používáme nejprve vyhledávání na šířku. Jak to chápu, všechno by mělo fungovat. Začínáme z cesty (počáteční pozice, požadovaná pozice)
Náš moveCar bude generovat všechny PLATNÉ pohyby (ve skutečnosti to dělá, zaškrtl jsem) z tohoto stavu. To znamená, že při prvním tahu můžeme provést 8 různých platných pohybů. Okraje grafu stavů se vytvoří, pokud k určitým stavům ještě nevede žádná cesta.
Pak následuje standardní prohledávání do šířky s dokončením grafu. Pokud to pro vás není obtížné, rád se podívám na vaše řešení.
25.03.2016 ve 09:32 #2650
V praxi můj algoritmus dokonce funguje.
Pokud zadáme jako vstup méně složitý požadavek (například situace, kdy k dosažení výsledku potřebujeme pouze 8 permutací), pak po 30 sekundách utrpení. vytvoří seznam přechodů.
30.03.2016 ve 18:54 #2662
Myslím, že máte velmi dobré řešení, moje verze nedává stejný výsledek (předtím jsem zkoušel hloubkové vyhledávání, výsledek byl podobný). Odebral jsem 4 oblouky a místo nich přidal dva nové (jak jsem psal výše), ale nepomohlo to.
hrana (a, b). hrana (b, c). hrana (c, d). %edge(b, e). %edge(e, f). hrana (f, e). %edge(f, h). %edge(h, j). hrana (j, i). hrana (j, k). hrana (k, l). hrana (b, f). hrana (j, f). merge_list([], []):-!. merge_list([HeadA|TailA], B):- select(HeadA, B, TailB), !, merge_list(CailA, TailB). existovat_hrana(Od, Do):- hrana(Od, Do); hrana (Do, Od). proliferate(FromState, [(CarId, CarCellTo)|FromTailState]):- select(Auto, FromState, From TailState), Car = (CarId, _CarCellFrom), move_car(Car, CarCellTo, From TailState). move_car((_CarIdFrom, CellFrom), CellTo, OtherCars):- exist_edge(CellFrom, CellTo), + member((_CarIdTo, CellTo), OtherCars). is_state_processed(State, ProcessedStates):- member(ProcessedState, ProcessedStates), merge_list(State, ProcessedState), !. cesta([[FinishState|PathPart]|_], [FinishState|PathPart]):- merge_list(FinishState, [(1, a), (2, b), (3, c), (4, c), ( 5, i), (6, j), (7, k), (8, 5)]). cesta([[FromState|PathPart]|ProcList], Cesta):- findall(Y, krok(FromState, PathPart, Y), AdjNodes), append(ProcList, AdjNodes, NewProcList), !, cesta (NewProcList, Path). step(FromState, ProcessedState,[ToState, FromState|ProcessedState]):- proliferate(FromState, ToState), + is_state_processed(ToState, ProcessedState). řešení(cesta):- cesta([[[(6, a), (7, b), (8, c), (1, c), (2, i), (3, j), (4, k), (XNUMX, l)]]], RPath), reverzní (RPath, Cesta), zápis (Cesta).
Abych zkontroloval stavy, napsal jsem predikát merge_list, který skutečně kontroluje, zda je jeden seznam permutací jiného. Postupně vytahuje prvky z prvního seznamu a hledá je ve druhém pomocí standardního predikátu select. Stejný predikát se používá pro kontrolu, zda se s podmínkou již dříve setkal (to značně urychlilo práci, ale problém zcela nevyřešilo).
Pokud zadáme jako vstup méně složitý požadavek (například situace, kdy k dosažení výsledku potřebujeme pouze 8 permutací), pak po 30 sekundách utrpení. vytvoří seznam přechodů.
V tomto případě můžete použít tzv hloubkové hledání je modifikace hloubkového vyhledávání, ve které se řešení hledá nejprve v 1 tahu, poté ve 2, ve 3 atd. dokud není vybrán minimální počet tahů pro získání odpovědi.