康托展开与八数码问题
康托展開的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai為當前未出現的元素中是排在第幾個(從0開始)。
?
用康托展開將排列對應為整數 即這個排列在所有排列中的字典序
舉個例子來說明一下:
例如,有一個數組 s = ["A", "B", "C", "D"],它的一個排列 s1 = ["D", "B", "A", "C"],現在要把 s1 映射成 X。
n 指的是數組的長度,也就是4,所以
X(s1) = a4*3! + a3*2! + a2*1! + a1*0!
關鍵問題是 a4、a3、a2 和 a1?等于什么?
a4 = "D" 這個元素在子數組 ["D", "B", "A", "C"] 中是第幾大的元素。"A"是第0大的元素,"B"是第1大的元素,"C" 是第2大的元素,"D"是第3大的元素,所以 a4 = 3。
a3 = "B" 這個元素在子數組 ["B", "A", "C"] 中是第幾大的元素。"A"是第0大的元素,"B"是第1大的元素,"C" 是第2大的元素,所以 a3 = 1。
a2 = "A" 這個元素在子數組 ["A", "C"] 中是第幾大的元素。"A"是第0大的元素,"C"是第1大的元素,所以 a2 = 0。
a1 = "C" 這個元素在子數組 ["C"] 中是第幾大的元素。"C" 是第0大的元素,所以 a1 = 0。(因為子數組只有1個元素,所以a1總是為0)
所以,X(s1) = 3*3! + 1*2! + 0*1! + 0*0! = 20
?
八數碼解法一:廣搜+哈希
考慮到費時主要在STL,對于大規模的遍歷,用到了ST的set和string,在效率上的損失是很大的,因此,現在面臨一個嚴重的問題,必須自己判重,為了效率,自然是自己做hash。有點麻煩,hash函數不好想,實際上是9!種排列,需要每種排列對應一個數字。網上搜索,得知了排列和數字的對應關系。取n!為基數,狀態第n位的逆序值為哈希值第n位數。對于空格,取其為9,再乘以8!。例 如,1 3 7 24 6 9 5 8 的哈希值等于:0*0! + 2*1! + 0*2! + 1*3! + 3*4! +1*5! + 0*6! + 1*7! + 0*8! <9!具體的原因可以去查查一些數學書,其中1 2 34 5 6 7 8 9 的哈希值是0 最小,9 8 7 6 54 3 2 1 的哈希值是(9!-1)最大。而其他值都在0 到(9!-1) 中,且均唯一。然后去掉一切STL之后,甚至包括String之后,得到單向廣搜+Hash的代碼,算法已經可以在三秒鐘解決問題,可是還是不夠快!POJ時限是1秒,后來做了簡單的更改,將路徑記錄方法由字符串改為單個字符,并記錄父節點,得到解,這次提交,266ms是解決單問題的上限。當然,還有一個修改的小技巧,就是逆序對數不會改變,通過這個,可以直接判斷某輸入是否有可行解。由于對于單組最壞情況的輸入,此種優化不會起作用,所以不會減少單組輸入的時間上限。
?
轉載于:https://www.cnblogs.com/zeze/p/6209538.html
總結
以上是生活随笔為你收集整理的康托展开与八数码问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css3加载ing动画
- 下一篇: 【bzoj1708】[USACO2007