有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

系统安装、升级讨论
版面规则
我们都知道新人的确很菜,也喜欢抱怨,并且带有浓厚的Windows习惯,但既然在这里询问,我们就应该有责任帮助他们解决问题,而不是直接泼冷水、简单的否定或发表对解决问题没有任何帮助的帖子。乐于分享,以人为本,这正是Ubuntu的精神所在。
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#16

帖子 astolia » 2014-07-28 20:48

科学之子 写了:
astolia 写了:
科学之子 写了: 当前距离遗忘临界点
kt=期望记忆时长=60
ckt=当前距离遗忘的距离=30

r(0.5)=ctk(30)/kt(60)//还有30秒忘记
r(0.05)=ctk(3)/kt(60)//还有3秒忘记
r(0.0)=ctk(0)/kt(60)//还有0秒忘记(达到遗忘临界点,是数值上最理想的被复习状态)
r从哪来的恒等于1?
看吧,我就说你没把公式搞清楚。
问题在于当kt=60时, ckt根本不可能为30
你自己说的 ft=遗忘时间点=当前系统时间(ct)+期望记忆时长,后面也没见你修改说法,就照这个算
那么当kt为60时,ft=ct+kt=ct+60
则ckt=abs(ft-ct)=abs(ct+60-ct)=abs(60)=60,r=60/60=1
注意ct=当前系统时间,它是一个可变量,而非固定不变,它不是存储在记录中,而是运行时从当前环境获取.
如果当前系统时间ct不变,您的理解是没错,r始终恒等于1.
我知道你的意思,但是你的公式和解释完全是在误导人。ft计算公式中的当前时间和ckt中的当前时间是两个不同的量,你首先就不应该用同一个ct符号表示。而且ft中的ct确实是存储在了记录中,而不是你说的运行时从当前环境中获取。另外ft说成是遗忘时间点也很误导人,应该是ft为下次需要复习的时间点。

如果你坚持用你那个公式判断的话,基本没什么优化余地了。如果你愿意改下算法,优先选择ft最接近当前系统时间的,ft相同时才去考虑kt的话,就可以通过对ft排序大幅减少查找时间
头像
qgymib
帖子: 539
注册时间: 2010-04-02 16:44
系统: openSUSE 13.2 x64

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#17

帖子 qgymib » 2014-07-28 21:40

表示怀疑数据库软件能从数量级上提升效率?数量级上的效率提升,感觉这不是一些技巧性优化能办到的.
这个lz不用怀疑,从时间上来讲,效率绝对是数量级的降低的。采用数据库的方案是因为对于一些程序来讲近百MB的内存占用开销过大,因此采用磁盘空间换取内存空间的方法。
而且即使lz的工具用途推广了,我的两种方法仍然适用。
正在建设中的个人博客
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#18

帖子 科学之子 » 2014-07-28 23:01

astolia 写了:
科学之子 写了:
astolia 写了:
科学之子 写了: 当前距离遗忘临界点
kt=期望记忆时长=60
ckt=当前距离遗忘的距离=30

r(0.5)=ctk(30)/kt(60)//还有30秒忘记
r(0.05)=ctk(3)/kt(60)//还有3秒忘记
r(0.0)=ctk(0)/kt(60)//还有0秒忘记(达到遗忘临界点,是数值上最理想的被复习状态)
r从哪来的恒等于1?
看吧,我就说你没把公式搞清楚。
问题在于当kt=60时, ckt根本不可能为30
你自己说的 ft=遗忘时间点=当前系统时间(ct)+期望记忆时长,后面也没见你修改说法,就照这个算
那么当kt为60时,ft=ct+kt=ct+60
则ckt=abs(ft-ct)=abs(ct+60-ct)=abs(60)=60,r=60/60=1
注意ct=当前系统时间,它是一个可变量,而非固定不变,它不是存储在记录中,而是运行时从当前环境获取.
如果当前系统时间ct不变,您的理解是没错,r始终恒等于1.
我知道你的意思,但是你的公式和解释完全是在误导人。ft计算公式中的当前时间和ckt中的当前时间是两个不同的量,你首先就不应该用同一个ct符号表示。而且ft中的ct确实是存储在了记录中,而不是你说的运行时从当前环境中获取。另外ft说成是遗忘时间点也很误导人,应该是ft为下次需要复习的时间点。

如果你坚持用你那个公式判断的话,基本没什么优化余地了。如果你愿意改下算法,优先选择ft最接近当前系统时间的,ft相同时才去考虑kt的话,就可以通过对ft排序大幅减少查找时间
一开始就是用的这种算法,但这种算法的缺点是某些单词被过于频繁的推荐,用户体验就是整个复习计划显得很死板且没效率.
如果按照比例,体验和复习效率很好很多,但性能优化将变得更加困难(尽管从"人眼"的实用角度来看这并不是什么大问题)
Tue Jul 29 23:25:59 CST 2014补充:
仔细想了想,提供了思路方向的指引,如果想继续优化,判断方法(在我看来)肯定需要变化才有可能实现.
谢谢.
上次由 科学之子 在 2014-07-29 23:29,总共编辑 2 次。
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#19

帖子 科学之子 » 2014-07-29 1:09

qgymib 写了:
表示怀疑数据库软件能从数量级上提升效率?数量级上的效率提升,感觉这不是一些技巧性优化能办到的.
这个lz不用怀疑,从时间上来讲,效率绝对是数量级的降低的。采用数据库的方案是因为对于一些程序来讲近百MB的内存占用开销过大,因此采用磁盘空间换取内存空间的方法。
而且即使lz的工具用途推广了,我的两种方法仍然适用。
这种"几乎乱序"的查找也会比自己写的程序快吗?为什么会更快呢?
怀疑的原因就是数据库软件用什么算法?凭什么更快?
Tue Jul 29 01:12:03 CST 2014补充:
和普通的乱序表查找不同,这里的key是不固定的,或者说根本就没有固定的key可供建立,我认为无法通过建立索引之类的方法去查找.
头像
qgymib
帖子: 539
注册时间: 2010-04-02 16:44
系统: openSUSE 13.2 x64

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#20

帖子 qgymib » 2014-07-29 7:40

科学之子 写了:
qgymib 写了:
表示怀疑数据库软件能从数量级上提升效率?数量级上的效率提升,感觉这不是一些技巧性优化能办到的.
这个lz不用怀疑,从时间上来讲,效率绝对是数量级的降低的。采用数据库的方案是因为对于一些程序来讲近百MB的内存占用开销过大,因此采用磁盘空间换取内存空间的方法。
而且即使lz的工具用途推广了,我的两种方法仍然适用。
这种"几乎乱序"的查找也会比自己写的程序快吗?为什么会更快呢?
怀疑的原因就是数据库软件用什么算法?凭什么更快?
Tue Jul 29 01:12:03 CST 2014补充:
和普通的乱序表查找不同,这里的key是不固定的,或者说根本就没有固定的key可供建立,我认为无法通过建立索引之类的方法去查找.
你哪里看出来数据库更快了 :em20 我都说了效率是数量级的降低的,任何涉及到IO的程序就不可能比在内存中操作数据的程序快(仅针对存取,不涉及复杂计算)。
对于你后一个问题的话,数据库的key,或者专业点讲,primary key,完全可以设置成单词本身,value则可以设置成固定不变的变量,等到取出时再做计算。举个栗子(就不用lz的例子了,我对这方面不了解,看不懂。。。),计算n个与二元一次算式(Ax2 + Bx + C)有关的值中的最小值,其中x与当前时间有关,n个变量中的A、B、C的值不同,则数据库中各个primary key的value可以设置为A、B、C,然后自己写个你计算公式对应的函数,最后再select (your primary key) from (your table) where (your funcation)。done!
正在建设中的个人博客
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#21

帖子 科学之子 » 2014-07-30 17:13

qgymib 写了:
科学之子 写了:
qgymib 写了:
表示怀疑数据库软件能从数量级上提升效率?数量级上的效率提升,感觉这不是一些技巧性优化能办到的.
这个lz不用怀疑,从时间上来讲,效率绝对是数量级的降低的。采用数据库的方案是因为对于一些程序来讲近百MB的内存占用开销过大,因此采用磁盘空间换取内存空间的方法。
而且即使lz的工具用途推广了,我的两种方法仍然适用。
这种"几乎乱序"的查找也会比自己写的程序快吗?为什么会更快呢?
怀疑的原因就是数据库软件用什么算法?凭什么更快?
Tue Jul 29 01:12:03 CST 2014补充:
和普通的乱序表查找不同,这里的key是不固定的,或者说根本就没有固定的key可供建立,我认为无法通过建立索引之类的方法去查找.
你哪里看出来数据库更快了 :em20 我都说了效率是数量级的降低的,任何涉及到IO的程序就不可能比在内存中操作数据的程序快(仅针对存取,不涉及复杂计算)。
对于你后一个问题的话,数据库的key,或者专业点讲,primary key,完全可以设置成单词本身,value则可以设置成固定不变的变量,等到取出时再做计算。举个栗子(就不用lz的例子了,我对这方面不了解,看不懂。。。),计算n个与二元一次算式(Ax2 + Bx + C)有关的值中的最小值,其中x与当前时间有关,n个变量中的A、B、C的值不同,则数据库中各个primary key的value可以设置为A、B、C,然后自己写个你计算公式对应的函数,最后再select (your primary key) from (your table) where (your funcation)。done!
抱歉,不知道怎么就鬼使神差的看成"复杂度是数量级降低"了...

Wed Jul 30 17:14:51 CST 2014补充:
公式没看明白.
不过想到了一个变相改进效率的方法.
在单词数组的元素数量不发生变化的情况下空闲时进行预先计算.
这样到了相应时间,只需根据当前时间读取索引好的预先被计算出来的结果即可.
不过感觉是治标不治本的方法,而且空间消耗巨大.

r是遗忘的比例(或遗忘进度的百分比)
无法索引的理由是:
1.每个单词的r必须通过访问相应单词的记录,获取单词记录后在和当前系统时间进行计算得出
2.系统时间变化同样的数量,每个单词的r发生的变化幅度不同.
3.系统时间只要发生变化,记录中每一个单词的r就需要重新计算.
回复