在线/离线算法
在开头,我们先来看看机器学习中在线/离线的概念。虽然没有必要和算法中在线/离线做直接联系,但是我觉得对理解在线/离线算法有一定帮助。
在ML系统中,比如说用推荐系统选择要给用户选择他们感兴趣的内容,我们需要通过了解用户的过往信息和此时的状态/需求(Query),通过算法来找到最好的内容(Item)。简单的概括,这样的ML系统最重要的两部分工作是:
启动/调整:用过往或实时的数据来启动/调整算法
应用:用算法来对新的Query推荐Item
这两部在机器学习中分别叫做训练(training period)和运行(prediction period)。

在这样的推荐算法中,有在线和离线的区分。无论是ML系统的训练(training)还是运行(prediction),都可以在线和离线执行,也各自有它们的缺点(备注在括号中):
在线训练(online training):用实时的数据来调整ML系统(算法的不稳定)
离线训练(offline training):线下用大批量的数据来训练ML系统(对新的需求不敏感)
在线推荐(online prediction):用实时的数据来做推荐(延时)
离线推荐(offline prediction):线下对可能的query进行推荐(对新的需求不敏感)
在算法题中也一样,对于很多个query,类比于online prediction vs. offline prediction:可以一个一个处理,或者可以整理好了结果以后再返回。
在线算法
经典的在线算法::用historical queries启动算法,对每一个新的query进行求解。
在线算法的情况很多时候是因为数据太大没办法一股放进内存,只能按照先来后到的顺序来一个个处理数据流(data/network stream)再返回答案。如果每一个新的query的结果都与之前的query有关,此时的在线算法又叫强制在线。
一般会用到的数据类型有:
Heap来缩小缓存大小
Heap,UnionFind,OrderedDict(或者双向链表)来加速查找。
一些经典题目包括:
例题:蓄水池抽样
蓄水池抽样(Reservoir sampling)有效地处理这样的问题:从N个数字中随机选择k个数。我们维护一个大小为k的蓄水池,对每一个新来的第i数字以 的概率接受并替换蓄水池中的数字。参考代码:
例题:数据流中的滑动窗口
原题[类似LC 340]:找到字符串中含有M个不同字符的substring。滑动窗口+Hashmap
数据流:找到数据流中含有M个不同字符的连续数据。由于如果M比较大的话,没办法把整个可能包含M个字符的substring存入buffer,所以我们要修改Hashmap。不再让Hashmap存储每个字符的频率,而存储每个字符最后一次出现的下标。这样一来,如果不同字符超过M个,我们可以让左指针直接移动到第一个distinct字符。如果要继续加速,快速找到第一个distinct字符,我们可以用OrderedDict来实现。
例题:数据流中的最长连续序列
原题[LC 128]:找到数字中最长连续序列
数据流:如果数字很多,不能把所有数字存在buffer中。用并查集来找到最大的连通图,其中连通性由“连续数字“定义。
离线算法
经典的离线算法:整理好Queries,启动算法,再对每一个Query求解。
比如下面这道题,如果用离线算法先对Queries进行排序再最后求解,时间复杂度就能大大降低。
如果想到每个query都有可能查询任何一个interval覆盖的区域,就要提前处理interval存储很多信息。但如果把Queries和Intervals都先排序以后从左到右依次处理,可以用线性的遍历来完成查询。
参考代码:
Last updated
Was this helpful?