如何加速计算时间?
我编写了以下代码:
combinationsstring = "List of Combinations"
for a = 0, 65 do
for b = 0, 52 do
for c = 0, 40 do
for d = 0, 28 do
for e = 0, 19 do
for f = 0, 11 do
for g = 0, 4 do
if (((1.15^a)-1)+((20/3)*((1.15^b)-1))
+((100/3)*((1.15^c)-1))+(200*((1.15^d)-1))
+((2000/3)*((1.15^e)-1))+((8000/3)*((1.15^f)-1))
+((40000/3)*((1.15^g)-1))) < 10000 then
combinationsstring = combinationsstring
.."\n"..a..", "..b..", "..c..", "..d
..", "..e..", "..f..", "..g
end
end
end
end
end
end
end
end
local file = io.open("listOfCombinations.txt", "w")
file:write(combinationsstring)
file:close()
我需要找到所有符合以下等式的数据集
(((1.15 ^ a)-1) + ((20 / 3) * ((1.15 ^ b) -1)) +
((100 / 3) * ((1.15 ^ c) -1)) + (200 * ((1.15 ^ d) -1)) +
((2000 / 3) * ((1.15 ^ e) -1)) + ((8000 / 3) * ((1.15 ^ f) -1)) +
((40000 / 3) * ((1.15 ^ g) -1))) <10000
每个变量(a-g)都是实整数。所以我计算了7个变量中每个的最大值(每个变量的最大值是当其他所有值都为0时)。这些最大值分别为65、52、40、28、19、11和4(62=a,52=b等等)
所以我创建了7个嵌套的循环(如上所示的代码),在中间的块中,我测试了7个值是否符合标准,如果符合,则将它们添加到字符串中。在代码的最后,程序会覆盖一个文件并将最终字符串放在其中,它包含了所有可能的组合。
程序工作得很好,但在这个模拟过程中有31亿次计算,经过一些测试,我发现我的计算机平均每秒进行3000次计算。这意味着总模拟时间约为12天5小时。我根本没有这么多时间,因此我花了整个上午简化了要测试的方程,删除了不必要的代码,这是我的最终结果。
在这里使用嵌套的for循环的方法是否最优?如果是,还有其他方法可以加速这个过程吗?如果不是,请告诉我另一种方法吧。
顺便说一句,我使用Lua,因为这是我最熟悉的语言,但如果你有其他的建议/示例,请使用你的语言并尝试针对这个程序进行优化。
我建议使用静态语言进行这种类型的暴力破解。我曾遇到一个问题(这个),使用 Python 无法解决,但是使用 C++ 的暴力破解方法可以在 30 秒内计算出解决方案。
既然你也要求使用不同的编程语言来解决问题,那么这里是一个快速而不太完美的 C++ 程序,还引入了 @tmyklebu 的建议。
#include <iostream>
#include <fstream>
#include <cmath>
int main()
{
std::ofstream os( "listOfCombinations.txt" );
using std::pow;
for( double a = 0; a <= 65; ++a ) {
double aa = (pow(1.15, a) - 1);
if ( aa > 10000 ) break;
for( double b = 0; b <= 52; ++b ) {
double bb = aa + (20/3) * (pow(1.15, b) - 1);
if ( bb > 10000 ) break;
for( double c = 0; c <= 40; ++c ) {
double cc = bb + (100/3) * (pow(1.15, c) - 1);
if ( cc > 10000 ) break;
// 以下这行代码为用户提供当前 a、b 和 c 值的可视化反馈
std::cout << a << " " << b << " " << c << std::endl;
for( double d = 0; d <= 28; ++d ) {
double dd = cc + 200 * ( pow(1.15, d) - 1);
if ( dd > 10000 ) break;
for( double e = 0; e <= 19; ++e ) {
double ee = dd + (2000/3) * (pow(1.15, e) - 1);
if ( ee > 10000 ) break;
for( double f = 0; f <= 11; ++f ) {
double ff = ee + (8000/3) * (pow(1.15, f) - 1);
if ( ff > 10000 ) break;
for( double g = 0; g <= 4; ++g ) {
double gg = ff + (40000/3) * (pow(1.15, g) - 1);
if ( gg >= 10000 ) break;
os << a << ", " << b << ", "
<< c << ", " << d << ", "
<< e << ", " << f << ", "
<< g << "\n";
}
}
}
}
}
}
}
return 0;
}
local res={}
combinationsstring = "List of Combinations"
--for a = 0, 65 do
a=0
for b = 0, 52 do
for c = 0, 40 do
for d = 0, 28 do
for e = 0, 19 do
for f = 0, 11 do
for g = 0, 4 do
if (((1.15^a)-1)+((20/3)*((1.15^b)-1))
+((100/3)*((1.15^c)-1))+(200*((1.15^d)-1))
+((2000/3)*((1.15^e)-1))+((8000/3)*((1.15^f)-1))
+((40000/3)*((1.15^g)-1))) < 10000 then
res[#res+1]={a,b,c,d,e,f,g}
end
end
end
end
end
end
end
--end
在我的机器上运行需要30秒并占用大约1GB的内存。在32位的Lua VM中无法运行66次,即使使用64位的LuaVM,表的数组部分仍然只能使用32位的整数键。
我已经注释了最外层循环,因此你需要大约30s*66=33分钟。我可能会将其写入66个不同的文件。结果首先存储在一个表中,然后可以连接起来。请查看以下代码:
local res={
{1,2,3,4,5,6,7},
{8,9,10,11,12,13,14}
}
for k,v in ipairs(res) do
-- either concatenate each line and produce a huge string
res[k]=table.concat(v,", ")
-- or write each line to a file in this loop
end
local text=table.concat(res,"\n")
print(text)
打印:
1, 2, 3, 4, 5, 6, 7
8, 9, 10, 11, 12, 13, 14
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我不会用 lua,但是我有几个建议:
b之前,计算并存储1.15^a-1,可以称之为fooa。c之前,计算fooa+(20/3)*(1.15^b-1),可以称之为foob。foob至少为10000,就退出循环;循环内的内容只会让结果变大。我还想补充的是,嵌套循环是一个完全合理的解决方案,并且在进行了以上的修改后,这就是我会做的方法。