首页 » Web前端 » php源码期数技巧_从Excel中的迭代计算到代码实现

php源码期数技巧_从Excel中的迭代计算到代码实现

访客 2024-12-09 0

扫一扫用手机浏览

文章目录 [+]

大略来说,便是让Excel在有公式循环引用时,通过不断重复打算来得出答案。

递归和迭代打算

1、递归:在编程中,递归是函数调用自身的过程,须要一个明确的结束条件,否则会无限循环,涌现Stack Overflow(堆栈溢出)

php源码期数技巧_从Excel中的迭代计算到代码实现

2、迭代打算:在Excel中,当公式涉及循环引用时,迭代打算类似于递归,Excel通过反复打算来办理这个问题。

php源码期数技巧_从Excel中的迭代计算到代码实现
(图片来自网络侵删)

假设你在单元格A1输入了公式:

A1 = A1 + 1

A1的结果是多少?如下图所示,常日Excel会通过提示,禁止循环引用的涌现。

开启迭代打算后,Excel则许可循环引用。

在Excel中,当涌现循环引用时,反复循环递归的打算,即为迭代打算。

迭代次数及迭代偏差,可以在Excel的设置中配置。
默认为1000 次,精度为0.001。

利用场景

在很多数学模型的打算中,没有特定的公式进行求解,而是须要一直的打算,反复逼近一个期望的结果。

运用处景

描述

运用实例

金融打算

处理贷款、投资等金融模型中须要逐步打算的公式

贷款偿还操持、投资回报率打算

工程打算

打算构造负载、应力等繁芜的工程模型

构造负载剖析、材料非线性应力打算

科学打算

办理物理学、化学等领域中繁芜的非线性方程

热传导模型、流体动力学仿照

优化问题

优化参数以实现目标,如最小化本钱或最大化利润

探求最佳原材料配比、优化生产流程

财务建模

预测公司利润、财务状况等,考虑不同的市场条件和变量

利润预测、财务方案

动态系统仿照

仿照随韶光变革的系统行为,如人口增长、资源花费等

人口增长模型、资源花费预测

业务和市场剖析

预测市场趋势和份额,剖析市场变革的影响

市场份额预测、发卖趋势剖析

C#示例1:梯度低落法1、新建项目

打开命令行(如Command Prompt或PowerShell)

dotnet new console -o GradientDescentAppcd GradientDescentApp2、更换Program.cs文件的内容

using System;classProgram{static void Main(){// 设置梯度低落法的参数double learningRate =0.01;// 学习率,决定每次更新的步长double initialGuess =10.0;// 初始预测值,梯度低落从这个值开始int maxIterations =1000;// 最大迭代次数,用于防止无限循环double tolerance =0.0001;// 收敛容忍度,当新值与旧值的差异小于这个值时,认为算法已收敛// 实行梯度低落法来找到目标函数的最小值double minValue =GradientDescent(learningRate, initialGuess, maxIterations, tolerance);// 输出优化后的最小值Console.WriteLine($"优化后的最小值: {minValue:F4}");}// 定义目标函数static double Function(double x){// 目标函数 x^2 + 4x + 4return x x +4 x +4;}// 打算目标函数的梯度static double Gradient(double x){// 目标函数的梯度(导数),对付 x^2 + 4x + 4,梯度是 2x + 4return 2 x +4;}// 实现梯度低落法static double GradientDescent(double learningRate, double initialGuess, int maxIterations, double tolerance){double x = initialGuess;// 初始化当前值为初始预测值int iteration =0;// 迭代计数器// 进行迭代while(iteration < maxIterations){// 打算当前值的梯度double grad =Gradient(x);// 更新当前值,利用学习率调度double xNew = x - learningRate grad;// 检讨是否知足收敛条件if(Math.Abs(xNew - x)< tolerance){// 如果新值与旧值的差异小于容忍度,返回目标函数在新值处的值return Function(xNew);}// 更新当前值为新值 x = xNew;// 增加迭代计数器 iteration++;}// 如果达到最大迭代次数仍未收敛,抛出非常throw new InvalidOperationException("达到最大迭代次数,未收敛");}}3、构建和运行项目

在命令行中,运行以下命令来构建项目和运行项目:

dotnet builddotnet run4、输出:

优化后的最小值: 0.0000

C#示例2:IRR打算

提到给孩子买的教诲金保险等金融工具,基本都会提到IRR这个词。

不懂这个,几十万保费可能白交了....

假设,某个教诲保险的情形是:每年交纳10万元,连交3年,之后第五年开始领取现金。
前两年每年领取5万元,第七年起每年领取2.24万元,直到第十五年,再在末了一次性取出7.48万元,保险任务结束。

我们看到打算出的内部收益率(IRR)只有1.89%,远低于余额宝的收益率,因此不是一个很好的选择。

IRR知识点

IRR是一种用于评估投资项目的潜在收益的指标,打算时常日须要解一个关于现金流量的非线性方程。

IRR是使得项目净现值(NPV, Net Present Value)即是零的贴现率。
公式如下:

个中:

(C_t)是第(t)年的现金流量(IRR)是内部收益率(t)是韶光期数代码

要在C#中实现 内部收益率(IRR, Internal Rate of Return)的打算,我们可以利用迭代方法,如Newton-Raphson方法。

迭代常日会提高近似值。

实现步骤

1、定义现金流量:创建一个数组来表示各期的现金流量。

2、实现IRR打算方法:利用迭代方法,如Newton-Raphson方法来逼近IRR值。

using System;classProgram{static void Main(){// 现金流量数据,数组索引代表年份double[] cashFlows ={-100000,-100000,-100000,0,0,50000,50000,22455,22455,22455,22455,22455,22455,22455,22455,74817};// 打算 IRRdouble irrValue =CalculateIRR(cashFlows);// 打印 IRR,格式化为百分比形式Console.WriteLine($"IRR: {irrValue 100:F2}%");}/// <summary>/// 打算内部收益率 (IRR)。
/// </summary>/// <param name="cashFlows">现金流量数组,个中现金流量的索引代表年份</param>/// <param name="maxIterations">最大迭代次数</param>/// <param name="tolerance">收敛容忍度,用于确定结果是否足够精确</param>/// <returns>打算得到的内部收益率</returns>static double CalculateIRR(double[] cashFlows, int maxIterations = 1000, double tolerance = 1e-6){double rate =0.1;// 初始预测的折现率为 10%// 进行最多 maxIterations 次迭代for(int i =0; i < maxIterations; i++){// 打算当前折现率下的净现值double npvValue =CalculateNPV(rate, cashFlows);// 打算净现值的导数double derivativeValue =CalculateDerivativeNPV(rate, cashFlows);// 如果导数靠近零,则避免除以零的问题if(Math.Abs(derivativeValue)< tolerance){break;}// 根据牛顿-拉夫森法更新折现率double newRate = rate - npvValue / derivativeValue;// 如果新的折现率与当前折现率足够靠近,则认为收敛if(Math.Abs(newRate - rate)< tolerance){return newRate;}// 更新折现率 rate = newRate;}// 如果未能在最大迭代次数内收敛,抛出非常thrownew Exception("IRR did not converge");}/// <summary>/// 打算净现值 (NPV)。
/// </summary>/// <param name="rate">折现率</param>/// <param name="cashFlows">现金流量数组</param>/// <returns>打算得到的净现值</returns>static double CalculateNPV(double rate, double[] cashFlows){double npv =0.0;// 打算所有现金流量的现值总和for(int i =0; i < cashFlows.Length; i++){ npv += cashFlows[i]/Math.Pow(1+ rate, i);}return npv;}/// <summary>/// 打算净现值的导数。
/// </summary>/// <param name="rate">折现率</param>/// <param name="cashFlows">现金流量数组</param>/// <returns>净现值的导数</returns>static double CalculateDerivativeNPV(double rate, double[] cashFlows){double derivative =0.0;// 打算净现值折半现率的导数for(int i =0; i < cashFlows.Length; i++){ derivative -= i cashFlows[i]/Math.Pow(1+ rate, i +1);}return derivative;}}

打算结果:和 Excel 里打算的值同等。

标签:

相关文章