東京大学 情報理工学系研究科 電子情報学専攻 2016年8月実施 専門 第3問
Author
adj-matrix, 祭音Myyura
Description
ある Web サービスに対し、異常に高頻度でアクセスするユーザをアクセスログから見つけたい。各ユーザには一意なユーザ ID が割り当てられており、アクセスログにはアクセスしたユーザの ID が時系列順で記録されている。このとき、以下の問いに答えよ。
(1) アクセスログにおいて、全体の過半数のアクセスを行っているユーザがいるかどうかを、全ユーザに対する頻度ヒストグラム等を生成することなく検証したい。そこで、以下のようなアルゴリズムを考えた。
- i. 空リスト で初期化されたリスト を用意する。
- ii. 配列 の要素に先頭からアクセスし、 番目の要素 について、そのときの の値に応じて以下のいずれかの処理を行う。
- ii-(a). が空である場合、 を に追加する。
- ii-(b). が空でない場合、 が に含まれていれば に追加し、含まれていなければ から任意の要素を1つ取り除く。
- iii. を出力する。
このアルゴリズムを用いて以下のユーザ ID の系列を先頭の要素から処理し、ii で各要素を処理した後のリスト の値を順に示せ。
(2) (1) のアルゴリズムにおいて、 に含まれる要素の種類数は高々一つであることを証明せよ。
(3) アクセスログにおいて過半数を占めるユーザ が存在するとき、 は (1) のアルゴリズムが出力するリスト に含まれる唯一のユーザであることを証明せよ。
(4) (1) のアルゴリズムでは、配列 のサイズが非常に大きい場合にリスト のサイズが問題となる場合がある。この点に注意し、 をリストとして陽に表現しないことで空間効率を改善した上で、アクセスログからユーザ ID を1つずつ順に読み込む関数 read_log() を用いて (1) のアルゴリズムを擬似コードで示せ。
なお、read_log() は最初に呼び出されるとアクセスログの先頭のユーザ ID を返し、以降、呼び出すたびに続くユーザ ID を返す。また、アクセスログの末尾に到達すると を返すものとする。
题目描述
希望从 Web 服务的访问日志中找出访问次数极多的用户。每位用户有唯一 ID,日志按时间顺序记录每次访问者的 ID。回答下列问题。
(1) 为判断日志中是否存在占全部访问次数过半的用户,同时不为所有用户建立频数直方图,考虑以下算法:
- 准备列表 ,初始为空列表 。
- 从头依次访问数组 的元素。处理第 个元素 时:
- 若 为空,将 加入 ;
- 若 非空且 已包含在 中,再加入一个 ;否则从 中任意删除一个元素。
- 输出 。
按顺序用该算法处理用户 ID 序列
依次写出步骤 2 每次处理 后 的值。
(2) 证明在 (1) 的算法中, 所含用户 ID 的种类数至多为 。
(3) 若日志中确实存在多数用户 ,证明它是 (1) 的算法最终输出列表 中唯一种类的元素。
(4) 当数组 很大时,显式保存列表 会造成空间问题。使用每次从日志读取一个用户 ID 的函数 read_log(),写出不显式表示 、空间效率更高但实现同一算法的伪代码。read_log() 第一次调用返回日志中的第一个用户 ID,随后逐次返回后续 ID,到达日志末尾时返回 。
Kai
(1)
| 処理した ID | 処理後の |
|---|---|
| 11 | |
| 10 | |
| 11 | |
| 11 | |
| 7 | |
| 11 | |
| 11 | |
| 3 | |
| 8 |
(2)
帰納法で示す。初期状態では は空である。処理前の が空なら1要素を追加するので種類数は1となる。空でなければ、その唯一の種類と同じ ID を追加するか、既存要素を1つ削除するだけなので、種類数は高々1に保たれる。
(3)
削除操作は、異なる ID の2要素(入力要素と 内の要素)を組にして除く操作とみなせる。過半数ユーザを とすると、 の出現数は他の全ユーザの出現数の和より多い。従って、異なる ID を何組取り除いても は少なくとも1個残る。(2) より最終的な の種類は高々1なので、その唯一の種類は である。
(4)
を「候補 ID とその個数」で表す。
FindCandidate():
candidate = NONE
count = 0
while true:
id = read_log()
if id == -1:
break
if count == 0:
candidate = id
count = 1
else if id == candidate:
count = count + 1
else:
count = count - 1
if count == 0:
return (NONE, 0)
return (candidate, count)
この組は元の出力リストを圧縮して表し、追加空間は 、時間はログ長に対して である。過半数ユーザの存在そのものを判定するには、候補の実際の出現数を再走査で数え、 を超えることを確認する。