如何将这个迭代循环转换为递归循环?

问题描述 投票:0回答:1

目前,我正在为计算机科学课程作业中的 Mandelbrot 集等内容开发分形渲染器,并且我想在下面的函数上使用递归而不是迭代,因为它会给我更多分数。

原始迭代函数如下。 (我删除了函数中用于渲染其他分形的某些部分,但我没有包含它们,否则这会太长)

function fractal:compute(x,y)
    iteration = 1
    local zx = 0
    local zy = 0
    while iteration < self.maxIterations and zx^2 + zy^2 < 4 do
        temp = zx
        if self.current == "Mandelbrot" then
            zx, zy = Mandelbrot(zx,zy,x,y)
        end
        iteration = iteration + 1
    end
    return iteration
end

function Mandelbrot(zx, zy, x, y)
    return zx^2-zy^2+x, 2*zx*zy+y
end

我尝试使用几种方法来做到这一点,例如使用:

x^2 + y^2 > 4 or iteration == maxIterations

作为基本情况,但由于某种原因它似乎不起作用 - 例如:

function fractal:compute_Recursively(x,y, cx, cy, count)
    if count >= fractal.maxIterations or x^2 + y^2 >= 4 then
        return count
    else return self.compute_Recursively(x^2-y^2+cx, 2*x*y + cy, cx, cy, count+1)
    end
end

function formulae.Mandelbrot_Recursive(x, y, cx, cy, i)
    if i >= fractal.maxIterations or x^2 + y^2 >= 4 then
        return i
    else return formulae.Mandelbrot_R(x^2-y^2+cx, 2*x*y + cy, cx, cy, i+1)
    end
end
recursion lua fractals
1个回答
0
投票

以我的拙见,在这种情况下递归没有用处。由于您需要计算迭代次数,因此需要采取特殊措施(例如附加参数)来存储当前迭代计数。

但是,下面是代码,您可以通过注释掉其中之一来选择函数的递归或非递归变体。为了使其更美观,并希望获得更多积分,代码变得更加通用。它依赖于一个小型复数库。不使用带有方法的表格。

-- get complex.lua from https://codereview.stackexchange.com/questions/252982/complex-number-class-in-lua.
local complex = require 'complex'

--[[
Get the iteration, at which the recursive function exceeds the limit. Not recursive.

    @param function func -- the recursive function to check,
    @param number limit -- limit to exceed,
    @param number max_iterations -- maximum number of iterations,
    @return number -- iteration at which the limit is exceeded, but not more than max_iterations.
--]]
local function iteration (func, limit, max_iterations)
    local z, iteration = complex (0), 0
    while iteration < max_iterations and z:abs () <= limit do
        z, iteration = func (z), iteration + 1
    end
    return iteration
end

--[[
Get the iteration, at which the recursive function exceeds the limit. Recursive.

    @param function func -- the recursive function to check,
    @param number limit -- limit to exceed,
    @param number max_iterations -- maximum number of iterations,
    @param complex z -- current value in the series; 0 by default,
    @param number iteration -- the current iteration; 0 by default.
    @return number -- iteration at which the limit is exceeded, but not more than max_iterations.
--]]
local function iterationRecursive (func, limit, max_iterations, z, iteration)
    local z, iteration = z or complex (0), iteration or 0
    if iteration >= max_iterations or z:abs() > limit then
        return iteration
    end
    z, iteration = func (z), iteration + 1
    return iterationRecursive (func, limit, max_iterations, z, iteration)
end

--[[
    Generate f_c (z) = z^2 + c function for the given c.
    
    @param complex c
    @return function
--]]
local function makeMandelbrot (c)
    return function (z)
        return z ^ 2 + c
    end
end

local limit, max_iterations = 2, 100
local range = {-1, -0.5, 0, 0.5, 1}
for _, re in ipairs (range) do
    for _, im in ipairs (range) do
        local c = complex (re, im)
        local mandelbrot = makeMandelbrot (c)
        --local iter = iteration (mandelbrot, limit, max_iterations)
        local iter = iterationRecursive (mandelbrot, limit, max_iterations)
        print ('c = ' .. tostring (c) .. ':\t' .. tostring (iter) .. '  iterations')
    end
end
© www.soinside.com 2019 - 2024. All rights reserved.