case04(再構築デモ): 攻撃の仕様 — 5/7¶
攻撃の設計 の手順を、具体的な制約に落とし込みます。実際のコードと実行は ② Colab で(制約ソルバ CP-SAT / OR-Tools を使います)。
前提(攻撃者が持っているもの)¶
- 公表統計表(人数・中央値・平均、14行・うち7行は秘匿)。
- 表ラベルの意味(「女性」「黒人女性」「既婚の成人」などのグループ定義)。これは公表表を読めば分かる一般知識。
- 元の個票は持っていない。
変数の置き方¶
- 人を1人ずつ未知数にする。総人口の公表値から7人と分かる。
- 各人
iに:年齢(0〜115の整数)、女性/黒人/既婚(各 0/1)。 - 対称性の除去: 年齢の昇順に並べる(
age[0] ≤ age[1] ≤ …)。人の集合が同じなら並べ替えても同じデータなので、7! 通りの重複解を防ぐだけで、答えには影響しない。 - 常識の制約: 未成年(18歳未満)は独身として記録される。
主なルール(公表行 → 制約)¶
- 人数: 「そのグループに属する人数 = 公表値」。例: 女性は4人。
- 平均 → 合計の区間: 公表値は小数第1位に丸め。
ceil((mean−0.05)×count) ≤ 合計 ≤ floor((mean+0.05)×count)。例: 黒人女性 平均36.7×3人 → 合計は 110 の一択。 - 中央値 → 順序統計量: 年齢の昇順に並んでいるので、「グループの k 番目の人」の年齢を指せる。奇数人なら中央の人、偶数人なら中央2人の平均(2倍して整数で書く)。
- 秘匿された行: 制約を1本も与えない(情報が無いだけ)。それでも解は一意に決まる。
CP-SAT で書くときの工夫
- 変数どうしの掛け算は書けないので、「グループに属せば年齢、属さねば0」という補助変数を条件付きで定義して合計を作る。
- 中央値は「i がグループの k 番目 = i はグループ員 かつ 先行するグループ員が k−1 人」という条件で表す。
- 全解列挙(
enumerate_all_solutions)で解を数え尽くし、1通りかどうかを判定する。
攻撃仕様一覧(公表行ごと)
| 表番号 | グループ | 与える制約 |
|---|---|---|
| 1A | 総人口 | 人数7/合計区間(平均38)/中央値30 |
| 2A | 女性 | 人数4/合計区間(平均33.5)/中央値30 |
| 2B | 男性 | 人数3/合計区間(平均44)/中央値30 |
| 2C | 黒人 | 人数4/合計区間(平均48.5)/中央値51 |
| 2D | 白人 | 人数3/合計区間(平均24)/中央値24 |
| 3B | 既婚の成人 | 人数4/合計区間(平均54)/中央値51 |
| 4A | 黒人女性 | 人数3/合計区間(平均36.7)/中央値36 |
| 3A,4B–4D,5A–5C | 独身の成人・黒人男性 ほか | 秘匿 → 制約なし |
小さな問題だが本質は同じ
7人・7行の小さな問題なので、CP-SAT は一瞬で全解を数え尽くします。実際の国勢調査はブロック数・属性数が桁違いに大きくなりますが、「多数の正確な統計 → 個票が定まる」という構造は同じです。
→ 実行は ② 実装(Colab)、復元後の個票は 復元後テーブル、結果と対策は ③ 結果。