====== Puzzle: Eight chess knights ... ====== * http://www.ageofpuzzles.com/Puzzles/ChessPuzzles.htm {{:pics:notes:knightsProblem.png}} * [[http://zvonka.fmf.uni-lj.si/netbook/lib/exe/fetch.php?id=paper%3A2-mode%3Asemi&cache=cache&media=pub:zip:april18.zip|Graph April 18, 2011]] ===== Omrežje skokov ===== # 0 1 2 3 # 4 x 5 6 # x 7 8 x # x 9 10 x # Vladimir Batagelj, 11. april 2012 def solutions(a,b,c,s=""): global n, S if a+b+c == 0: n += 1; S[s] = n; net.write(str(n)+' "'+s+'"\n'); return if a > 0: solutions(a-1,b,c,s+'.') if b > 0: solutions(a,b-1,c,s+'B') if c > 0: solutions(a,b,c-1,s+'C') global n, S net = open('horse.net','w') net.write('*vertices \n') n = 0; S = {} solutions(3,4,4) print('# of vertices = ',len(S)) skoki = [[5,7], [8,6], [4,7], [8], [2,8,9], [0,9], [1,7,10], [0,2,6], [1,3,4], [4,5], [6] ] net.write('*edges\n') for sol in S.keys(): for i in range(11): if sol[i]=='.': for j in skoki[i]: tol = sol[:i]+sol[j]+sol[(i+1):] tol = tol[:j]+'.'+tol[(j+1):] si = S[sol]; ti = S[tol] if ti>si: net.write(str(si)+' '+str(ti)+'\n') net.close() print('graph is on the file horse.net') {{:notes:data:knights.net}} Iščemo najkrajše poti med ..BB.BBCCCC in ..CC.CCBBBB . V Pajku dobimo ustrezno podomrežje. Najkrajše poti imajo dolžino 18. Rešitev je veliko. Če natančneje preberemo nalogo, vidimo, da dopušča tudi zaporedja skokov istega konjička - **poteze** in sprašuje po rešitvi, ki zahteva najmanj potez. Možne so le poteze dolžine 1, 2 ali 3. ===== Omrežje potez ===== Omrežju dodamo poteze dolžine 2 (2 skoka) čez dvojnike srednje točke. i k j ---------------------------------- u | |c| |.| |.| | ---------------------------------- ---------------------------------- t | |.| |c| |.| | ---------------------------------- ---------------------------------- v | |.| |.| |c| | ---------------------------------- Uteži novih povezav so 1/2. Nato še poteze dolžine 3 z utežmi povezav 1/3 i k m j ------------------------------------------- u | |c| |.| |.| |.| | ------------------------------------------- ------------------------------------------- t | |.| |c| |.| |.| | ------------------------------------------- ------------------------------------------- z | |.| |.| |c| |.| | ------------------------------------------- ------------------------------------------- v | |.| |.| |.| |c| | ------------------------------------------- Iskane rešitve so najkrajše poti v omrežju potez. Omrežje skokov dopolnimo s potezami: from Graph import Graph def Knights(): G = Graph.loadPajek('horse.net') S = { G.getNode(k,'lab') : k for k in G.nodes() } n = len(S); print("# of vertices = ",n); A = "abcdefghijk" skoki = [[5,7], [8,6], [4,7], [8], [2,8,9], [0,9], [1,7,10], [0,2,6], [1,3,4], [4,5], [6] ] for T in S.keys(): t = S[T]; p = [i for i in range(11) if T[i] == '.'] for [i,j] in [ [p[0],p[1]], [p[0],p[2]], [p[1],p[2]] ]: for k in set(skoki[i]) & set(skoki[j]): U = T[:i]+T[k]+T[(i+1):]; U = U[:k]+'.'+U[(k+1):] V = T[:j]+T[k]+T[(j+1):]; V = V[:k]+'.'+V[(k+1):] u = S[U]; v = S[V] if (u!=t) & (v!=t): n += 1; G.addNode(n); G.setNode(n,'lab',T+A[k]) G.addEdge(u,n,0.5); G.addEdge(n,v,0.5) for T in S.keys(): t = S[T]; p = [i for i in range(11) if T[i] == '.'] for i in p: for k in set(skoki[i])-set(p): ch = T[k]; U = T[:i]+ch+T[(i+1):]; U = U[:k]+'.'+U[(k+1):]; u = S[U] for m in (set(skoki[k])&set(p))-{i}: Z = T[:m]+ch+T[(m+1):]; Z = Z[:k]+'.'+Z[(k+1):]; z = S[Z] for j in (set(skoki[m])&set(p))-{i,k}: V = T[:j]+ch+T[(j+1):]; V = V[:k]+'.'+V[(k+1):]; v = S[V] n += 1; G.addNode(n); G.setNode(n,'lab',T+A[k]) G.addEdge(u,n,1/3) n += 1; G.addNode(n); G.setNode(n,'lab',Z+A[k]) G.addEdge(n-1,n,1/3); G.addEdge(n,v,1/3) G.savePajek('8knights.net',False) print("done, # of vertices = ",n) if __name__ == '__main__': Knights() {{:notes:data:8knights.net}} V Pajku dobimo za poteze dolžine 2 dve najkrajši poti dolžine 12 {{:notes:pics:knights.png}} Ko dodamo še poteze dolžine 3, je rešitev dolžine 12 več {{:notes:data:8knightsSol.net}} **Opravki:** Skoke in poteze pobarvati z barvo konjička, ki skače - črni ali beli (večrelacijsko omrežje). Morda vrednosti uteži zamenjati s 6, 3 in 2. Tako se pri iskanju najkrajših poti izognemo morebitnim zaokrožitvenim napakam - računamo s celimi števili. * http://vlado.fmf.uni-lj.si/seminar/dmfa08/ * http://www.presek.si/3/3-4-Batagelj.pdf