Mathematica: Gerçek Labirent (827 karakter)
Başlangıçta, {1,1,1} 'den {5,5,5}' e bir yol ürettim, ancak yapılması gereken yanlış dönüşler olmadığı için çatalları veya "karar noktalarını" (derece 2> köşeleri) kişinin hangi yöne gideceğine karar vermesi gerekir. Sonuç gerçek bir labirent veya labirenttir.
"Kör sokakları" çözmek basit, doğrudan bir yol bulmaktan çok daha zordu. En zorlu şey, çözüm yolundaki döngülere izin verirken yol içindeki döngüleri ortadan kaldırmaktı.
Aşağıdaki iki kod satırı yalnızca çizilen grafikleri oluşturmak için kullanılır, bu nedenle çözümde kullanılmadığından kod sayılmaz.
o = Sequence[VertexLabels -> "Name", ImagePadding -> 10, GraphHighlightStyle -> "Thick",
ImageSize -> 600];
o2 = Sequence[ImagePadding -> 10, GraphHighlightStyle -> "Thick", ImageSize -> 600];
Kullanılan kod:
e[c_] := Cases[EdgeList[GridGraph[ConstantArray[5, 3]]], j_ \[UndirectedEdge] k_ /; (MemberQ[c, j] && MemberQ[c, k])]
m[] :=
Module[{d = 5, v = {1, 125}},
While[\[Not] MatchQ[FindShortestPath[Graph[e[v]], 1, 125], {1, __, 125}],
v = Join[v, RandomSample[Complement[Range[125], v], 1]]];
Graph[e[Select[ConnectedComponents[Graph[e[v]]], MemberQ[#, 1] &][[1]]]]]
w[gr_, p_] := EdgeDelete[gr, EdgeList[PathGraph[p]]]
y[p_, u_] := Select[Intersection[#, p] & /@ ConnectedComponents[u], Length[#] > 1 &]
g = HighlightGraph[lab = m[], PathGraph[s = FindShortestPath[lab, 1, 125]],o]
u = w[g, s]
q = y[s, u]
While[y[s, u] != {}, u = EdgeDelete[u, Take[FindShortestPath[u, q[[1, r = RandomInteger[Length@q[[1]] - 2] + 1]],
q[[1, r + 1]]], 2] /. {{a_, b_} :> a \[UndirectedEdge] b}];
q = y[s, u]]
g = EdgeAdd[u, EdgeList@PathGraph[s]];
Partition[StringJoin /@ Partition[ReplacePart[Table["x", {125}],
Transpose[{VertexList[g], Table["o", {Length[VertexList@g]}]}]/. {{a_, b_} :> a -> b}], {5}], 5]
Örnek çıktı
{{"oxooo", "xxooo", "xoxxo", "xoxxo", "xxoox"}, {"ooxoo", "xoooo", "ooxox", "oooxx", "xooxx"}, {"oooxx", "ooxxo", "ooxox", "xoxoo", "xxxoo"}, {"oxxxx", "oooox", "xooox", "xoxxx", "oooxx"}, {"xxxxx", "ooxox", "oooox "," xoxoo "," oooxo "}}
Kaputun altında
Aşağıdaki resim, ({{"ooxoo",...}}
yukarıda görüntülenen çözüme karşılık gelen labirent veya labirenti gösterir :
İşte aynı labirent, 5x5x5'e yerleştirildi GridGraph
. Numaralı köşeler, labirentten en kısa yoldaki düğümlerdir. Çatalları veya karar noktalarını 34, 64 ve 114'te not edin. Çözümün bir parçası olmasa bile grafiği oluşturmak için kullanılan kodu ekleyeceğim:
HighlightGraph[gg = GridGraph[ConstantArray[5, 3]], g,
GraphHighlightStyle ->"DehighlightFade",
VertexLabels -> Rule @@@ Transpose[{s, s}] ]
Ve bu grafik sadece labirentin çözümünü gösterir:
HighlightGraph[gg = GridGraph[ConstantArray[5, 3]],
Join[s, e[s]], GraphHighlightStyle -> "DehighlightFade", VertexLabels -> Rule @@@ Transpose[{s, s}] ]
Son olarak, kodun okunmasına yardımcı olabilecek bazı tanımlar:
Orijinal çözüm (432 karakter, Bir yol oluşturdu, ancak gerçek bir labirent veya labirent değil)
Farklı birim küplerden oluşan 5x5x5 büyüklüğünde bir katı küp düşünün. Aşağıdakiler, çözümün bir parçası olması gerektiğini bildiğimiz için {1,1,1} ve {5,5,5} 'de birim küpler olmadan başlar. Daha sonra {1,1,1} 'den {5,5,5}' e engelsiz bir yol olana kadar rastgele küpleri kaldırır.
"Labirent", kaldırılmış birim küpler göz önüne alındığında en kısa yoldur (birden fazla mümkünse).
d=5
v={1,d^3}
edges[g_,c_]:=Cases[g,j_\[UndirectedEdge] k_/;(MemberQ[c,j]&&MemberQ[c,k])]
g:=Graph[v,edges[EdgeList[GridGraph[ConstantArray[d,d]]],v]];
While[\[Not]FindShortestPath[g,1,d^3]!={},
v=Join[v,RandomSample[Complement[Range[d^3],v],1]]]
Partition[Partition[ReplacePart[
Table["x",{d^3}],Transpose[{FindShortestPath[g,1,d^3],Table["o",{Length[s]}]}]
/.{{a_,b_}:> a->b}],{d}]/.{a_,b_,c_,d_,e_}:> StringJoin[a,b,c,d,e],5]
Misal:
{{"ooxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxx"},
{"xoxxx", "xoooo", "xxxxo", "xxxxo", "xxxxo"},
{"xxxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxo"},
{"xxxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxo"},
{"xxxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxo"}}
Teknik olarak bu henüz gerçek bir labirent değildir, çünkü kişinin yapabileceği yanlış dönüşler yoktur. Ama grafik teorisine dayandığından ilginç bir başlangıç olarak düşündüm.
Rutin aslında bir labirent yapar ama döngülere neden olabilecek tüm boş yerleri tıkadım. Döngüler kaldırmanın bir yolunu bulursam bu kodu buraya ekleyeceğim.