<プロフィール>
藤田 瞭
東京大学数学科卒業。高校時代に情報オリンピックに出場。東京大学大学院数学科中退後、株式会社メディカルフォースにジョイン。現在はエンジニアとして、主にバックエンドの開発などに取り組んでいる。
ーー藤田さんが入社されたのは、大学院在学のときに組田さん(現:代表取締役COO)に誘われたことがきっかけだそうですね。入社後、組織で開発することに対してどう感じましたか?
組織で働くということは、チームで開発すること。一人での開発に慣れていた自分にとって、チーム開発は全く別の世界でした。僕がプログラミングをはじめたきっかけは、中学校時代に先輩のマネをしながらゲーム作りに挑戦したこと。次第にゲーム制作のフレームワークづくりなどにのめり込んでいくわけですが、一人での開発では「自分が作りたいものをどう効率的に作るか」だけを考えていました。
たとえば、画面の設定やデータの初期化などを、一行で済ませるようなコードを書くことも頻繁にありました。自分だけがそのコードを理解していれば良かったため、効率的な一行コードを書き上げることに満足していたのです。
しかし、チーム開発になると話は違います。チーム全員がコードの意味を理解し、他の部分との整合性を保つ必要があります。コードの短さに満足するのではなく、複数人で保守運用をするためにコードの責務を明確に分け、それぞれの役割を定義することが重要だなと実感しました。
ーーチームで働く利点はなんですか?
チーム開発の利点は、一人では煮詰まりがちな場面でも、チームで気軽に相談でき、問題解決がスムーズになることです。また、メンバー全員が少しずつ効率を上げるだけでも、チーム全体としては大きな成果につながることがあります。
行き詰まりがあっても、チームが支え合える環境は、効率化だけでなく、モチベーションの維持にも大きな効果をもたらします。一人では立ち直りが難しい状況でも、チームの支えがあることで継続的な成長が可能になると実感しています。
ーーメディカルフォースで担当した、印象に残っている事例はありますか?
クリニック向けオールインワンSaaS「medicalforce」の機能のひとつに、施術担当者の振り当てがあります。一見なんてことない機能に思えるかもしれませんが、考える要素の多い機能実装でした。
medicalforceのユーザー画面イメージ(※奥が予約機能)
ーーどのように進めていきましたか?
まず、以下のことを考えました。
- 施術をおこなうスタッフを配置するための「割り当て設定」がある
- 実際に割り当てをするには「担当者のシフトや空き時間の考慮」が必要
- 複数の施術を連続して行うことがある
ーー施術をおこなうスタッフを配置するための「割り当て設定」がある、とはどのような話でしょうか。
当たり前ですが、施術は自動的におこなうのではなく作業者が必要です。いろいろ考慮した結果、以下の条件を満たす機能を考えました。
- 各施術に対して 「役割」 を複数指定できる (ex. 医師、看護師、カウンセラー など)
- 役割それぞれに、指定可能なスタッフを複数紐づけられる
- 役割ごとに、必要な人数を設定できる (ex. 医師は 1 人、看護師は 2 人)
患者が予約をする際は、以下のステップを踏みます。
- STEP1:一連の施術 (=施術セット) を指定
- STEP2:表示される候補日のなかから好きな時間帯を選択
- STEP3: 選択された時間帯で予約を作成
これらを実装する際に大変な点としては、2点ありました。
- 一連の施術を指定時における予約可能な時間枠の○×候補表の作成
- スタッフを割り当てる際の「できるだけ良い割り当て」の定義&時間枠の指定と実行
ーー「一連の施術を指定時における予約可能な時間枠の○×候補表の作成」とは、何のための機能ですか?
前述の「STEP2:表示される候補日のなかから好きな時間帯を選択」を実行するための、候補日枠を設計するものです。以下のような前提をもとに、結果が機能に反映されるようにしました。
<メニュー>
施術A:看護師 2 人を必要とする施術
施術B:看護師1人を必要とする施術
<前提>
看護師の A さんが 13:00 から 14:00 ok
看護師の B さんが 14:00 から 15:00 ok
看護師の C さんが 13:00 から 15:00 ok
<結果>
13:00 から 15:00 で、看護師 2 人を必要とする施術Aはできない
→施術Aを選択した患者には13:00-15:00に予約枠を表示しない
13:00 から 15:00 で、看護師 1 人を必要とする施術Bはできる
→施術Bを選択した患者は13:00-15:00に予約枠を表示するーー2つ目の要素の「できるだけ良い割り当て」についてはどうでしょう。
たとえば、院内にスタッフが14人、それぞれ以下のポジションだとします。
カウンセラー
A、B
医師
I、J、K、L、M
看護師
P、Q、R、S、T
経過観察
Y、Zそのうち、クリニックが提供しているメニューと必要な人的リソースは以下のとおりです。
施術 1
「カウンセラー (= A, B)」が 1 人必要
施術 2
「2 をできる医師 = (I, J, K)」が 1 人必要
「2 をできる看護師 = (P, Q, R)」が 2 人必要
施術 3
「3 をできる医師 = (I, J, K, L, M)」が 2 人必要
「3 をできる看護師 = (P, Q, R, S, T)」が 4 人必要
施術 4
「4 をできる医師 = (K, L, M)」が 1 人必要
「4 をできる看護師 = (R, S, T)」が 2 人必要
施術 5
「経過観察 = (Y, Z)」が 1 人必要上記のような状況で、できるだけ同じ医師と同じ看護師を割り当てることが「できるだけ良い割り当て」と定義します。ただし、各施術で、複数の役割を担うことができる人はいません。「医師だけど、看護師の仕事も兼任でやっちゃいます!」みたいなケースはないとします。
ーーなるほど。
まとめると、以下の条件を設定しました。
スタッフの人数:s
スタッフは1〜sいる
施術メニュー数:m
施術1から施術mからなる
必要とするポジション数:r_i
施術 iをおこなうにあたってポジションは役割1〜役割 r_iを持つ
バイネームでのスタッフ配置: i_j_{s_i_j}
施術 i の役割 j にはスタッフ i_j_1 〜 i_j_{s_i_j} を割り当て可能制約は施術 i を固定すると スタッフ i__ は相異なるということになります。
ーーこれを元に、どのように割り当てていくのでしょうか。
例をあげると、以下のようになります。
スタッフの人数:s
スタッフは1から14までいる:スタッフ数 s=14
施術メニュー数:m
メニューは施術1から5まである:施術メニューの種類 m=5これをもとに、「施術3」の場合を考えてみます。
必要とするポジション数:r_i
施術3は役割1から役割2を必要とする:ポジション数 r_3=2
バイネームでのスタッフ配置: i_j_{s_i_j}
役割2にはスタッフ 8, 9, 10, 11, 12 を割り当て可能 (s_3_2 = 5)上記のケースであれば、「A, I, K, P, Q, R, S, Y 」の 7 人を割り当てるのは良さそうです。全体で必要な人数を最小にすればいいとするとして、「B, J, K, Q, R, S, T, Z 」とかでもいいですね。
ーーそれをどう考えていくのでしょうか。
色々やっていたら、整数線形計画問題 (ILP) になりました。
変数 p_1, …, p_s を
p_1 = スタッフ 1 を起用するなら 1 起用しないなら 0
...
p_s = スタッフ s を起用するなら 1 起用しないなら 0例えば、施術 2 で必要な人数を確保するということは以下のようになります。
p_3 + p_4 + p_5 >= 1
p_8 + p_9 + p_10 >= 2つまり、各施術で必要な人数を確保するということは、各施術 i で、各スタッフ j に対して以下のようになります。
p_i_j_1 + ... + p_i_j_{s_i_j} >= 施術 i の役割 j での必要人数また、最適 (最小) にしたい値は以下のとおりです。
最小にしたいもの = p_1 + ... + p_s解法としては、特殊なケースに関しては効率的な解法がありますが、おそらく当てはまらないので分枝限定法がいいのではないかと思います。
ーーありがとうございます。こうしてみると、機能を考えるにあたって医療というポジションならではの制約が多いですね。
そうですね。始めのうちはクリニックの業務知識をインプットすることは大変です。しかし、 メディカルフォースではカスタマーサクセスと連携しお客様とコミュニケーションをとる機会があり、お客様から直接学ばせていただく機会も多いです。
こういったバーティカルSaaSの開発で大事なことは、ユーザの利用シーンや目的、達成したいことをより深く理解しプロダクトに反映すること。機能実装する際には、ユーザの利用シーンを想定して、かゆいところに手の届くような設計にする楽しさがあると思います。