一端のゲームエンジニアが"エレベータ"について本気出して考えてみた

こんにちは。技術部サーバーサイドエンジニアの大河原です。

ゲーム作ってます。一応まだ新卒です。

こちらはTech KAYAC Advent Calendar 2017 の23日目の記事になります。

(昨日の記事は我らが@commojun「新卒一年間で確立した紙のノート仕事術!」でした。)

ちなみに前回僕が書いた記事はカヤックのエンジニアのエディタ事情 2017 です。こちらもよかったら是非。

今回は普段から僕らが利用しているエレベータとエレーベータのアルゴリズムについて調べてみました。

f:id:taiga006:20171221185128j:plain
ポルトガル・リスボンの観光地でもあるサンタ・ジュスタのエレベーター。上の展望台からはリスボン市街地を一望できる。

■ なんでエレベータ?

言うまでもなく、弊社はエレベータを設計したり製造したりしていません。←

これといった大きな理由はないんですが、僕自身昔から電化製品とか電子機器とか見るとその性能よりも「どういうギミックで動いてるんだろ?」と不思議に思う性格で、いろんなものを壊しては親に怒られるタイプの子供でした。 (まあ、いい言い方をすれば好奇心旺盛、悪い言い方をすればものを大切にしない性格ということです。)

その意味で高校のときに出会ったアルゴリズムの勉強はとても興味深いものでした。

…で、どうしてエレベータ?って話ですよね。

弊社は鎌倉に本社を構えており僕自身も現在鎌倉勤務なのですが、実は横浜駅前にもオフィスがあります。

「そもそも、なぜわざわざ鎌倉に本社を?」

と思った方は是非弊社代表の柳澤の書いたこちらの記事を読んでみて下さい。

www.kayac.com

ご存じの方もいらっしゃるかもしれませんが、鎌倉は歴史ある街であることもあり、市の規定により市街地含め一部地域では15メートル以上のビルを建設することが規制されています。

景観地区 - 鎌倉市公式サイト

僕が通っているオフィスも例に漏れず駅前の4階建ての自社ビルでエレベータはなく階段で移動しています。

ただ、たまにイベントやMTGなどで横浜オフィスにいくことがあるんですが、こちらの横浜オフィスのほうは横浜駅前の三井ビルディングの30F(最上階)にあり当然最新式のエレベータが複数台設置されています。

人間誰しもオフィスビルやショッピングモールなどで待てども待てどもエレベータが全然来なかったり、「来た!」と思っても反対方向行きだったりしてイライラしたことがあると思います。

エンジニアであれば尚更、「全然エレベータこねーじゃねーか!!どんなアルゴリズムで動いてんだ?俺が一から実装し直してやろうか!!」と寝坊して遅刻しそうな自分を棚に上げて考えたことが一度はあることでしょう(?)

つい先日久しぶりに横浜オフィスに足を運んだときに、まさに上のような状況になって(…あれ?でも待てよ?たしかにこいつら一体どんな仕組みで30階ものフロアを行ったり来たりしてるんだ?しかも複数台で…!?)と不思議に思い、持ち前の好奇心で今回調査してみた次第です。

■ エレベータのアルゴリズムとエレベータアルゴリズム

『エレベータ アルゴリズム』とかで検索するとまず引っかかるのが「エレベータアルゴリズム」というものです。

これで意外とあっさりブログが書き終わってしまいそうと思われたかもしれませんが、残念ながらこれはある特定のアルゴリズムを指すものであり、僕らが普段利用するエレベータに直接適用されているアルゴリズムではありません。

エレベータアルゴリズム - wikipedia

アルゴリズムだけ簡単にまとめると、

  1. ある1つのリクエストを受信すると、同じ移動方向で別のリクエストが有る限りその方向に移動し処理しつづける(無くなれば2へ)
  2. 1とは逆方向でリクエストが有る限りその方向に移動し処理しつづける(また無くなれば1へ)

といった具合ですごくシンプルな内容です。

このアルゴリズムは身近なところで使われています。

つい最近だと、GoogleのRui Ueyamaさんのnoteでも話題に挙げられていたHDDのヘッダのスケジューリングの基本アルゴリズムの一つだったりします。

note.mu

エレベータの下の階が「HDDのトラックの内側」で上の階が「HDDのトラックの外側」とイメージするとわかりやすいと思います。

このアルゴリズムを使ったSCAN方式と呼ばれるものはあくまでディスクスケジューリングアルゴリズムの一つであり、他にも色々とあるようです。

ここでは上のエレベータアルゴリズムを含むディスクスケジューリングのアルゴリズムをいくつか紹介します。


- FCFS (First-Come-First-Served)

単純にリクエストが来た順に処理して行くアルゴリズム。どのリクエストも公平に処理され余計な遅延も起きないが、アクセス時間は非効率でパフォーマンスも悪くなりやすい。

- SSTF (Shortest Seek Time First)

現在位置から一番近い(移動時間が短い)リクエストを順に処理して行くアルゴリズム。平均のレスポンスタイムがFCFSより早くなる一方でリクエストによってはずっと処理されず餓死状態になる場合がある。

- SCAN

上で出たエレベータアルゴリズム。(SCANがなんの略なのかはわからなかった。)移動方向が変わらないため応答時間の変動が少なく上2つに比べると単位時間あたりの処理能力が高くなる。デメリットは追加のリクエストに対しても一度通過してしまった場所だと処理が後回しにされる点や両端のトラックの待ち時間が必然的に長くなってしまうこと。(まさにエレベータ)

- LOOK

SCANとすごく似ているアルゴリズム。実はSCANはある一方向にリクエストを処理しづけて終端まで移動してしまうのに対して、これはそれ以降その方向にリクエストがない場合に引き返す、というアルゴリズム。

- C-SCAN

最初のCはCircularのC。SCANは終端までチェックし続けて引き返すがつまりそれは一度走査した箇所を再度チェックして行くことになる。それに対してC-SCANは一気にもう片方の終端まで飛んでから再度同一方向に移動しながらリクエストを処理する(つまり循環する)、というアルゴリズム。

- C-LOOK

説明不要かと。つまり循環するLOOKということ。


より詳しく知りたいという方はgeelsforgeeksの記事 とか イリノイ工科大学の授業資料 を読んでみると面白いかもしれません。

さて、実際のエレベータもそのビルに1台しか設置されていないのであればこのアルゴリズム(あるいはそれを少し拡張したもの)に則るだけで十分な性能が得られそうですが、多くの場合そうではなく2,3台、大きなビルとなればもっと多くのエレベータが同じエントランスに存在することになります。

しかし、これまた有名な話で恐縮ですが、SCANのような単純なアルゴリズムで複数台のエレベータを運転させた場合、最終的にエレベータ同士が連れ添ったような動き(団子運転)をしてしまうことが知られています。

これを解消するためにあるのが 郡管理 と呼ばれるシステムです。

正確には郡管理システムという言葉自体は、企業や工場などで複数の制御対象に対してある法則に則って連動させることで高効率化を測ることを意図したシステムを意味します。(ただしざっとググった感じだと特にエレベータのシステムに対して使われている印象です。)

群管理システムには例えば「過去の利用データから各時間帯の利用者数を予想して効率的に人を運送する方式」であったり、あるいは「運行効率を工夫することでより省エネを実現できる方式」であったり、はたまた「心理学の観点からエントランスでの待ち時間と実際の乗車時間のうちそれぞれの時間あたりのストレス値などを計算して乗客のイライラを最小限にする方式」であったり...他にも様々な方式が存在し、大手電気メーカの開発・技術関連のページを巡回してみるだけでも面白い情報が得られます。

そういえば最近、現在の階数表示がされていないエレベータをよく見かけますね。あれは、そのエレベータの群管理システムによって敢えて乗車希望者のいるフロアを通過していたりするのを隠すためにあるようです。たしかにいくら全体の効率が良くなるからと言って自分の目の前をエレベータが素通りしていったらストレスたまりそうですよね。

そして当然といえば当然のことですが、それらの詳細なシステムロジックについては各企業の最重要機密事項に当たるため簡単に調査することはできませんでしたあぁああぁああぁ。←

■ 閑話休題

「ボタン押したのに全然こねーじゃねーか!」

以外のエレベータあるあるに「やっべ、違う階のボタン押しちゃった!」があると思います。

あまり知られていませんが製造元メーカによっては押したボタンをキャンセルできる機能がついてたりします。

www.buzzfeed.com

エレベータの動くロジックとは直接関係ありませんが、自分の会社が入っているオフィスビルのキャンセル方法くらいは覚えておいて損はないかと思います。

(もちろん型番によってキャンセルできる/できない場合があることも含めて。)

余談ついでにもう一つ言うと、世界初のエレベータはかのアルキメデスが発明したそうです。

とはいえ、彼が生きていたのは紀元前。ロープと滑車を使った人力のもので人ではなく荷物を運搬するためだったそうです。

■ エレベータのアルゴリズムを書いてみる ~ Elevator Saga ~

f:id:taiga006:20171221173705p:plain

エレベータのアルゴリズムについて調べていたらたまたまElevator Sagaというサイトを見つけました。(GitHubはこちら)

Elevator Sagaはエレベーターのシミュレーションゲームを通じてプログラミングの基礎を学べるサイトのようです。利用できるAPIがドキュメント込みで公開されているのでパズル感覚でアルゴリズムを考えられます。(言語はJavaScriptです。)

例えば「エレベータが待ち状態の時には1階に行く」みたいな指示は次のように書けます。

elevator.on("idle", function() {
    elevator.goToFloor(0);
});

これらのAPIを駆使して指定時間内に目標人数を行きたい階数に輸送できるとクリアとなります。

面白そうなので最初の簡単なレベルだけ挑戦してみました。

lv.1 3階建て:60秒で15人を輸送せよ

{
    init: function(elevators, floors) {
        var elevator = elevators[0];

        elevator.on("idle", function() {

            elevator.goToFloor(0);
            elevator.goToFloor(1);
            elevator.goToFloor(2);

        });
    },
    update: function(dt, elevators, floors) {
    }
}

まだよくわかってないのでとりあえず1階から3階までを巡回するだけのエレベータを作ってみました。

(実際あったらブチ切れそう。)

elevatorsとあるようにレベルが上がって行くに従ってエレベータの数自体も増えて行きます。

ちなみに lv2 は上と変わらずに巡回する階数を増やせばクリアできます。

lv.3 5階建て:60秒で23人を輸送せよ

{
    init: function(elevators, floors) {
        var elevator = elevators[0];

        _.each(floors, function(floor) {
            floor.on("up_button_pressed down_button_pressed", function() {
                elevator.goToFloor(floor.floorNum());
            });
        });

        elevator.on("floor_button_pressed", function(floorNum) {
            elevator.goToFloor(floorNum);
        });

    },
        update: function(dt, elevators, floors) {
        }
}

今度は少し工夫しました。と言っても

  • 「各フロアでボタンが押されたらその階に移動する」
  • 「乗客が押した階に移動する」

と行ったエレベータのごくごく基本的な動作を入れただけです。

台数が増えてこのあとLv4あたりから本番、と行った感じです。

普段から競プロとかやられてる人はこう言ったゲームおそらく得意でしょうね。

■ 最後に

いかがだったでしょうか。おそらくこのブログの読者層からして普段の業務には1ミリも役立たない内容だったかと思いますが、通勤時間の暇つぶしくらいにはなったんじゃないでしょうか。

最後に募集告知です。

カヤックでは、でかいオフィスビルでいつまでもエレベータを待っていられない!一秒でも長くコードを書いていたい!というエンジニアを募集しています。(強引)

www.kayac.com

www.kayac.com

さて、毎日コツコツ続けてきたカヤックのAdvent Calenderも残すはあと僅か!

明日は@butchi_yの記事を予定しております。お楽しみに。

本記事で参考にさせていただいたサイト

新卒の一年間で確立させた紙のノートを使った仕事術!

この記事は Tech KAYAC Advent Calendar 2017 の22日目の記事です。

こんにちは、最近入社2年目になったバックエンドエンジニアの @commojun と申します。

皆さんは紙のノート使っていますか?僕は毎日使っていて、仕事を進める上ではPCの次くらいに必要不可欠な存在となっています。 本日は、新卒で入社してから約1年、毎日紙のノートを使ってきて自分なりのノート活用法が確立したので紹介いたします。

もくじ

どんな感じに使っている?

まずはこちらをご覧ください。僕は毎日紙面にこのような欄を設けてノートを利用しています。それぞれの箇所に役割があるので、順番に紹介していきます。 f:id:commojun:20171221002659j:plain

ノートの役割

①その日のタスクを一覧する

ノートの一つめの役割はタスク管理です。一日が始まる前に、その日あることとやることをリストに書き出します。

[予定]の欄には、その日のスケジュールの一覧を、[やるコト]の欄には、その日やるもしくはやりたいタスクを書き出し、デスクに置いておきます。

基本的に人間は一つの作業に集中している時は他のことを考えません。ちょっとした作業に身が入りすぎて、もっと重要なタスクのことを忘れてしまっていた!なんて経験は無いでしょうか?作業が一息ついた時にこのページが目に入る場所に置いてあれば、「あぁ、次はこれをやるんだったな」と次のタスクへスムーズに移行できます。

ポイントは、「気にかける」とか、「確認をする」とか、「何か起きたら対応する」だけのようなとても小さなタスクもここにしっかり記しておくことです。このリストはTODOリストでもありながら、後述する一日の振り返りをするための材料となります。小さなタスクを書き漏らすと、たまたままとまった成果が得られなかった日に「あれ、オレ今日仕事してなくね?」という感覚に陥ることがあります。これは正しく振り返りが出来ておらず、メンタルヘルス的にもとてもマイナスなことです。小さなタスクもタスクとしてしっかり認めましょう。

②一日ごとに小さな目標と振り返りを持つ

弊社社長日記より、

www.kayac.com

「その人にとっての天職とは、その仕事を通して、その人に多くの気づきを与えてくれるものである」

という記事が話題になったことがあります。これについて僕自身も同様の意見を持っており、仕事で能力を継続的に向上できるかどうかは、一日の中でどれだけ多くの気付きを得続けることができるかにかかっていると考えています。

そのための習慣付けが[目標]と[評価]の欄です。[目標]の欄には、「今日一日でこれが出来たらマジで最高だぜ!」という達成目標を記入します。[評価]の欄は、一日を振り返って今日が何点だったかを主観で点数*1を付け、よかったことや、もっとよく出来たことなどの気づきを記入します。この一連の振り返りをすることで、「明日はこうしてみよう!」という小さな改善を継続できるようになります。

③まとまりきらない考えをいったん書き下す

ここから先はなんでもありの殴り書きメモのページです。一番初めに着手するタスク名を書いたら、あとは頭に浮かんでいるものをどんどん自由に書き下していきます。

ところで皆さんは、頭に浮かんだままのアイデアから、いきなりコードや文書、グラフィック・デザインなどの成果物を生み出すことが出来ますでしょうか?たいていの場合、一度作っては壊し、の試行錯誤を繰り返すケースが多いと思います。すんなりとできる人は相当その作業に慣れた熟練の方だと思います。

人間の脳には常時様々な雑念が流れており、その混沌とした中に浮かんだアイデアからいきなり完成形の成果物を生み出すというのはとても精神的なコストが大きく、ストレスがかかります。

f:id:commojun:20171221153654p:plain

そこで、アイデアから成果物への変換経路にまとまりきらない考えをいったん書き下す場を設けます。

f:id:commojun:20171221153712p:plain

もやもやとした形になりきらないアイデアをいったん全て紙に吐き出すことで、頭がスッキリします。(この作業をブレインダンプと呼ぶらしいです。)そのスッキリとした状態で書き下したメモを眺め、重要そうな部分を抽出したり、新たに浮かんだことを書き加えたりというブラッシュアップを経ると、アイデアに方向性が付き始めます。このタイミングが実際に成果物に取り掛かる合図です。ノートで一度アイデアの方向性に確信が持てた状態になっているので、最後まで作り上げたのにやっぱりゼロからやり直し、といった事が起こる確率を下げることができます。

なぜ、紙のノートなのか?

なんだ、それくらいのことならデジタルのメモでも同じようなことができるじゃないか、という意見を持つ方も多いと思います。僕があえて紙のノートを利用しているのにはいくつか理由がありますので、紹介いたします。

①汚く使える

皆さんは学生時代、問題集を解いた後に丸つけをしていましたか?僕は結構丸つけが好きで、シュバババー!っと大胆に赤ペンで丸つけをしていました。

[やるコト]リストにも同じようなことをしています。着手したタスクには容赦なく赤線を引いて、DONEという文字を書いたり、チェックマークをつけたりしています。デジタルのTODOチェックリストでポチポチとチェックマークを付けるのと何ら変わりない作業なのですが、汚く使えば使うほど「やったったぜ!」という気分にひたれるので僕は紙のノートが好きです。

f:id:commojun:20171221143150j:plain

②型にはまらない使い方ができる

①と関連しますが、デジタルでメモを書く場合、メモはアプリケーションで扱える型で記入しなければなりません。

例えばメモ帳アプリでメモ書きをしていてこんなことがしたくなった時、どうしますか?

  • 図を入れたい
  • 絵を描きたい
  • 下線を引きたい
  • 赤文字を書き込みたい
  • 急に大きな文字が書きたくなった
  • 文字を斜めに書きたい
  • テキストに横断して矢印が書きたい
  • 文字の隙間に小さい文字で一言追加したい
  • 今まで書いたメモにでっかいバツ印をつけたい
  • ページを破って人に渡したい
  • 破ったページを折り紙にして立体物を作りたい(!?)

これらを我慢してプレーンテキストでメモを書いたとき、メモ帳アプリによってアイデアの広がりが制限されてしまったことになります。

近年はこれら全ての要望を叶えるアプリケーションがいくつも登場しているかと思います!使いこなすことができれば最強かもしれませんが、結局はそのアプリケーションの作法に従わなくてはならず、どこかしら一長一短なケースが多いな、と個人的に感じています。

こちらは、今回の記事を作成するために書いたメモ書きです。アプリの設計思想にとらわれず、ストレスなく使えるというのが紙のノートの利点だと思います。

f:id:commojun:20171221143330j:plain

③目に入る場所に置いておける

TODOリストをデジタルで管理している方、一日に何回TODOリストを見返しますか?PCの画面は(マルチディスプレイでない限り)一つしかないので、デジタルのTODOリストをずっと見える形で置いておくことはあまり現実的ではありません。

紙であれば、デスクの空いている場所に置いておけばよいので、自然と今日のタスクを定期的に思い返すことができます。

欠点

もちろん紙のノートにも欠点がいろいろとありますよね。それらを理解することも紙のノートを上手く活用するコツです。

アンドゥができない

消しゴムを使って消してもいいですが…間違いを修正するのはデジタルのほうが楽ですね。むしろどんどんノートを汚く使うべきだと思います。

あのメモっていつどこに書いたっけ?ってなる

検索できませんからね。お決まりの手順書のような、あとで見返すようなメモを書くのには向いていないと思います。そういった情報を記す場合は積極的にデジタル媒体を利用したほうが良いでしょう。

エコでない

仕方ないですね…圧倒的に仕事効率を上げて元をとりましょう。

最後に

入社初日から約1年間毎日ノートを書き続け、10冊目に差し掛かりました。過去のページを見ると「そういえばあのときはこんな仕事していたなぁ」と振り返ることができてなかなかおもしろいですね。

f:id:commojun:20171221154430j:plain

といった感じで紙のノートの活用術を紹介させていただきました。参考にしてみてください。

面白法人カヤックでは、紙のノートをもっと賢く使っているぞ!という人を募集しています。

www.kayac.com

www.kayac.com

次回は @ogrew による「エレベータにイライラする話」です。

*1:点数を主観で付けることにあまり意義を感じていませんが、後から見返すと、少なくともそのときの自分が楽しく働けているかどうかがこの点数に反映されていることがわかってきました。