学习需要,结合模型实现了商人过河问题。
包括:
- N商人N随从 M小船问题
- 人,猫,鸡,米过河问题
目前使用暴力算法,后期打算写下Dijstra算法求解(毕竟暴力算法无法证明无解性)
模型
S允许状态集合
D允许决策集合
代码
N对商人随从过河
const N = 3
// 遍历算法
// 输入 商人 随从人数 n = 3,4,5...
// 输出 每一步的 决策
func nextStep(x, y, stepCount int, printContent string) {
// 设置递归层数,防止无限递归。
if stepCount > 30 {
return
}
// 决策集合
for _, decision := range [][2]int{{0, 1}, {0, 2}, {1, 0}, {1, 1}, {2, 0}} { // 可以改变允许决策集合D
nextX, nextY := decide(x, y, decision[0], decision[1], stepCount)
if checkInS(nextX, nextY) {
nextPrintContent := printContent + fmt.Sprintf("第%d步:%d,%d.", stepCount, decision[0], decision[1])
//fmt.Println(nextPrintContent)
if nextX == 0 && nextY == 0 {
fmt.Println(nextPrintContent, nextX, nextY)
return
}
nextStep(nextX, nextY, stepCount+1, nextPrintContent)
}
}
}
// 做决策
func decide(x, y, decisionOne, decisionTwo, stepCount int) (int, int) {
if stepCount%2 != 0 {
return x - decisionOne, y - decisionTwo
} else {
return x + decisionOne, y + decisionTwo
}
}
// 查看现在的状态是否符合 S 允许状态集合
func checkInS(x, y int) bool {
if N <= 0 {
return false
}
if x == y {
return true
}
for j := 0; j <= N; j++ {
if x == 0 && y == j {
return true
}
}
for j := 0; j <= N; j++ {
if x == N && y == j {
return true
}
}
return false
}
复制代码
人猫鸡米过河
同上面算法类似,只是增加了变元
func nextStep(a, b, c, d, stepCount int, printContent string) {
if stepCount > 7 {
return
}
for _, decision := range [][4]int{{1, 0, 0, 0}, {1, 0, 0, 1}, {1, 0, 1, 0}, {1, 1, 0, 0}} {
nextA, nextB, nextC, nextD := decide(a, b, c, d, decision[0], decision[1], decision[2], decision[3], stepCount)
if checkInS(nextA, nextB, nextC, nextD) {
nextPrintContent := printContent + fmt.Sprintf("第%d步:%d,%d,%d,%d.", stepCount, decision[0], decision[1], decision[2], decision[3])
//fmt.Println(nextPrintContent)
if nextA == 0 && nextB == 0 && nextC == 0 && nextD == 0 {
fmt.Println(nextPrintContent, nextA, nextB, nextC, nextD)
return
}
nextStep(nextA, nextB, nextC, nextD, stepCount+1, nextPrintContent)
}
}
}
func decide(a, b, c, d, decideOne, decideTwo, decideThree, decideFour, stepCount int) (int, int, int, int) {
if stepCount%2 != 0 {
// 是奇数 ,减
return a - decideOne, b - decideTwo, c - decideThree, d - decideFour
}
return a + decideOne, b + decideTwo, c + decideThree, d + decideFour
}
func checkInS(a, b, c, d int) bool {
if 0 <= a && a <= 1 && 0 <= b && b <= 1 && 0 <= c && c <= 1 && 0 <= d && d <= 1 {
if a == 0 {
if b+c == 2 || c+d == 2 {
return false
}
return true
}
if a == 1 {
if b+c == 0 || c+d == 0 {
return false
}
return true
}
return true
}
return false
}
复制代码