-
一套图 搞懂“时间复杂度”
2019-06-04 13:12:15是我到目前为止所看到的关于时间复杂度介绍的最好的文章,简介 清晰 明了。 所以拿来po出来 仅供学习交流,如侵则删。 现已将此文收录至:《数据结构》C语言版 (清华严蔚敏考研版) 全书知识梳理 正文: ...写在前面:
这篇文章是在公众号: 程序员小灰 中发布的。是我到目前为止所看到的关于时间复杂度介绍的最好的文章,清晰明了。
所以拿来po出来 仅供学习交流,如侵则删。
现已将此文收录至: 《数据结构》C语言版 (清华严蔚敏考研版) 全书知识梳理
同类好文: 8种方法优雅地利用C++编程从1乘到20
正文:
时间复杂度的意义
究竟什么是时间复杂度呢?让我们来想象一个场景:某一天,小灰和大黄同时加入了一个公司......
一天过后,小灰和大黄各自交付了代码,两端代码实现的功能都差不多。大黄的代码运行一次要花100毫秒,内存占用5MB。小灰的代码运行一次要花100秒,内存占用500MB。于是......
由此可见,衡量代码的好坏,包括两个非常重要的指标:
1.运行时间;
2.占用空间。
基本操作执行次数
关于代码的基本操作执行次数,我们用四个生活中的场景,来做一下比喻:
场景1:给小灰一条长10寸的面包,小灰每3天吃掉1寸,那么吃掉整个面包需要几天?
答案自然是 3 X 10 = 30天。
如果面包的长度是 N 寸呢?
此时吃掉整个面包,需要 3 X n = 3n 天。
如果用一个函数来表达这个相对时间,可以记作 T(n) = 3n。
场景2:给小灰一条长16寸的面包,小灰每5天吃掉面包剩余长度的一半,第一次吃掉8寸,第二次吃掉4寸,第三次吃掉2寸......那么小灰把面包吃得只剩下1寸,需要多少天呢?
这个问题翻译一下,就是数字16不断地除以2,除几次以后的结果等于1?这里要涉及到数学当中的对数,以2位底,16的对数,可以简写为log16。
因此,把面包吃得只剩下1寸,需要 5 X log16 = 5 X 4 = 20 天。
如果面包的长度是 N 寸呢?
需要 5 X logn = 5logn天,记作 T(n) = 5logn。
场景3:给小灰一条长10寸的面包和一个鸡腿,小灰每2天吃掉一个鸡腿。那么小灰吃掉整个鸡腿需要多少天呢?
答案自然是2天。因为只说是吃掉鸡腿,和10寸的面包没有关系 。
如果面包的长度是 N 寸呢?
无论面包有多长,吃掉鸡腿的时间仍然是2天,记作 T(n) = 2。
场景4:给小灰一条长10寸的面包,小灰吃掉第一个一寸需要1天时间,吃掉第二个一寸需要2天时间,吃掉第三个一寸需要3天时间.....每多吃一寸,所花的时间也多一天。那么小灰吃掉整个面包需要多少天呢?
答案是从1累加到10的总和,也就是55天。
如果面包的长度是 N 寸呢?
此时吃掉整个面包,需要 1+2+3+......+ n-1 + n = (1+n)*n/2 = 0.5n^2 + 0.5n。
记作 T(n) = 0.5n^2 + 0.5n。
上面所讲的是吃东西所花费的相对时间,这一思想同样适用于对程序基本操作执行次数的统计。刚才的四个场景,分别对应了程序中最常见的四种执行方式:
场景1:T(n) = 3n,执行次数是线性的。
void eat1(int n){ for(int i=0; i<n; i++){; System.out.println("等待一天"); System.out.println("等待一天"); System.out.println("吃一寸面包"); } } vo
场景2:T(n) = 5logn,执行次数是对数的。
void eat2(int n){ for(int i=1; i<n; i*=2){ System.out.println("等待一天"); System.out.println("等待一天"); System.out.println("等待一天"); System.out.println("等待一天"); System.out.println("吃一半面包"); } }
场景3:T(n) = 2,执行次数是常量的。
void eat3(int n){ System.out.println("等待一天"); System.out.println("吃一个鸡腿"); }
场景4:T(n) = 0.5n^2 + 0.5n,执行次数是一个多项式。
void eat4(int n){ for(int i=0; i<n; i++){ for(int j=0; j<i; j++){ System.out.println("等待一天"); } System.out.println("吃一寸面包"); } }
渐进时间复杂度
有了基本操作执行次数的函数 T(n),是否就可以分析和比较一段代码的运行时间了呢?还是有一定的困难。
比如算法A的相对时间是T(n)= 100n,算法B的相对时间是T(n)= 5n^2,这两个到底谁的运行时间更长一些?这就要看n的取值了。
所以,这时候有了渐进时间复杂度(asymptotic time complexity)的概念,官方的定义如下:
若存在函数 f(n),使得当n趋近于无穷大时,T(n)/ f(n)的极限值为不等于零的常数,则称 f(n)是T(n)的同数量级函数。
记作 T(n)= O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
渐进时间复杂度用大写O来表示,所以也被称为大O表示法。
如何推导出时间复杂度呢?有如下几个原则:
-
如果运行时间是常数量级,用常数1表示;
-
只保留时间函数中的最高阶项;
-
如果最高阶项存在,则省去最高阶项前面的系数。
让我们回头看看刚才的四个场景。
场景1:
T(n) = 3n
最高阶项为3n,省去系数3,转化的时间复杂度为:
T(n) = O(n)
场景2:
T(n) = 5logn
最高阶项为5logn,省去系数5,转化的时间复杂度为:
T(n) = O(logn)
场景3:
T(n) = 2
只有常数量级,转化的时间复杂度为:
T(n) = O(1)
场景4:
T(n) = 0.5n^2 + 0.5n
最高阶项为0.5n^2,省去系数0.5,转化的时间复杂度为:
T(n) = O(n^2)
这四种时间复杂度究竟谁用时更长,谁节省时间呢?稍微思考一下就可以得出结论:
O(1)< O(logn)< O(n)< O(n^2)
在编程的世界中有着各种各样的算法,除了上述的四个场景,还有许多不同形式的时间复杂度,比如:
O(nlogn), O(n^3), O(m*n),O(2^n),O(n!)
今后遨游在代码的海洋里,我们会陆续遇到上述时间复杂度的算法。
时间复杂度的巨大差异
我们来举过一个栗子:
算法A的相对时间规模是T(n)= 100n,时间复杂度是O(n)
算法B的相对时间规模是T(n)= 5n^2,时间复杂度是O(n^2)
算法A运行在小灰家里的老旧电脑上,算法B运行在某台超级计算机上,运行速度是老旧电脑的100倍。
那么,随着输入规模 n 的增长,两种算法谁运行更快呢?
从表格中可以看出,当n的值很小的时候,算法A的运行用时要远大于算法B;当n的值达到1000左右,算法A和算法B的运行时间已经接近;当n的值越来越大,达到十万、百万时,算法A的优势开始显现,算法B则越来越慢,差距越来越明显。
这就是不同时间复杂度带来的差距。
如果感觉还不错,点个赞↗ 支持一下吧 ~
随后还会不定期更新同类型文章,欢迎订阅关注我的博客 ~
-
-
Java获取系统时间的四种方法
2016-11-09 18:07:081、Date day=new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(df.format(day));...通过Date类来获取当前时间 2、SimpleDateFormat df = new SimpleDateF1、Date day=new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(day));
通过Date类来获取当前时间
2、SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(df.format(System.currentTimeMillis()));
通过System类中的currentTimeMillis方法来获取当前时间
3、Calendar c = Calendar.getInstance();//可以对每个时间域单独修改
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int date = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year + "/" + month + "/" + date + " " +hour + ":" +minute + ":" + second);
通过Calendar类来获取当前时间
4、 Date date = new Date();
String year = String.format("%tY", date);
String month = String.format("%tB", date);
String day = String.format("%te", date);
System.out.println("今天是:"+year+"-"+month+"-"+day);
通过Date类来获取当前时间
总结:设置时间格式可通过调用SimpleDateFormat类进行设置和通过String中的format方法来设置。可通过Date类和System中的currentTimeMillis来获取!
点关注,不迷路
文章每周持续更新,可以微信搜索「 十分钟学编程 」第一时间阅读和催更,如果这个文章写得还不错,觉得有点东西的话 ~求点赞👍 求关注❤️ 求分享❤️
各位的支持和认可,就是我创作的最大动力,我们下篇文章见! -
时间序列分析和预测(含实例及代码)
2018-09-17 21:37:34研究时间序列主要目的:进行预测,根据已有的时间序列数据预测未来的变化。 时间序列预测关键:确定已有的时间序列的变化模式,并假定这种模式会延续到未来。 时间序列预测法的基本特点 假设事物发展趋势会...导论
研究时间序列主要目的:进行预测,根据已有的时间序列数据预测未来的变化。
时间序列预测关键:确定已有的时间序列的变化模式,并假定这种模式会延续到未来。
时间序列预测法的基本特点 - 假设事物发展趋势会延伸到未来
- 预测所依据的数据具有不规则性
- 不考虑事物发展之间的因果关系
时间序列数据用于描述现象随时间发展变化的特征。
时间序列分析就其发展历史阶段和所使用的统计分析方法看:传统的时间序列分析和现代时间序列分析。
一、时间序列及其分解
时间序列(time series)是同一现象在不同时间上的相继观察值排列而成的序列。根据观察时间的不同,时间序列中的时间可以是可以是年份、季度、月份或其他任何时间形式。
时间序列:
(1)平稳序列(stationary series)
是基本上不存在趋势的序列,序列中的各观察值基本上在某个固定的水平上波动,在不同时间段波动程度不同,但不存在某种规律,随机波动
(2)非平稳序列(non-stationary series)
是包含趋势、季节性或周期性的序列,只含有其中一种成分,也可能是几种成分的组合。可分为:有趋势序列、有趋势和季节性序列、几种成分混合而成的复合型序列。
趋势(trend):时间序列在长时期内呈现出来的某种持续上升或持续下降的变动,也称长期趋势。时间序列中的趋势可以是线性和非线性。
季节性(seasonality):季节变动(seasonal fluctuation),是时间序列在一年内重复出现的周期波动。销售旺季,销售淡季,旅游旺季、旅游淡季,因季节不同而发生变化。季节,不仅指一年中的四季,其实是指任何一种周期性的变化。含有季节成分的序列可能含有趋势,也可能不含有趋势。
周期性(cyclicity):循环波动(cyclical fluctuation),是时间序列中呈现出来的围绕长期趋势的一种波浪形或振荡式波动。周期性是由商业和经济活动引起的,不同于趋势变动,不是朝着单一方向的持续运动,而是涨落相间的交替波动;不同于季节变动,季节变动有比较固定的规律,且变动周期大多为一年,循环波动则无固定规律,变动周期多在一年以上,且周期长短不一。周期性通常是由经济环境的变化引起。
除此之外,还有偶然性因素对时间序列产生影响,致使时间序列呈现出某种随机波动。时间序列除去趋势、周期性和季节性后的偶然性波动,称为随机性(random),也称不规则波动(irregular variations)。
时间序列的成分可分为4种:趋势(T)、季节性或季节变动(S)、周期性或循环波动(C)、随机性或不规则波动(I)。传统时间序列分析的一项主要内容就是把这些成分从时间序列中分离出来,并将它们之间的关系用一定的数学关系式予以表达,而后分别进行分析。按4种成分对时间序列的影响方式不同,时间序列可分解为多种模型:加法模型(additive model),乘法模型(multiplicative model)。乘法模型:
二、描述性分析
1、图形描述
2、增长率分析
是对现象在不同时间的变化状况所做的描述。由于对比的基期不同,增长率有不同的计算方法。
(1)增长率(growth rate):增长速度,是时间序列中报告期观察值与基期观察值之比减1后的结果,用%表示。由于对比的基期不同,可分为环比增长率和定基增长率。
环比增长率:是报告期观察值与前一时期观察值之比减1,说明现象逐期增长变化的程度;
定基增长率是报告期观察值与某一固定时期观察值之比减1,说明现象在整个观察期内总的增长变化程度。
设增长率为G: 环比增长率 :
定基增长率 :
(2)平均增长率(average rate of increase):平均增长速度,是时间序列中逐期环比值(环比发展速度)的几何平均数减1的结果:
n:环比值的个数
(3)增长率分析中应注意的问题
i: 当时间序列中的观察出现0或负数时,不宜计算增长率。这种序列计算增长率,要么不符合数学公理,要么无法解释其实际意义。可用绝对数进行分析。
ii: 有些情况下,不能单纯就增长率论增长率,注意增长率与绝对水平结合起来。增长率是一个相对值,与对比的基数值的大小有关。这种情况,计算增长1%的绝对值来克服增长率分析的局限性:
增长1%的绝对值表示增长率每增长一个百分点而增加的绝对数量:
增长1%的绝对值=前期水平/100
三、时间序列预测的程序
时间序列分析的主要目的之一是根据已有的历史数据对未来进行预测。时间序列含有不同的成分,如趋势、季节性、周期性和随机性。对于一个具体的时间序列,它可能含有一种成分,也可能同时含有几种成分,含有不同成分的时间序列所用的预测方法是不同的。预测步骤:
第一步:确定时间序列所包含的成分,确定时间序列的类型
第二步:找出适合此类时间序列的预测方法
第三步:对可能的预测方法进行评估,以确定最佳预测方案
第四步:利用最佳预测方案进行预测
1、确定时间序列成分
(1)确定趋势成分
确定趋势成分是否存在,可绘制时间序列的线图,看时间序列是否存在趋势,以及存在趋势是线性还是非线性。
利用回归分析拟合一条趋势线,对回归系数进行显著性检验。回归系数显著,可得出线性趋势显著的结论。
(2)确定季节成分
确定季节成分是否存在,至少需要两年数据,且数据需要按季度、月份、周或天来记录。可绘图,年度折叠时间序列图(folded annual time series plot),需要将每年的数据分开画在图上,横轴只有一年的长度,每年的数据分别对应纵轴。如果时间序列只存在季节成分,年度折叠时间序列图中的折线将会有交叉;如果时间序列既含有季节成分又含有趋势,则年度折叠时间序列图中的折线将不会有交叉,若趋势上升,后面年度的折线将会高于前面年度的折线,若下降,则后面年度的折线将会低于前面年度的折线。
2、选择预测方法
确定时间序列类型后,选择适当的预测方法。利用时间数据进行预测,通常假定过去的变化趋势会延续到未来,这样就可以根据过去已有的形态或模式进行预测。时间序列的预测方法:传统方法:简单平均法、移动平均法、指数平滑法等,现代方法:Box-Jenkins 的自回归模型(ARMA)。
一般来说,任何时间序列都会有不规则成分存在,在商务和管理数据中通常不考虑周期性,只考虑趋势成分和季节成分。
不含趋势和季节成分的时间序列,即平稳时间序列只含随机成分,只要通过平滑可消除随机波动。因此,这类预测方法也称平滑预测方法。
3、预测方法的评估
在选择某种特定的方法进行预测时,需要评价该方法的预测效果或准确性。评价方法是找出预测值与实际值的差距,即预测误差。最优的预测方法就是预测误差达到最小的方法。
预测误差计算方法:平均误差,平均绝对误差、均方误差、平均百分比误差、平均绝对百分比误差。方法的选择取决于预测者的目标、对方法的熟悉程度。
(1)平均误差(mean error):Y:观测值,F:预测值,n预测值个数
由于预测误差的数值可能有正有负,求和的结果就会相互抵消,这种情况下,平均误差可能会低估误差。
(2)平均绝对误差(mean absolute deviation)是将预测误差取绝对值后计算的平均无擦,MAD:
平均绝对误差可避免误差相互抵消的问题,因而可以准确反映实际预测误差的大小。
(3)均方误差(mean square error):通过平方消去误差的正负号后计算的平均误差,MSE:
(4)平均百分比误差和平均绝对百分比误差
ME,MAD,MSE的大小受时间序列数据的水平和计量单位的影响,有时并不能真正反映预测模型的好坏,只有在比较不同模型对同一数据的预测时才有意义。平均百分比误差(mean percentage error,MPE)和平均绝对百分比误差(mean absolute percentage error,MAPE)则不同,它们消除了时间序列数据的水平和计量单位的影响,是反映误差大小的相对值。
4、平稳序列的预测
平稳时间序列只含有随机成分,预测方法:简单平均法、移动平均法、指数平滑法。主要通过对时间序列进行平滑以消除随机波动,又称平滑法。平滑法可用于对时间序列进行短期预测,也可对时间序列进行平滑以描述序列的趋势(线性趋势和非线性趋势)。
(1)简单平均法:根据已有的t期观察值通过简单平均法来预测下一期的数值。设时间序列已有的t期观察值为
,则t+1期的预测值
为:
到了t+1期后,有了t+1期的实际值,t+1期的预测误差
为:
=
t+2期预测值:
简单平均法适合对较为平稳的时间序列进行预测,即当时间序列没有趋势时,用该方法比较好。但如果时间序列有趋势或季节成分,该方法的预测则不够准确。简单平均法将远期的数值和近期的数值看作对未来同等重要。从预测角度,近期的数值比远期的数值对未来有更大的作用,因此简单平均法预测的结果不够准确。
(2)移动平均法(moving average):通过对时间序列逐期递移求得平均数作为预测值的一种预测方法,有简单移动平均法(simple moving average)和加权移动平均法(weighted moving average).
简单移动平均将最近k期数据加以平均,作为下一期的预测值。设移动平均间隔为k(1<k<t),则t期的移动平均值为:
是对时间序列的平滑结果,通过这些平滑值可描述出时间序列的变化形态或趋势。也可以用来预测。
t+1期的简单移动平均预测值为:
t+2期的简单移动平均预测值为:
移动平均法只使用最近k期的数据,在每次计算移动平均值时,移动的间隔都为k,也适合对较为平稳的时间序列进行预测。应用关键是确定合理的移动平均间隔k。对于同一个时间序列,采用不同的移动间隔,预测的准确性是不同的。可通过试验的方法,选择一个使均方误差达到最小的移动间隔。移动间隔小,能快速反映变化,但不能反映变化趋势;移动间隔大,能反映变化趋势,但预测值带有明显的滞后偏差。
移动平均法的基本思想:移动平均可以消除或减少时间序列数据受偶然性因素干扰而产生的随机变动影响,适合短期预测。
(3)指数平滑法(exponential smoothing)是通过对过去的观察值加权平均进行预测,使t+1期的预测值等t期的实际观察值与t期的预测值的加权的平均值。指数平滑法是从移动平均法发展而来,是一种改良的加权平均法,在不舍弃历史数据的前提下,对离预测期较近的历史数据给予较大权数,权数由近到远按指数规律递减,因此称指数平滑。指数平滑有一次指数平滑法、二次指数平滑法、三次指数平滑法等。
一次指数平滑法也称单一指数平滑法(single exponential smoothing),只有一个平滑系数,且观察值离预测时期越久远,权数变得越小。一次指数平滑是将一段时期的预测值与观察值的线性组合作为t+1时期的预测值,预测模型为:
:平滑系数(
)
t+1期的数据是t期的实际观察值与t期的预测值的加权平均。1期的预测值=1期的观察值
2期预测值:
3期预测值:
4期预测值:
对指数平滑法的预测精度,用均方误差来=衡量:
是t期的预测值
加上用
调整的t期预测误差(
)。
使用指数平滑法时, 关键问题是确定一个合适的平滑系数
,不同的
对预测结果产生不同的影响。
=0,预测值仅仅是重复上一期的预测结果;
=1,预测值就是上一期的实际值;
越接近1,模型对时间序列变化的反应就越及时,因为它给当前的实际值赋予了比预测值更大的权数;
越接近0,给当前的预测值赋予了更大的权数,模型对时间序列变化的反应就越慢。
当时间序列有较大随机波动时,选较大
,以便能很快跟上近期的变化;当时间序列比较平稳时,选较小
。
实际应用中,需考虑预测误差,用均方误差衡量预测误差大小。确定
时,可选择几个
进行预测,然后找出预测误差最小的作为最后的
值。
与移动平均法一样,一次指数平滑法可用于对时间序列进行修匀,以消除随机波动,找出序列的变化趋势。
用一次指数平滑法进行预测时,一般
取值不大于0.5,若大于0.5,才能接近实际值,说明序列有某种趋势或波动过大。
阻尼系数
,阻尼系数越小,近期实际值对预测结果的影响越大,反之,越小。阻尼系数是根据时间序列的变化特性来选取。
5、趋势型序列的预测
时间序列的趋势可分为线性趋势和非线性趋势,若这种趋势能够延续到未来,就可利用趋势进行外推预测。有趋势序列的预测方法主要有线性趋势预测、非线性趋势预测和自回归模型预测。
(1) 线性趋势预测
线性趋势(linear trend)是指现象随着时间的推移而呈现稳定增长或下降的线性变化规律。
趋势方程:
:时间序列
的预测值;
是趋势线斜率,表示时间t 变动一个单位,观察值的平均变动数量
(2) 非线性趋势预测
序列中的趋势通常可认为是由于某种固定因素作用同一方向所形成的。若这种因素随时间推移按线性变化,则可对时间序列拟合趋势直线;若呈现出某种非线性趋势(non-linear trend),则需要拟合适当的趋势曲线。
i: 指数曲线(exponential curve):用于描述以几何级数递增或递减的现象,即时间序列的观察值
按指数规律变化,或者时间序列的逐期观察值按一定的增长率增长或衰减。一般的自然增长及大多数经济序列都有指数变化趋势。
趋势方程:
,
为待定系数
若
>1,则增长率随着时间t的增加而增加;若
<1,则增长率随着时间t的增加而降低;若
>0,
<1,则预测值
逐渐降低以到0为极限。
为确定
,
,可采用线性化手段将其化为对数直线形式,两端取对数:
根据最小二乘原理,按直线形式的常数确定方法求得
,
,求出
,
后,再取其反对数,即可得到
,
。
ii: 多阶曲线:
有些现象变化形态复杂,不是按照某种固定的形态变化,而是有升有降,在变化过程中可能有几个拐点。这时就需要拟合多项式函数。当只有一个拐点时,可拟合二项曲线,即抛物线;当有两个拐点时,需要拟合三阶曲线;有k-1个拐点时,需要拟合k阶曲线。
6、复合型序列的分解预测
复合型序列是指含有趋势、季节、周期和随机成分的序列。对这类序列的预测方法是将时间序列的各个因素依次分解出来,然后进行预测。由于周期成分的分析需要有多年的数据,实际中很难得到多年的数据,因此采用的分解模型为:
预测方法有:季节性多元回归模型、季节自回归模型和时间序列分解法预测。
分解法预测步骤:
第一步:确定并分离季节成分。计算季节指数,以确定时间序列中的季节成分。然后将季节成分从时间序列中分离出去,即用每一个时间序列观察值除以相应的季节指数,以消除季节性。
第二步:建立预测模型并进行预测。对消除了季节成分的时间序列建立适当的预测模型,并根据这一模型进行预测。
第三步:计算最后的预测值。用预测值乘以相应的季节指数,得到最终的预测值。
(1)确定并分离季节成分
季节性因素分析是通过季节指数来表示各年的季节成分,以此描述各年的季节变动模式。
i: 计算季节指数(seasonal index)
季节指数刻画了序列在一个年度内各月或各季度的典型季节特征。在乘法模型中,季节指数以其平均数等于100%为条件而构成的,反映了某一月份或季度的数值占全年平均值的大小。若现象的发展没有季节变动,则各期的季节指数应等于100%;若某一月份或季度有明显的季节变化,则各期的季节指数应大于或小于100%。因此,季节变动的程度是根据各季节指数与其平均数(100%)的偏差程度来测定的。
季节指数计算方法较多,移动平均趋势剔除法步骤:
第一步:计算移动平均值(若是季节数据,采用4项移动平均,月份数据则采用12项移动平均),并对其结果进行中心化处理,即将移动平均的结果再进行一次二项移动平均,即得出中心化移动平均值(CMA)。
第二步:计算移动平均的比值,即季节比率,即将序列的各观察值除以相应的中心化移动平均值,然后计算出各比值的季度或月份平均值。
第三步:季节指数调整。由于各季节指数的平均数应应等于1或100%,若根据第二步计算的季节比率的平均值不等于1,则需要进行调整。具体方法:将第二步计算的每个季节比率的平均值除以它们的总平均值。
ii: 分离季节成分
计算出季节指数后,可将各实际观察值分别除以相应的季节指数,将季节成分从时间序列中分离出去:
结果即为季节成分分离后的序列,反映了在没有季节因素影响下时间序列的变化形态。
iii: 建立预测模型并进行预测
7、时序案例分析
https://blog.csdn.net/mengjizhiyou/article/details/104765862
参考:贾俊平《统计学》第六版
《统计学》pdf及课后答案:链接: https://pan.baidu.com/s/1dZPW0smz2cO-67zfn1BFyQ 提取码: ktxq
-
Java Calendar 日历类的时间操作 Timestamp Date Calendar 相互转换
2013-07-30 17:53:36Java Calendar 日历类的时间操作,这也许是 Java 环境下创建和管理日历及操作时间最简单的一个方案了,示范代码也很简单。 演示了获取时间,日期时间的累加和累减,以及日期时间的比较。 原文地址:blog.csdn.net/...Java Calendar 日历类的时间操作,这也许是 Java 环境下创建和管理日历及操作时间最简单的一个方案了,示范代码也很简单。
演示了获取时间,日期时间的累加和累减,以及日期时间的比较。
原文地址:blog.csdn.net/joyous/article/details/9630893
注意事项:
Calendar 的 month 从 0 开始,也就是全年 12 个月由 0 ~ 11 进行表示。
而 Calendar.DAY_OF_WEEK 定义值如下,每周从 SUNDAY 开始,从 1 ~ 7:
Calendar.SUNDAY = 1
Calendar.MONDAY = 2
Calendar.TUESDAY = 3
Calendar.WEDNESDAY = 4
Calendar.THURSDAY = 5
Calendar.FRIDAY = 6
Calendar.SATURDAY = 7SimpleDateFormat 的格式定义
Letter Date or Time Component Presentation Examples G
Era designator Text AD
y
Year Year 1996
;96
Y
Week year Year 2009
;09
M
Month in year (context sensitive) Month July
;Jul
;07
L
Month in year (standalone form) Month July
;Jul
;07
w
Week in year Number 27
W
Week in month Number 2
D
Day in year Number 189
d
Day in month Number 10
F
Day of week in month Number 2
E
Day name in week Text Tuesday
;Tue
u
Day number of week (1 = Monday, ..., 7 = Sunday) Number 1
a
Am/pm marker Text PM
H
Hour in day (0-23) Number 0
k
Hour in day (1-24) Number 24
K
Hour in am/pm (0-11) Number 0
h
Hour in am/pm (1-12) Number 12
m
Minute in hour Number 30
s
Second in minute Number 55
S
Millisecond Number 978
z
Time zone General time zone Pacific Standard Time
;PST
;GMT-08:00
Z
Time zone RFC 822 time zone -0800
X
Time zone ISO 8601 time zone -08
;-0800
;-08:00
Java Calendar 演示代码如下:
package demo; import java.util.Date; import java.text.SimpleDateFormat; import java.text.DateFormat; import java.text.ParseException; import java.util.Calendar; public class Test { public Test() { } public static void main(String[] args) { // 字符串转换日期格式 // DateFormat fmtDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 接收传入参数 // String strDate = args[1]; // 得到日期格式对象 // Date date = fmtDateTime.parse(strDate); // 完整显示今天日期时间 String str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(new Date()); System.out.println(str); // 创建 Calendar 对象 Calendar calendar = Calendar.getInstance(); try { // 对 calendar 设置时间的方法 // 设置传入的时间格式 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-M-d H:m:s"); // 指定一个日期 Date date = dateFormat.parse("2013-6-1 13:24:16"); // 对 calendar 设置为 date 所定的日期 calendar.setTime(date); // 按特定格式显示刚设置的时间 str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(calendar.getTime()); System.out.println(str); } catch (ParseException e) { e.printStackTrace(); } // 或者另一種設置 calendar 方式 // 分別爲 year, month, date, hourOfDay, minute, second calendar = Calendar.getInstance(); calendar.set(2013, 1, 2, 17, 35, 44); str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(calendar.getTime()); System.out.println(str); // Calendar 取得当前时间的方法 // 初始化 (重置) Calendar 对象 calendar = Calendar.getInstance(); // 或者用 Date 来初始化 Calendar 对象 calendar.setTime(new Date()); // setTime 类似上面一行 // Date date = new Date(); // calendar.setTime(date); str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")).format(calendar.getTime()); System.out.println(str); // 显示年份 int year = calendar.get(Calendar.YEAR); System.out.println("year is = " + String.valueOf(year)); // 显示月份 (从0开始, 实际显示要加一) int month = calendar.get(Calendar.MONTH); System.out.println("nth is = " + (month + 1)); // 本周几 int week = calendar.get(Calendar.DAY_OF_WEEK); System.out.println("week is = " + week); // 今年的第 N 天 int DAY_OF_YEAR = calendar.get(Calendar.DAY_OF_YEAR); System.out.println("DAY_OF_YEAR is = " + DAY_OF_YEAR); // 本月第 N 天 int DAY_OF_MONTH = calendar.get(Calendar.DAY_OF_MONTH); System.out.println("DAY_OF_MONTH = " + String.valueOf(DAY_OF_MONTH)); // 3小时以后 calendar.add(Calendar.HOUR_OF_DAY, 3); int HOUR_OF_DAY = calendar.get(Calendar.HOUR_OF_DAY); System.out.println("HOUR_OF_DAY + 3 = " + HOUR_OF_DAY); // 当前分钟数 int MINUTE = calendar.get(Calendar.MINUTE); System.out.println("MINUTE = " + MINUTE); // 15 分钟以后 calendar.add(Calendar.MINUTE, 15); MINUTE = calendar.get(Calendar.MINUTE); System.out.println("MINUTE + 15 = " + MINUTE); // 30分钟前 calendar.add(Calendar.MINUTE, -30); MINUTE = calendar.get(Calendar.MINUTE); System.out.println("MINUTE - 30 = " + MINUTE); // 7天前 calendar.add(Calendar.DAY_OF_YEAR, -7); // 显示当月 x 号 int day_of_month = calendar.get(Calendar.DAY_OF_MONTH); System.out.println("day_of_month -7 = " + day_of_month); // 格式化显示 str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime()); System.out.println(str); // 重置 Calendar 显示当前时间 calendar.setTime(new Date()); str = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS")).format(calendar.getTime()); System.out.println(str); // 创建一个 Calendar 用于比较时间 Calendar calendarNew = Calendar.getInstance(); // 设定为 5 小时以前,后者大,显示 -1 calendarNew.add(Calendar.HOUR, -5); System.out.println("时间比较:" + calendarNew.compareTo(calendar)); // 设定7小时以后,前者大,显示 1 calendarNew.add(Calendar.HOUR, +7); System.out.println("时间比较:" + calendarNew.compareTo(calendar)); // 退回 2 小时,时间相同,显示 0 calendarNew.add(Calendar.HOUR, -2); System.out.println("时间比较:" + calendarNew.compareTo(calendar)); } }
运行结果
2013-06-07 23:27:34:195 2013-06-01 13:24:16:000 2013-02-02 17:35:44:197 2013-06-07 23:27:34:197 year is = 2013 nth is = 6 week is = 6 DAY_OF_YEAR is = 158 DAY_OF_MONTH = 7 HOUR_OF_DAY + 3 = 2 MINUTE = 27 MINUTE + 15 = 42 MINUTE - 30 = 12 2013-06-08 02:12:34:197 2013-06-07 23:27:34:199 时间比较:-1 时间比较:1 时间比较:0
要计算时间差,可用 Calendar.getTimeInMillis() 取得两个时间的微秒级的时间差,再加以换算即可,比如获得相差天数,代码如下:
// 得微秒级时间差 long val = calendarEnd.getTimeInMillis() - calendarBegin.getTimeInMillis(); // 换算后得到天数 long day = val / (1000 * 60 * 60 * 24);
其他与 date 相关的类型转换代码如下。
Timestamp 类型转换为 Date 类型:
Timestamp stamp = new Timestamp(System.currentTimeMillis()); Date date = new Date(stamp.getTime()); System.out.println(date);
Timestamp 类型转换为 Calendar 类型:
// 获取 Timestamp 类型时间 Timestamp timestamp = new Timestamp(System.currentTimeMillis()); // 转换为 Calendar 类型,SUN 也推荐用 Calendar 处理时间信息 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timestamp.getTime());
Date 类型转换为 Calendar 类型:
// Date 向 Calendar 赋值 calendar.setTime(date);
Calendar 类型转换为 Timestamp 类型:
// 创建 Calendar 对象,也同时获取了当前时间 Calendar calendar = Calendar.getInstance(); // 转换为 Timestamp 类型对象 Timestamp timestamp = new Timestamp(calendar.getTimeInMillis()); System.out.println(timestamp);
Calendar 类型转换为 Date 类型:
// Calendar 对象类型转换为 Date 对象类型 Calendar calendar = Calendar.getInstance(); java.util.Date date = calendar.getTime(); System.out.println(date);
StringDate 转换为 Date 或者 Timestamp
/* 将字符串日期或者日期时间转换为 timestamp 格式 */ try { // 一个字符串日期 String strDate = "2020-01-31"; // 设置传入格式 // yyyy-MM-dd 或者完整的 yyyy-MM-dd HH:mm:ss DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = dateFormat.parse(strDate); // 创建 Calendar 用于处理 date 对象 Calendar calendar = Calendar.getInstance(); calendar.setTime(date); // 由 calendar 对象生成 timestamp Timestamp timestamp = new Timestamp(calendar.getTimeInMillis()); System.out.printf(timestamp); } catch (Exception e) { e.printStackTrace(); }
原文地址:blog.csdn.net/joyous/article/details/9630893
https://blog.inull.net
Q群讨论 236201801 -
java学习-获取当前毫秒数,毫秒转时间,时间计算,时间转毫秒,时间相关
2018-05-31 09:51:37时间有关 +1s 1、获取当前毫秒数 long t1=System.currentTimeMillis(); 2、毫秒数转换为时间 Date date2=new Date(); date2.setTime(t1); System.err.println(date2); 3、时间格式化 SimpleDateFormat ... -
java如何获取当前日期和时间
2019-06-12 18:11:36本篇博客主要总结java里面关于获取当前时间的一些方法 System.currentTimeMillis() 获取标准时间可以通过System.currentTimeMillis()方法获取,此方法不受时区影响,得到的结果是时间戳格式的。例如: ... -
Java时间处理(UTC时间和本地时间转换)
2017-06-22 20:25:21UTC时间和本地时间两者之间的转换 -
查看系统时间和硬件时间
2019-03-22 09:52:20硬件时间 硬件时钟是存储在主板上CMOS里的时间即BIOS时间,关机后该时钟依然运行,主板的电池为它供电。对应于嵌入式设备有一个RTC模块。硬件时钟即RTC时钟。信息比较少没时区、夏令时的概念。 系统时间 系统... -
微信小程序----日期时间选择器(自定义精确到分秒或时段)(MUI日期时间)
2017-12-28 13:52:40DEMO下载 效果图 实现原理 利用微信小程序的picker组件的多列选择器实现! WXML view class=&quot;tui-picker-content&...时间选择器(选择时分)view&gt; pi -
完成时间,周转时间,平均周转时间以及带权周转时间和平均带权周转时间
2017-06-21 13:33:43首先我们必须明确:FCFS和SJF两种调度算法,只有在进程的完成时间计算上有一些区别,其他时间(周转时间等)的计算都是相同的。 周转时间 周转时间=完成时间-到达时间 带权周转时间=周转时间/服务时间(除法运算... -
算法的时间与空间复杂度(一看就懂)
2018-11-21 11:17:45对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。 那么我们应该如何去衡量不同算法之间的优劣呢? 主要还是从算法所占用的「时间」和「空间」两个维度... -
mysql获取当前时间
2018-08-26 16:26:551. current_timestamp 2. current_time 3.current_data 4. now() 5. curdate() ...将当前时间插入数据库 insert into t_login(user_id,login_time) values (1,CURRENT_TIMESTAMP); ... -
JAVA实现UTC时间转换成北京时间
2017-11-27 14:17:10之前有一篇关于将UTC时间转换成北京时间的python文章(传送门),这次需要用到java版的,本以为这种小工具网上会很多,但是在网上搜了一圈之后发现都不尽人意。UTC就是世界标准时间,与北京时间相差八个时区(相关... -
java8 LocalTime DateTimeFormatter 时间加秒 时间间隔 时间加几秒
2019-09-20 15:59:30java8 LocalTime DateTimeFormatter 时间加秒 时间间隔 时间加几秒 import java.time.LocalTime; import java.time.format.DateTimeFormatter; public class TestZD { public static String ... -
redis的过期时间设置和过期删除机制
2018-08-08 10:47:07一:设置过期时间 redis有四种命令可以用于设置键的生存时间和过期时间: EXPIRE <KEY> <TTL> : 将键的生存时间设为 ttl 秒 PEXPIRE <KEY> <TTL> :将... -
MySQL中日期时间类型与格式化
2016-12-01 11:09:12Mysql中常用的几种时间类型有:date、datetime、time、year、timestamp; Datetime : 时间日期型,格式是YYYY-mm-dd HH:ii:ss,表示的范围是从1000到9999。但是有零值,0000-00-00 00:00:00;Date:日期,就是... -
日期时间规范
2020-06-20 18:17:57日期时间 【强制】日期格式化时,传入 pattern 中表示年份统一使用小写的 y。 说明:日期格式化时,yyyy 表示当天所在的年,而大写的 YYYY 代表是 week in which year(JDK7 之后 引入的概念),意思是当天所在的周... -
UTC(世界标准时间)/GMT(格林威治时间)/CST(北京时间)
2019-07-05 11:29:03关于时间格式 2016-08-9T10:01:54.123Z 20160809100154.123Z 处理方法 今天遇到了一个奇怪的时间格式 如以下格式,下面两种时间格式所表示的时间是同一个时间,这个不难理解 //UTC时间,世界标准时间 2016-08-9T10:... -
StringRedisTemplate/RedisTemplate设置过期时间
2019-06-11 17:00:13//向redis里存入数据和设置缓存时间 stringRedisTemplate.opsForValue().set("baike", "100", 60 * 10, TimeUnit.SECONDS); //val做-1操作 stringRedisTemplate.boundValueOps("baike").increment(-1); //根据key... -
时间序列的7种预测模型
2018-12-23 20:02:00时间序列问题比较常见,比如股市,工业生产指标等。 1 朴素估计 使用最后一个时间点的值估测后面一段时间段的值。 2 简单平均 4 滑动窗平均 使用之前一定大小时间段的平均值作为这个时间点的值。 ... -
时间序列预测算法总结
2018-10-18 10:30:48时间序列算法 time series data mining 主要包括decompose(分析数据的各个成分,例如趋势,周期性),prediction(预测未来的值),classification(对有序数据序列的feature提取与分类),clustering(相似数列... -
localStorage设置过期时间
2019-01-30 15:02:36众所周知,前端三大缓存,cookie,sessionStorage,localStorage,cookie空间太小,一旦大了,会消耗流量,知识和存一些登录会话信息,而sessionStorage的过期时间就是关闭浏览器,是个临时会话窗口,但是,最近这个... -
Docker 修改容器时间和宿主机时间一致(标准北京时间)
2020-05-15 17:56:54# 查看时间配置文件 ls/usr/share/zoneinfo/Asia/Shanghai ls/etc/timezone # 如果有显示,直接将 timezone 文件替换 为 Shanghai 并重命名,如需要记得备份 timezone cp /usr/share/zoneinfo/Asia/Shanghai /... -
[Python3]显示当前时间、计算时间差以及时间加减法
2019-06-05 20:14:10在使用Python写程序时,经常需要输出系统的当前时间以及计算两个时间之间的差值,或者将当前时间加减一定时间(天数、小时、分钟、秒)来得到新的时间,这篇文章就系统的对这些进行总结。 -
周转时间,平均周转时间,带权周转时间
2016-11-17 14:07:27周转时间=作业完成时间−作业提交时间周转时间 = 作业完成时间 - 作业提交时间特别注意作业提交时间不是作业进内存的时间,而是发出请求,提交就开始计时,如果无法安排进内存,那么就等待,等待的这部分时间也要... -
关于redis.Hash如何设置过期时间,时间不过期
2018-11-02 17:37:22关于redis.opsForHash时间不过期,如何设置过期时间 首先看opsForHash中的put方法 Redis.opsForHash.put(key,hashkey,value); 我们平时设置过期时间用的expire方法设置的是hashkey的过期时间,为什么要用redis,... -
递归时间复杂度分析 —— 斐波那契数列
2020-12-20 11:35:54对斐波那契数列递归求解的时间复杂度分析 -
AOE网活动的最早、最迟发生时间及关键路径问题
2018-05-22 18:10:12上个学期学数据结构的时候有学到,这学期的离散数学又要考。。复习复习 ...在AOV网的边上加上权值表示完成该活动所需的时间,则称这样的AOV网为AOE(Activity On Edge)网,如图: 如何求AOE网... -
python 获取域名到期时间
2020-12-25 17:31:42**需求:**我要查询百度域名的到期时间或者开始时间 **思路分析:**如果在linux系统中直接使用下面命令即可: echo | openssl s_client -servername www.baidu.com -connect www.baidu.com:443 2>/dev/null | ... -
UTC时间、CST时间和GMT时间
2019-06-03 21:06:361、UTC时间是l零时区的时间。(时间协调时间) CST时间是四大时区的时间,(中央标准时间) 分别是: Central Standard Time (USA) UT-6:00(美国cst时间:零区时减6个小时) Central Standard Time...
-
nodejs V14.15 32位下载
-
第3章 入门程序、常量、变量
-
苹果iphone6 puls原理图、IPhone 6原厂电路原理图纸
-
保存Windows聚焦锁屏壁纸
-
Object类
-
C++ 21种面向对象设计模式源代码.zip
-
visual c++ HGE游戏引擎 坦克大战,子弹是粒子效果特别炫.zip
-
【2021】UI自动化测试框架(Selenium3)
-
Selenium3分布式与虚拟化
-
python办公自动化技巧
-
java多线程 AbstractOwnableSynchronizer源码分析
-
总线通信协议-USB
-
在virtualbox虚拟机里静默安装RAC 11G.docx
-
AndroidCamera相机介绍.ppt
-
Redis数据库入门与使用
-
高效的socket tcp IOCP完成端口通信机制, 实现多人同时在线. 本实例登录服务器同时在线的最大人数为20000.zip
-
STM32_CAN多帧.zip
-
为什么要用Dubbo-远程通信背景
-
【数据分析-随到随学】Tableau数据分 析+PowerBI
-
勒索病毒加密oracle数据库修复教程-DMP备份文件的修复与数据提取3.mp4