はじめに
先日、空港送迎のシェア乗りサービスの空席を埋めるための時刻表機能をリリースしました。 構想は昔からあったのですが、ようやく開発を進めて世に出すことができました。 ここではその機能概要やシステムについて説明します。
時刻表について
NearMeではユーザー同士がタクシー/シャトルの車両をシェアして乗車するサービスを構築してきました(※同じシェアですが、昨今、ドライバー不足で議論されている"ライドシェア"は一般ドライバーと乗客のマッチングによるもので、それとは異なります)。
特に、空港送迎のような事前に予約するシナリオにおいて運行効率を高める機能を作ってきました。 ユーザー同士のマッチングを最適化したり(参考、参考)、 車両と運行のマッチングも最適化して密な運行セットを作ったりしました(参考)。
また、既にある運行の空席を埋める施策として、時間をずらしたら乗れるというレコメンド機能も実装しました(下図)。
レコメンド表示の図。上が希望の運行。下がマッチした既存の運行。下は希望とずれる分、安くなっている。
今回はその空席をさらに埋めるためのアプローチとして時刻表機能を開発しました。 既にある運行予定をの一覧を表示して、ユーザーは、多少希望の時間・位置がずれたとしても、その中からマッチする運行を選択できるようにしています。
希望の地点を入力してマッチするものに絞り込りこんだり、
時刻表にて地点を入力して運行を絞り込もうとするところ。
運行を選択したら、マッチ可能なエリアが表示されたりします(※エリア内でも、諸々の事情で配車できないことがあります)。
ある運行に対してマッチング可能なエリアを表示。
使い方としては例えば、空港で少し時間をつぶした後、途中の駅までシャトルで移動して、あとはタクシーで移動する、といったことが挙げられます。
また、特に直前に予約する場合は時刻表が効果的です。 一般に、直前になるほど車両を一から手配するのは難しくなり、 既に運行予定がある車両に追加で乗る方が手配しやすく、コストも安く済むからです。
システムについて
この機能のアナロジーはバスの時刻表からきてますが、 それがタクシー/シャトルのような、よりダイナミックなものに対して適用しているところが新しい点です。
時刻表の一覧表示自体は非常に単純です。 運行のリストを時間で絞り込んで、位置情報をマスクした上で表示するだけです。
難しいのは、希望の地点を入力した時に、そこでマッチする可能性のある運行のリストに絞り込むところです。 また、希望の地点を入力しないで一覧から運行を選択したときに、 どこまでのエリアがマッチングできるのかを位置をぼかして表示するところも一工夫必要です。
マッチング可能なエリアは、現実装においては、簡単な数式でポリゴンを算出し、複数経由地があったらポリゴンを合成するなどしています(※概算でエリアを求めているので改善の余地はあります)。
また、位置ぼかしのためh3というライブラリでポリゴンの解像度を落としたりしています。
悩んだのはその結果を、データに保存するか、オンデマンドで計算するかです。 データに保存する場合は、検索はしやすくなるものの、状態の整合性を保つための処理が大変です。 一方で、オンデマンド処理は、検索の度にシステム負荷が高くなる可能性があります。
今回は結果的にオンデマンド処理にしました。フィルタリングとキャッシュも利用して、処理速度は許容範囲と判断しました。
とはいえ、JavaScriptでアルゴリズムを作ると、運行1件あたり数十〜百ミリ秒くらいかかることが分かりました。検索時に一気に数十件を処理することを考えると、最悪数秒かかることになります。これを既存のNode.js上で動かすとなると(シングルスレッドなこともあり)既存処理への影響が大きいです。
なので、別サービスに切り出してRustで実装することにしました。結果として、Rustで実装することにより10倍くらい速くなることを確認しました(副次的ですが、イメージサイズ、メモリフットプリントもかなり小さく、サービスを増やすハードルは低かったです)。
なお、正式な実装では単体テストも書きつつ、Streamlitを用いてインタラクティブにAPIを検証するツールも作りました(下図)。このツールにより、単体テストでは見つけづらい、いくつかの不具合を発見しています。
今後の展望
今は空港送迎サイトにおける表示だけですが、今後は様々な利用シーンで使えるようにしていきたいと考えています。 例えば、登録した地点においてマッチする運行リストを表示できるので、ホテルのカウンターなどにQRを置いて空席を探すといったことをしたいです。 また、ユーザー数が比較的少ない地域のシャトルなどでも、マッチングの可能性を高める手段として期待しています。
最後になりますが、NearMeではエンジニアを募集しています!まだまだ多くの可能性が潜んでいる領域です。興味を持った方はぜひ以下から応募いただければと思います。
Author: Kenji Hosoda