Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift算法计算到达目的地的可能途径_Swift_Algorithm - Fatal编程技术网

Swift算法计算到达目的地的可能途径

Swift算法计算到达目的地的可能途径,swift,algorithm,Swift,Algorithm,我正在写一个算法来计算到达目的地的可能路径数,该目的地距离起始点有n步,因为每个移动可以是1到6步的随机数 以下是算法的概要: f(1) = 1 // when total number of block is 1, there is 1 way to reach the goal f(2) = 2 // when total number of block is 2, there is 2 ways to reach the goal, such as 1+1 and 2 f(3) =

我正在写一个算法来计算到达目的地的可能路径数,该目的地距离起始点有n步,因为每个移动可以是1到6步的随机数

以下是算法的概要:

 f(1) = 1 // when total number of block is 1, there is 1 way to reach the goal
 f(2) = 2 // when total number of block is 2, there is 2 ways to reach the goal, such as 1+1 and 2
 f(3) = 5 // when total number of block is 3, there is 5 ways to reach the goal
 f(4) = 8 // when total number of block is 3, there is 5 ways to reach the goal
 f(5) = 14 // when total number of block is 3, there is 5 ways to reach the goal
 f(6) = 25 // when total number of block is 3, there is 5 ways to reach the goal

 // when total number of block is 7, you may rolled 1~6 at 1st time
 // then you have 7-1 ~ 7-6 block for the rest, thus 
 f(7) = f(7-1) + f(7-2) + f(7-3) + f(7-4) + f(7-5) + f(7-6) 

 // With MI, when total number of block is n, then
 f(n) = f(n-1) + f(n-2) + f(n-3) + f(n-4) + f(n-5) + f(n-6)
我设法得到了这个函数

func probabilityToGoal(_ n: Int) -> Int {
    if n == 1 {return 1}
    if n == 2 {return 2}
    if n == 3 {return 5}
    if n == 4 {return 8}
    if n == 5 {return 14}
    if n == 6 {return 25}

    return probabilityToGoal(n-1)
         + probabilityToGoal(n-2)
         + probabilityToGoal(n-3)
         + probabilityToGoal(n-4)
         + probabilityToGoal(n-5)
         + probabilityToGoal(n-6)
}

但问题是函数只在小值(小于50)下运行。我们如何在swift 3中实现上述算法以获得大值(例如n=610)

您需要使用一种称为动态规划的技术

其思想是通过避免对已经计算的值进行递归调用来修剪调用树的整个分支

字典用于存储从输入到输出的映射。每次新的递归调用即将完成时,首先检查字典,查看它是否已经包含所需输入的输出。如果它存在,则使用它,否则使用递归获得结果。计算完成后,结果将存储在字典中以备将来使用

下面是它的样子:

var cache = [Int: Int]()

func probabilityToGoal(_ n: Int) -> Int {
    if n == 1 { return 1 }
    if n == 2 { return 2 }
    if n == 3 { return 5 }
    if n == 4 { return 8 }
    if n == 5 { return 14 }
    if n == 6 { return 25 }

    if let existingValue = cache[n] {
        // result for n is already known, just return it
        return existingValue
    }

    let newValue = probabilityToGoal(n-1)
                 + probabilityToGoal(n-2)
                 + probabilityToGoal(n-3)
                 + probabilityToGoal(n-4)
                 + probabilityToGoal(n-5)
                 + probabilityToGoal(n-6)

    cache[n] = newValue // store result for future result

    return newValue
}

print(probabilityToGoal(64))
记住这是行不通的≥ 64,因为它会溢出64位
Int
(在64位系统上)

此外,迭代解决方案的执行速度要快得多,因为它消除了递归开销,并允许您使用数组而不是字典:

var cache = [0, 1, 2, 5, 8, 14,25]

func probabilityToGoal2(_ n: Int) -> Int {
    cache.reserveCapacity(n)
    for i in stride(from: n, to: 6, by: +1) {
            let r1 = cache[i - 1] + cache[i - 2]
            let r2 = cache[i - 3] + cache[i - 4]
            let r3 = cache[i - 5] + cache[i - 6]
            cache.append(r1 + r2 + r3)
    }

    return cache[n]
}

谢谢你的帮助。这意味着我们只能为n@LêKhánhVinh您可以使用类似@LêKhánhVinh的东西,也许您可以使用它来代替
Int
,并获得更高数字的结果。缓存也可以通过创建“记忆”功能来完成,如WWDC 2014会话404:Advanced Swift中所述。马丁纳:是的,我见过,真的很酷。但我特别选择了一种更为深入的方法,并展示了设计是如何实现的。在你做Memoization-as-a-Restful-YAML-microservice-API-provider-factory之前,你必须先走一走:你确定f(3)=5和f(5)=14吗?@MartinR是的,我认为
f(3)=4
11
12
21
3
)谢谢你应该是f(3)=4。f(5)=14正确吗?@LêKhánhVinh:f(5)=14不正确。f(5)应该是12?