小学生のたかし君
たかし君のクラスでは、2か月に1回くらい席替えをします。
くじ引きで決めたり、班のグループを先に決めたりといろいろな方法で決めています。 どんな方法で決めても、喜んだり、悲しんだり大騒ぎです。
くじ引きで決めたり、班のグループを先に決めたりといろいろな方法で決めています。 どんな方法で決めても、喜んだり、悲しんだり大騒ぎです。
そこで
席替え用のプログラムを作ってみることにしました。
ミッション
必須条件を満たし、各自の希望をできるだけ叶える席配置を求めよ。
必須条件
- 視力が悪い人は前から2列目まで。
- 背が高い人のすぐ後ろが背の低い人にならないようにする。
- 隣り合わせNGの組み合わせが数組ある。その人たちが隣り合わせにならないようにする。
(通路を挟んでの隣はOK)
机配置と希望エリア
机配置は以下の通りです。
各自、以下のいずれかのエリアを希望しています。
・最前列
・最後列
・窓際2列
・中央2列
・廊下側2列
メンバー表
ID | 背の高さ | 視力 | 隣NG | 希望エリア |
---|---|---|---|---|
01 | 低い | 良 | 22 | 最前列 |
02 | 低い | 良 | - | 最前列 |
03 | 低い | 良 | - | 最後列 |
04 | 低い | 良 | - | 最後列 |
05 | 低い | 良 | 10 | 窓際2列 |
06 | 低い | 悪 | - | 窓際2列 |
07 | 低い | 良 | - | 窓際2列 |
08 | 低い | 良 | - | 廊下側2列 |
09 | 低い | 良 | - | 中央2列 |
10 | 低い | 良 | 05 | 中央2列 |
11 | ふつう | 良 | - | 最前列 |
12 | ふつう | 良 | - | 最前列 |
13 | ふつう | 良 | - | 最後列 |
14 | ふつう | 良 | - | 最後列 |
15 | ふつう | 良 | 20 | 窓際2列 |
16 | ふつう | 悪 | - | 窓際2列 |
17 | ふつう | 悪 | - | 廊下側2列 |
18 | ふつう | 良 | - | 廊下側2列 |
19 | ふつう | 良 | - | 中央2列 |
20 | ふつう | 良 | 15 | 中央2列 |
21 | 高い | 良 | - | 最前列 |
22 | 高い | 悪 | 01 | 最前列 |
23 | 高い | 良 | - | 最前列 |
24 | 高い | 良 | - | 最後列 |
25 | 高い | 良 | - | 最後列 |
26 | 高い | 悪 | - | 窓際2列 |
27 | 高い | 良 | - | 廊下側2列 |
28 | 高い | 悪 | - | 廊下側2列 |
29 | 高い | 良 | - | 中央2列 |
30 | 高い | 良 | - | 中央2列 |
考え方
30人の席順の組み合わせの数は30!(1から30まですべて掛け合わせた値)。10の32乗を超えます。
すべての席順を比較するのは現実的ではありません。
そこで、このミッションでは、局所探索法というアプローチを使ってみることにします。
具体的には、以下のアルゴリズムで最適解を見つけていきます。
- 番号順に並べる。
- 必須条件違反は-10点、要望を叶えたら+1点として点数を計算。
- ランダムに3人選んで席を入れ替えて、点数を計算。
- 入れ替える前と比べて、悪化していたり、点数が変わらなければ入れ替えない。
- 3,4を20,000回繰り返す。
ヒント
キーとなるアルゴリズムの実装例です。
ヒント1:3つの重複しないランダムな数字を作る
ヒント2:3つの要素の順番を入れ替える
自分でプログラムを作成するのは、ここから。
[+]ボタンを押すと新たに作成できます。
チュートリアル
完成形
完成形のプログラム例はこちら。
プログラム例:席替え大作戦