让f
成为算术函数,A={k1,k2,...,kn}
是递增顺序的整数。
现在,我想从k1
开始,并将f(ki)
与f(k1)
进行比较。如果f(ki)>f(k1)
,请将ki
设为k1
。
现在从ki
开始,将f(kj)
与f(ki)
进行比较,j>i
。如果f(kj)>f(ki)
,请将kj
设为ki
,然后重复此过程。
最后,我们将使用此属性的B={L1,...,Lm}
子序列A
:
L1=k1
L2=ki
L3=kj
...
,其中
f(L(i+1))>f(L(i))
,适用于任何1<=i<=m-1
例如,设f为整数的除数函数。
我认为应该有一些方法比我更有效率和更快。
您是否知道如何在Mathematica或Matlab中为我的目的编写代码。
Mathematica更可取。
«««««««««««««««««««««««««««««««
我已经使用Mathematica为这个程序编写了一个代码,并且需要几个小时来计算ki的f或大数的集合B.
这里我放了部分代码,这只是一个示例,我的程序中的问题可能比这些更大:
g之间的空间是产品。例如:
g [67757] g [353] = g [67757] * g [353]««««««««««««««««««««««««««««««««««««
f[n_] := DivisorSigma[0, n];
g[n_] := Product[Prime[i], {i, 1, PrimePi[n]}];
k1 = g[67757] g[353] g[59] g[19] g[11] g[7] g[5]^2 6^3 2^7;
k2 = g[67757] g[353] g[59] g[19] g[11] g[7] g[5] 6^5 2^7;
k3 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5] 6^4 2^7;
k4 = g[67759] g[349] g[53] g[19] g[11] g[7] g[5] 6^5 2^6;
k5 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5] 6^4 2^8;
k6 = g[67759] g[349] g[53] g[19] g[11] g[7] g[5]^2 6^3 2^7;
k7 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5] 6^5 2^6;
k8 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5] 6^4 2^9;
k9 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5]^2 6^3 2^7;
k10 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5] 6^5 2^7;
k11 = g[67759] g[349] g[53] g[19] g[11] g[7] g[5]^2 6^4 2^6;
k12 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5]^2 6^3 2^8;
k13 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5]^2 6^4 2^6;
k14 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5]^2 6^3 2^9;
k15 = g[67757] g[359] g[53] g[19] g[11] g[7] g[5]^2 6^4 2^7;
k16 = g[67757] g[359] g[53] g[23] g[11] g[7] g[5] 6^4 2^8;
k17 = g[67757] g[359] g[59] g[19] g[11] g[7] g[5] 6^4 2^7;
k18 = g[67757] g[359] g[53] g[23] g[11] g[7] g[5] 6^4 2^9;
k19 = g[67759] g[353] g[53] g[19] g[11] g[7] g[5] 6^4 2^6;
k20 = g[67763] g[347] g[53] g[19] g[11] g[7] g[5] 6^4 2^7;
k = Table[k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20];
i = 1;
count = 0;
For[j = i, j <= 20, j++,
If[f[k[[j]]] - f[k[[i]]] > 0, i = j; Print["k",i];
count = count + 1]];
Print["count= ", count]
««««««««««««««««««««««««««««««««««««
答案 0 :(得分:6)
将新列表计算为旧列表/ gcd。
考虑gcd。
使用一个函数,在给定一对因子形式的整数的情况下,合并分解(因此你将它们的产品分解为因子形式)。
然后对于简化列表中的任何两个元素,您可以通过将它们的每个因子与gcd的因子合并进行比较,并在给定因式形式时调用一个函数来计算除数的数量。最后一个只是指数的乘积,每个都增加了一个。
在代码中:
kgcd = GCD @@ k;
newk = k/kgcd;
gcdfacs = FactorInteger[kgcd];
sumDivisors[faclist_] := Times @@ (1 + faclist[[All, 2]])
mergeFactorLists[fl1_, fl2_] :=
Flatten[GatherBy[Join[fl1, fl2], First] /.
{{p1_Integer,e1_Integer}, {p1_,e2_Integer}} -> {{p1,e1+e2}}, 1]
f2[v1_] := sumDivisors[mergeFactorLists[FactorInteger[v1], gcdfacs]]
以下是您的示例,其中f2应用于newk的元素。
Timing[i = 1;
count = 0;
For[j = i, j <= 20, j++,
If[f2[newk[[j]]] - f2[newk[[i]]] > 0, i = j; Print["k", i];
count = count + 1]];
Print["count= ", count]]
评估In [140]时:= k2
评估In [140]时:= k5
评估In [140]时:= k7
评估In [140]时:= k8
评估In [140]时:= k9
评估In [140]时:= k10
评估In [140]时:= k12
评估In [140]时:= k13
评估In [140]时:= k14
评估In [140]时:= k15
评估In [140]时:= k16
评估In [140]时:= k17
评估In [140]时:= k18
在评估In [140]期间:= count = 13
Out [140] = {0.539918,Null}
正如其他人评论的那样,你可能想要做SortBy或者
sortedk = k[[Ordering[newk, All, f2[#1] < f2[#2] &]]];
- 更新2011-02-01 -
以下是各种请求函数,用于对表示为其素因子和相应幂的列表的整数进行操作。我们使用效用函数来“乘”两个或更多这样的表示,以便它们可以从上面g []的定义中轻松构造。
logarithm [fl_]:= fl [[All,2]]。登录[FL [[全部,1]]]
divSigma[k_, fax_] := Times @@
((fax[[All, 1]]^(k*(fax[[All, 2]] + 1)) - 1)/(fax[[All, 1]]^k - 1))
mergeFactorLists[f1_,f2_,f3__] :=
mergeFactorLists[mergeFactorLists[f1,f2],f3]
mergeFactorLists[fl1_, fl2_] :=
Flatten[GatherBy[Join[fl1, fl2], First] /.
{{p1_Integer,e1_Integer}, {p1_,e2_Integer}} -> {{p1,e1+e2}}, 1]
eulerPhi[fl_] :=
Times @@ ((fl[[All, 1]] - 1)*fl[[All, 1]]^(fl[[All, 2]] - 1))
我以类似于上面使用g []的方式使用factorlist,但是为了获得因式列表而不是整数本身。为了便于转换代码,您可以执行以下操作。
g[n__] := factorList[n]
然后你将构建k1等作为:
k1 = mergeFactorLists[g[67757], g[353], g[59], g[19], g[11], g[7],
g[5, 2], g[4, 3], g[2, 7]];
我注意到使用索引可能更好,例如k [1],k [2]等。这种方式可以存储索引而不是数字(无论是表示为因子列表还是完全展开)。这是您的评论或私人电子邮件中的一个问题,我不确定。
这是一个简短的例子,表明这些功能可能与广告一样有效。
在[77]中:= example = mergeFactorLists [g [59],g [19],g [11],g [7],g [5,2],g [4,3],g [2,7]] Out [77] = {{2,16},{3,9},{5,6},{7,4},{11,3},{13,2},{17, 2},{19,2},{23,1},{29,1},{31,1},{37,1},{41,1},{43, 1},{47,1},{53,1},{59,1}}
在[83]中:= divSigma [2,示例] 出[83] = 8309625653259163198663074449058595410045270294408417958734031 0136565010401600000000
在[92]中:= eulerPhi [例子] 出[92] = 30117106786279162451552137484697600000000
在[95]中:= examplenumber = Times @@ Map [#[[1]] ^#[[2]]&amp ;, example] 出[95] = 225123336762006539948611826706656256000000
在[99]中:= DivisorSigma [2,examplenumber] 出[99] = 8309625653259163198663074449058595410045270294408417958734031 0136565010401600000000
在[100]中:= EulerPhi [examplenumber] Out [100] = 30117106786279162451552137484697600000000
- 结束更新 -
Daniel Lichtblau Wolfram Research
答案 1 :(得分:1)
在我的mathematica版本中,大部分计算时间都花在应用函数f [n]上。即使只是f [k1]也需要几秒钟。
无论如何,您要做的是使用SortBy。这将采用列表和函数作为参数。它将函数应用于列表的每个成员,并按从最小到最大的顺序对它们进行排序,因此您需要将列表交换为最大到最小。记得使用k = List [k1,k2,...,k20]而不是k = Table [k1,k2,...,k20],你应该很好。
答案 2 :(得分:0)
之所以这么慢,部分原因是因为你在Mathematica中使用for和if。两者都不是特别快。
通常建议尝试进行一些列表操作,因为这样会更快。我不确定你是如何做到这一点的,但你可能想要研究一下。