TL;DR
- 筆者は一級建築士(40代)。プログラミング経験ゼロでリリースした割り勘アプリ「FAMI-KAN」の開発ストーリー第4弾です。
- 精算アプリを開発する際、誰もが真っ先に実装しがちな「送金回数を減らすアルゴリズム(貪欲法)」。しかしそこには、現実の人間関係や摩擦を無視した「不都合な真実」が隠されています。
- 「中途半端に少しだけ支払った人」が、数百円の端数のために銀行振込手数料を払わされるという理不尽。
- ハッカソンの懇親会や大人数のイベントで発生する「面識のない人に直接送金させられる社会的気まずさ(Social Awkwardness)」。
- 最後に、メンバーが増えた際に発生する「別次元のカオス(トレードオフ)」について、現在も私が頭を悩ませている未解決の構想を共有します。
1. はじめに:送金回数を減らす「貪欲法」とは
こんにちは。プログラミング経験ゼロの建築士です。AI(Antigravity)と二人三脚で、登録不要の割り勘Webアプリ「FAMI-KAN」を開発・運営しています。
割り勘アプリを開発する際、避けて通れないのが「単純な数値の計算」です。
合計金額を人数で割るだけなら簡単ですが、旅行やBBQで「複数人がバラバラに支払いを立て替えた場合」は少し複雑になります。このとき、どうすれば「最も少ない送金回数で精算を終わらせることができるか」を考える必要があります。
私も最初にアプリを作った際、真っ先にこの「送金回数を最小化するアルゴリズム(貪欲法)」を導入しました。
仕組みは非常にシンプルです。
- 各メンバーの「実際に支払った額」と「負担すべき額」の差額を出す。
- グループを「お金を受け取る人」と「お金を支払う人」に分ける。
- 一番多く支払うべき人から、一番多く受け取るべき人へ、限界まで送金させる(マッチング)。
- これを全員の差額がゼロになるまで繰り返す。
これで、例えば「Aさん→Bさん、Bさん→Cさん」という二つの送金を、「Aさん→Cさん」の1回にショートカットできます。計算上は最も効率の良い正解です。
しかし、この効率的なアルゴリズムには、現実の人間関係を無視したいくつかの**「不都合な真実」**が隠されていました。
2. 不都合な真実①:中途半端に支払った人が大きく損をする理不尽
具体的な数字を出して説明します。6人でBBQに行き、総額30,000円かかりました。一人あたりの負担額は全員一律で5,000円です。
| メンバー | 役割・内訳 | 当日の支払額 | 精算時の状態 |
|---|---|---|---|
| Aさん | 幹事(食材・場所代) | 21,000円 | 16,000円 受け取る |
| Bさん | 手伝った(買い出し) | 7,000円 | 2,000円 受け取る |
| Cさん | 中途半端(高速・ガソリン) | 2,000円 | 3,000円 支払う |
| Dさん | 何もしなかった | 0円 | 5,000円 支払う |
| Eさん | 何もしなかった | 0円 | 5,000円 支払う |
| Fさん | 何もしなかった | 0円 | 5,000円 支払う |
この状態で、一般的な「貪欲法(送金最小化)」を適用すると、以下の送金ルートが生成されます。
| 順番 | 送金する人 | 送金先 | 送金額 | 備考 |
|---|---|---|---|---|
| 1 | Dさん | Aさん | 5,000円 | |
| 2 | Eさん | Aさん | 5,000円 | |
| 3 | Fさん | Aさん | 5,000円 | |
| 4 | Cさん | Aさん | 1,000円 | Aさん精算完了 |
| 5 | Cさん | Bさん | 2,000円 | 全員の精算が完了 |
送金回数はわずか「5回」です。
しかし、この結果を人間関係の視点から見ると、非常に理不尽な状況が生まれています。
- お金を受け取る側(Aさん、Bさん):多く立て替えているので、複数人から送金されてきても特に不満はありません。
- 何も財布を出さなかったDさん、Eさん、Fさん:Aさんに「1回送金して終わり」という最も楽な役回り。
- 中途半端に2,000円支払って手伝ったCさん:当日2,000円を手出しして協力したにもかかわらず、精算時にAさんとBさんの**「2箇所へ」細かく送金しなければならない**という、一番面倒な役割を押し付けられています。
もしこれが、全員が同じ電子マネーを使っておらず、「銀行口座への振込」で精算しなければならない場面だとしたらどうでしょうか。
Cさんは当日2,000円も手出ししたのに、最後の最後で、**「わずか1,000円や2,000円を振り込むために、無駄な手数料を自腹で2回分払わされる」**という、余計な手数料の負担を背負わされることになります。
3. 不都合な真実②:貸借のショートカットによる「社会的気まずさ」
もう一つの不都合な真実。それは、世界シェアNo.1の割り勘アプリである『Splitwise』などでよく使われている、**「人間関係の無視」による社会的気まずさ(Social Awkwardness)**です。
Splitwiseなどのアプリには、グループ内の送金をマージして減らす「債務の簡素化(Simplify debts)」という機能があります。非常に便利ですが、この機能は全体の送金回数を減らすために、元々の「誰が誰のために立て替えたか」という貸借関係を勝手にシャッフルします。
これが、日本の日常的なイベントでも、以下のような気まずいノイズを生み出します。
ハッカソンの懇親会や、友達の友達が混ざる大人数のケース
- IT勉強会やハッカソンの打ち上げ懇親会、あるいは「友達が自分の連れを連れてきた」というBBQなど、メンバー全員が全員と親しいわけではない集まりです。
- このような場では、受付での前払いや会場限定チケットを、先に到着したメンバーがまとめて購入することがよく起こります。あなた(Aさん)は先に到着し、友人Bさんの飲食チケットを代わりに購入しました(「後で払って」という口約束で)。
- BさんはさらにBさんの知人Cさん(あなたとは初対面)が遅れて参加することを知っており、受付でCさんの分のチケットも代わりに購入しました。こうして「AさんがBさんの分を立て替え、BさんがCさんの分を立て替える」という連鎖が自然に発生します。
本来の貸し借りの文脈は「Cさん→Bさん」「Bさん→あなた(Aさん)」です。
ここで「Simplify debts(債務の簡素化)」をオンにすると、中間のBさんが省略され、画面には**「初対面で一言も喋っていないCさんから、あなた(Aさん)へ直接PayPayや銀行振込で送金してください」**という指示が出ます。
「この機能(Simplify debts)をオフにすれば解決するのでは?」と思われるかもしれません。
確かにオフにすれば、Cさんは知り合いのBさんに払い、Bさんがあなたに払うため、人間関係は維持されます。しかしそうすると、グループ全体の送金回数が激増するというトレードオフが発生します。
結果として、海外のRedditコミュニティでも、この機能に対して「なぜ知らない人に直接払わなければいけないのか?」「送金アプリでメッセージを書くときに何て書けばいいか分からなくて困る」といった、ユーザーからのリアルな困惑や不満が大量に議論されています。
数学的にどんなに正しくても、お金の貸し借りは関係性のやり取りです。「面識のない相手へ直接送金させる」ロジックは、人間関係の摩擦を増やすアンチパターンになり得るのです。
4. 私たちがいつか実装したい「貢献者ファースト」という思考実験
私たちは、この不都合な真実に直面したとき、「数学的最適解」を優先するのをやめ、**「デフォルトは人間の感覚に優しくあるべきだ」**と考えました。
まだFAMI-KANに実装はできていませんが、もし以下のような**「手伝った(貢献した)人の送金先を極力減らし、手伝わなかった人に送金の手間を引き受けてもらう」**というアルゴリズムを実装したらどうなるか考えてみます。
**6人での日帰り旅行(計 48,000円 / 1人あたりの負担額 8,000円)**のケースで考えてみます。
| メンバー | 役割・内訳 | 当日の支払額 | 精算時の状態 |
|---|---|---|---|
| Aさん | 交通係(バス・タクシー) | 10,000円 | 2,000円 受け取る |
| Bさん | 食事係(ランチ代) | 13,000円 | 5,000円 受け取る |
| Cさん | 宿泊係(温泉・手配) | 16,000円 | 8,000円 受け取る |
| Dさん | 少し手伝った(ガソリン) | 5,000円 | 3,000円 支払う (※保護したい) |
| Eさん | あまり払わなかった | 3,000円 | 5,000円 支払う |
| Fさん | ほとんど払わなかった | 1,000円 | 7,000円 支払う |
この状態で**貪欲法(送金最小化)**を適用すると:
| 順番 | 送金する人 | 送金先 | 送金額 | 備考 |
|---|---|---|---|---|
| 1 | Fさん | Cさん | 7,000円 | |
| 2 | Eさん | Bさん | 5,000円 | |
| 3 | Dさん | Cさん | 1,000円 | Cさん精算完了 |
| 4 | Dさん | Aさん | 2,000円 | 全員の精算完了 |
送金回数は「4回」。しかし、人間関係の視点から見ると理不尽があります。
- Fさん(ほぼ払わなかった):Cさん「1箇所」だけで完了という最も楽な役回り。
- Dさん(5,000円払って手伝ってくれた):CさんとAさんの**「2箇所へ」**細かく送金しなければならず、銀行振込なら手数料も2回分。
次に「Dさんの送金先を1箇所に絞る」貢献者ファーストを適用すると:
| 順番 | 送金する人 | 送金先 | 送金額 | 備考 |
|---|---|---|---|---|
| 1 | Dさん | Bさん | 3,000円 | ✅ Dさん送金1箇所で完了 |
| 2 | Fさん | Cさん | 7,000円 | |
| 3 | Eさん | Bさん | 2,000円 | Bさん精算完了 |
| 4 | Eさん | Cさん | 1,000円 | Cさん精算完了 |
| 5 | Eさん | Aさん | 2,000円 | 全員の精算完了 |
送金回数は「5回」——貪欲法より1回増加しました。ただし、全体が文字通り小規模なグループ向けなら1回程度の増加は許容範囲とも言え、FAMI-KAN本体への実装候補として活発に検討したいアルゴリズムです。
Dさんを守った代わりに、Eさんの送金先が「1箇所」から「3箇所」へと増えてしまいました。これが「貢献者ファースト」の本質的なトレードオフです。
- 守られたDさん:送金先1箇所、手数料1回分で完了
- 割を食ったEさん:送金先3箇所、手数料3回分を負担。ここが解決すべき核心の問題です。
- Fさん:変わらず1箇所
「手伝ってくれた人を優遇する」感覚は正しいのですが、その裏で必ず誰かが多く負担するという構造は変わりません。そして、これが8人以上の規模になり、複数人が中途半端に立て替える複雑な状況になると、このしわ寄せは許容できなくなります。
⚠️ 人間関係を優先した際の問題
手伝って中途半端に支払ってくれた中堅メンバーたちの送金先を強引に**「最小(1箇所)」**に絞り込もうとすると、計算のしわ寄せが「財布を一度も出さなかった非貢献者」に一極集中します。
-
1度も財布を出さなかったメンバーの送金先が5箇所、6箇所へと増え続け、振込手数料だけで送金額を上回るような逆転現象が起きます。
-
さらに、登録不要(個人情報を取らない)というFAMI-KANのポリシーを守っているため、システム側には「誰と誰が知り合いか」の関係性データがありません。そのため、関係性を考慮した自動最適化をしようとすると、プログラム of 計算自体が無限ループに陥り、計算不能になります。
-
全体の送金回数を減らす(貪欲法) ──→ 中途半端に支払った人が余分な振込手数料を払い、気まずい相手への送金が発生する。
-
手伝った人を優遇する(貢献者優先) ──→ 何もしなかった人の送金先が増加し、手数料で破綻する。
この「人間の感覚とコンピューターの計算のジレンマ」は、今も未解決の課題として残っています。
「貢献者ファースト」は現時点ではFAMI-KANに未実装ですが、「1回程度の追加なら許容範囲ではないか」という感覚があり、将来のオプション実装の候補として積極的に検討しています。「少し役に立ててくれた人の負担をわずかに軽くする」という人間の心理を考慮した仕組みは、割り勘アプリに必要とされている機能の一つです。
5. おわりに:コードを書く前に、人間をデバッグしよう
FAMI-KANは現状でもメンバーごと・グループごとの支払いを記録できますが、現在挑もうとしている次なる大きな課題が、まさにこの「社会的気まずさ」の解決です。
目指しているのは、**「全体の送金回数を最小化しつつ、支払う相手は『自分が所属するグループ内(顔見知り)』に限定するアルゴリズム」**の実現です。
この難題をシステムに落とし込むため、現在いくつかの実装案を模索しています。
- 案1(グループ間ブリッジ送金):AグループからBグループに対して「グループ単位」で負債を計算し、両グループに共通して所属しているメンバー(橋渡し役)を経由して送金する仕組み。
- 案2(幹事プロキシ方式):グループを超えた支払いや、面識がない人同士の債権債務については、一度すべて代表の幹事を経由(集金・再分配)する仕組み。
しかし、どちらの案を採用するにしても、UI/UXが極端に複雑になってしまったり、特定の幹事に負担が集中しすぎたりと、まだ「これだ!」という完璧な正解には辿り着けていません。
プログラミングの知識が全くなくても、AIと一緒にここまでのロジックを組み、プロダクトをリリースできる時代になりました。
しかし、だからこそ痛感します。
「何を作るべきか(What)」「なぜ作るのか(Why)」という設計思想の部分、そして「使う人が現実の生活でどう感じ、どう困るのか」という人間の感覚のデバッグは、AIにはできません。人間が自らの思考でデバッグするしかないのです。
「数式の美しさ」のために、ユーザーの「不憫な手数料」や「社会的気まずさ」を見落としていないか。
FAMI-KANはまだまだ発展途上ですが、これからも「優しさのあるコード」をAIと一緒に模索し続けようと思います。もし「自分ならこのジレンマをこう解く!」というアイデアがあれば、ぜひコメント欄で知恵を貸してください!