汉诺塔

Posted yant07

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汉诺塔相关的知识,希望对你有一定的参考价值。

昨天户外拓展的时候,教练安排了“汉诺塔”这个游戏,目的是考验大伙的智力和团队合作能力。

 

当汉诺塔的层数增加的时候,明显觉得排列组合的难度大了很多。其实,如果换一种思维去想这个问题,就会觉得其实不那么难。

 

技术分享图片

 

可以把整个汉诺塔看成两个部分,最底端的套圈(A)和除去最底端的套圈之外的其他套圈(B)。 那目标就变得简单了:

1. 将B挪开(移动到缓冲区)

2. 移动A到目标区

3. 将缓冲区的B移动到A上

 

举个例子,当只有2个套圈时,只需要移动B,再移动A,再将B移动到A上,一共3步即可完成。当有3个套圈的时候,我们把B当成一个整体,先挪开,再组合,挪开和组合就是移动这个整体(2个套圈)两次,中间再加一步移动A,所以理论上最少需要(3*2+1=7)步。同理,4个套圈需要(7*2+1)15步。可以通过归纳法得到步数为2n-1。

 

可以把这种思想用递归来表示出来,那就是:

def move(n,from1,buffer,to):
    global k
    if n==1:
        print (from1 ,->, to)
        k=k+1
        print (k)
    else:
        move(n-1, from1, to, buffer)
        move(1, from1, buffer, to)
        move(n-1, buffer, from1, to)


k=0      
move(4,"a","b","c")
print("%d steps in total."%k)
a -> b
1
a -> c
2
b -> c
3
a -> b
4
c -> a
5
c -> b
6
a -> b
7
a -> c
8
b -> c
9
b -> a
10
c -> a
11
b -> c
12
a -> b
13
a -> c
14
b -> c
15
15 steps in total.

 P.S. : a b c分别是三根柱子

 

OK,既然到了这里。可否多想一步?尝试train一个model,让model能够知道汉诺塔的下一步该如何移动。

 

思路如下:以n=4为例,汉诺塔完成移动一共最少需要15步。可以把汉诺塔抽象成15*3*4的三维资料库,每一笔资料看成一个有序的二维数组(3*4)。

 

移动的方式可以抽象成6种:

a -> b
1

a -> c
2

b -> c
3

c -> a
4

c -> b
5

b -> a
6

 

最后用Keras搭建LSTM框架。

 

import os
import
pandas as pd import numpy as np os.chdir(r"C:\\Users\\yant07\\Desktop\\han") han=pd.read_csv("han.csv",header=None) dataX=han.loc[:,0:2] X1=np.array(dataX) X=np.reshape(X1,(15,3,1)) y=han.loc[:,3] y=pd.get_dummies(y) from keras.layers.core import Activation, Dense #from keras.layers import Embedding,Masking from keras.layers.recurrent import LSTM from keras.models import Sequential from keras.preprocessing import sequence #from sklearn.model_selection import train_test_split model = Sequential() model.add(LSTM(32, input_shape=(X.shape[1], X.shape[2]))) model.add(Dense(y.shape[1], activation=softmax)) model.compile(loss=categorical_crossentropy, optimizer=adam, metrics=[accuracy]) model.fit(X, y, nb_epoch=5000, batch_size=1, verbose=1) 15/15 [==============================] - 0s 4ms/step - loss: 0.7316 - acc: 0.7333 Epoch 212/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.7247 - acc: 0.8000 Epoch 213/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.7211 - acc: 0.8000 Epoch 214/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.7122 - acc: 0.8000 Epoch 215/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.7145 - acc: 0.8000 Epoch 216/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.7052 - acc: 0.8667 Epoch 217/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.7011 - acc: 0.8667 Epoch 218/5000 15/15 [==============================] - 0s 4ms/step - loss: 0.6948 - acc: 0.8667 Epoch 219/5000 15/15 [==============================] - 0s 5ms/step - loss: 0.6868 - acc: 0.8667 ...

发现准确率并不是很高。86%  主要原因可能是抽象出来的数据结构并没有完全区分所有情况,也可能是数据量有限。

 

最后祝大家周末愉快~ :p


以上是关于汉诺塔的主要内容,如果未能解决你的问题,请参考以下文章

python汉诺塔非递归

C语言汉诺塔问题

汉诺塔问题的详解-附代码

python3汉诺塔简单实现代码

汉诺塔(代码记录+注释)

hdu 汉诺塔