Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.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
Java 我的任务需要高效的解决方案_Java_Performance_Algorithm_Dynamic Programming - Fatal编程技术网

Java 我的任务需要高效的解决方案

Java 我的任务需要高效的解决方案,java,performance,algorithm,dynamic-programming,Java,Performance,Algorithm,Dynamic Programming,我只是解决了这个问题,但想知道更有效的矩阵乘法方法 M = | 1 0 3 | | 1 0 2 | | 0 5 0 | f[n]=M^n 我已经实现了使用 还有比这更有效的吗 我想,这实际上更适合数学,因为有一个封闭形式的解。这是一种制度 另一个可能性是:通过推导两个步骤的公式,即通过RR(i-2)等,表示RR(i)等,可以两次加速程序 这可以重复,所以你可以跳得更快。我想,这实际上更适合数学,因为有一个封闭形式的解。这是一种制度 另一个可能性是:通过推导两个步骤的公式,

我只是解决了这个问题,但想知道更有效的矩阵乘法方法

 M = | 1 0 3 |
     | 1 0 2 |
     | 0 5 0 |
f[n]=M^n

我已经实现了使用


还有比这更有效的吗

我想,这实际上更适合数学,因为有一个封闭形式的解。这是一种制度

另一个可能性是:通过推导两个步骤的公式,即通过
RR(i-2)
等,表示
RR(i)
等,可以两次加速程序


这可以重复,所以你可以跳得更快。

我想,这实际上更适合数学,因为有一个封闭形式的解。这是一种制度

另一个可能性是:通过推导两个步骤的公式,即通过
RR(i-2)
等,表示
RR(i)
等,可以两次加速程序


这个过程可以重复,所以你可以跳得更快。

一个问题是你的计算太多了。如果对K=1和J=9运行它,则会得到
-334328541#510576792#-817751931

最简单的修复方法是在
calculateProduction
中执行
%100000006

关于效率,我将把这个问题看作是执行矩阵乘法。 从向量(即1*3矩阵)开始:

在每一步中,将其(mod 100000006)乘以矩阵:

1 1 0
0 0 5
3 2 0
让我们调用向量V和矩阵M。基本上你需要计算V*MN。因为矩阵乘法是关联的,所以可以先计算MN,然后递归地进行计算:
如果N是偶数,则MN=(MN/2)2,或

MN=M*(M[N/2])2如果N是奇数,一个问题是您的计算溢出了。如果对K=1和J=9运行它,则会得到
-334328541#510576792#-817751931

最简单的修复方法是在
calculateProduction
中执行
%100000006

关于效率,我将把这个问题看作是执行矩阵乘法。 从向量(即1*3矩阵)开始:

在每一步中,将其(mod 100000006)乘以矩阵:

1 1 0
0 0 5
3 2 0
让我们调用向量V和矩阵M。基本上你需要计算V*MN。因为矩阵乘法是关联的,所以可以先计算MN,然后递归地进行计算:
如果N是偶数,则MN=(MN/2)2,或

MN=M*(M[N/2])2如果N是奇数,则不需要计算MM。这就是为什么:

PP[i] = 5*MM[i-1] = 5*(RR[i-2] + 2*PP[i-2])
RR[i] = RR[i-1] + 3*PP[i-1] = (RR[i-2] + 3*PP[i-2]) + 3*PP[i-1]
看到了吗?您不需要在每一步计算MM。这应该是算法:

public class RecurrenceMachine {
    private static final int max = 1000000006;

    public String calculate(int k, int j) {
        long n = k * j;
        if (n < 1)
            return "error";
        long RRi2 = 3;
        long PPi2 = 0;
        long RRi1 = 3 + 3 * PPi2;
        long PPi1 = 5 * 1;
        if (n == 1)
            return RRi1 + "##" + (RRi2 + 2 * PPi2) + "##" + PPi1;
        Long PPi = (long) 0, RRi = (long) 0, temp;
        int i;
        for (i = 2; i <= n; i++) {
            temp = RRi2 + 2 * PPi2;
            PPi = 5 * temp;
            if (PPi >= max)
                PPi %= max;
            RRi = temp + PPi2 + 3 * PPi1;
            if (RRi >= max)
                RRi %= max;
            RRi2 = RRi1;
            PPi2 = PPi1;
            RRi1 = RRi;
            PPi1 = PPi;
        }
        return RRi + "##" + (RRi2 + 2 * PPi2) % max + "##" + PPi1;
    }
}
公共类递归机{
私有静态最终整数最大值=1000000006;
公共字符串计算(int k,int j){
长n=k*j;
if(n<1)
返回“错误”;
长RRi2=3;
长PPi2=0;
长RRi1=3+3*PPi2;
长PPi1=5*1;
如果(n==1)
返回RRi1+“##”+(RRi2+2*PPi2)+“##”+PPi1;
长PPi=(长)0,RRi=(长)0,温度;
int i;
对于(i=2;i=max)
PPi%=最大值;
RRi=温度+PPi2+3*PPi1;
如果(RRi>=最大值)
RRi%=最大值;
RRi2=RRi1;
PPi2=PPi1;
RRi1=RRi;
PPi1=PPi;
}
返回RRi+“##”+(RRi2+2*PPi2)%max+“##”+PPi1;
}
}

我只尝试了较小的值,它似乎有效。

您不需要计算MM。这就是为什么:

PP[i] = 5*MM[i-1] = 5*(RR[i-2] + 2*PP[i-2])
RR[i] = RR[i-1] + 3*PP[i-1] = (RR[i-2] + 3*PP[i-2]) + 3*PP[i-1]
看到了吗?您不需要在每一步计算MM。这应该是算法:

public class RecurrenceMachine {
    private static final int max = 1000000006;

    public String calculate(int k, int j) {
        long n = k * j;
        if (n < 1)
            return "error";
        long RRi2 = 3;
        long PPi2 = 0;
        long RRi1 = 3 + 3 * PPi2;
        long PPi1 = 5 * 1;
        if (n == 1)
            return RRi1 + "##" + (RRi2 + 2 * PPi2) + "##" + PPi1;
        Long PPi = (long) 0, RRi = (long) 0, temp;
        int i;
        for (i = 2; i <= n; i++) {
            temp = RRi2 + 2 * PPi2;
            PPi = 5 * temp;
            if (PPi >= max)
                PPi %= max;
            RRi = temp + PPi2 + 3 * PPi1;
            if (RRi >= max)
                RRi %= max;
            RRi2 = RRi1;
            PPi2 = PPi1;
            RRi1 = RRi;
            PPi1 = PPi;
        }
        return RRi + "##" + (RRi2 + 2 * PPi2) % max + "##" + PPi1;
    }
}
公共类递归机{
私有静态最终整数最大值=1000000006;
公共字符串计算(int k,int j){
长n=k*j;
if(n<1)
返回“错误”;
长RRi2=3;
长PPi2=0;
长RRi1=3+3*PPi2;
长PPi1=5*1;
如果(n==1)
返回RRi1+“##”+(RRi2+2*PPi2)+“##”+PPi1;
长PPi=(长)0,RRi=(长)0,温度;
int i;
对于(i=2;i=max)
PPi%=最大值;
RRi=温度+PPi2+3*PPi1;
如果(RRi>=最大值)
RRi%=最大值;
RRi2=RRi1;
PPi2=PPi1;
RRi1=RRi;
PPi1=PPi;
}
返回RRi+“##”+(RRi2+2*PPi2)%max+“##”+PPi1;
}
}


我只尝试了很小的价值观,但似乎很有效。

@DavidPostill为什么不呢?优化和性能是这里常见的标签。我想,这实际上更适合数学,因为有一个封闭形式的解决方案。另一个可能性是:通过推导两个步骤的公式,可以将程序加速两次。这可以重复…@DavidPostill其他人会将其发送给CR。如果你问我,这都是BS。@maaartinus你是对的,我应该说codereview(咖啡不够)@maaartinus
其他人会将其发送给CR。如果你问我,这都是BS。
??正在进行的讨论。。找不到you@DavidPostill为什么是OT?优化和性能是这里常见的标签。我想,这实际上更适合数学,因为有一个封闭形式的解决方案。另一个可能性是:通过推导两个步骤的公式,可以将程序加速两次。这可以重复…@DavidPostill其他人会将其发送给CR。如果你问我,这都是BS。@maaartinus你是对的,我应该说codereview(咖啡不够)@maaartinus
其他人会将其发送给CR。如果你问我,这都是BS。
??正在进行的讨论。。我找不到你我也试过了。。但是没有得到建议,我已经认为这个算法,但问题矩阵求幂可能需要时间。。你能更好地了解矩阵求幂算法吗?…(动态规划)@ankit337我已经解释了如何轻松地进行矩阵求幂,你读了我答案的最后部分了吗?是的,我明白了,但我认为这不足以提高性能,我得到了最好的方法,如何实现这一点?@ankit337我很确定我的方法足够好,这是对数时间,我也尝试过。。但是没有得到建议我已经认为这个算法