はじめに
久しぶりの投稿として,数ヶ月前にやってみた数学の遊びについて書いてみます。
X(旧Twitter)で,5 × 5の行列を眺めていたら,「ビンゴみたい」と言われた──というポストを見かけました。なるほど25個の数が正方形の形に並んでいたらビンゴに見えますね。ならば,1 ~ 25の自然数がそれぞれ1回ずつ使われた5 × 5行列を「ビンゴ行列」と呼ぶこととし,ランダムに配られたビンゴ行列の──そうですね,行列式が最も大きいものが勝ち,としてみましょう。さて,このとき,最強のビンゴ行列,つまり理論上可能な最大の行列式はいくつでしょうか?
1 ~ 25の自然数をそれぞれ1回ずつ使った5 × 5行列をビンゴ行列と呼ぶとき,ビンゴ行列として可能な最大の行列式はいくつか? また,そのビンゴ行列は何か?
例えば綺麗に数字が並んだ場合,
となります。一方,1と2,16と25をそれぞれ入れ替えた場合,
となります。数の並び方を工夫すれば,もっと大きな行列式が作れるでしょう。しかし,最大値は何でしょうか? これは組み合わせ最適化問題と言えそうですね。今回はこれを考えてみようと思います。
AIに頼る
膨大な計算時間
単純計算でビンゴ行列は25! = 15,511,210,043,330,985,984,000,000個あります。すべてのケースの行列式を計算するとして,1つあたり1 μsで計算できたとしても,15,511,210,043,330,985,984 s = 491,857,243,890年 ≃ 4,920億年を要します。行列式は転置しても変わらず,行と行を入れ替えても,列と列を入れ替えても,符号が変わるのみで絶対値は変わりません。これらの性質を利用すれば,計算の回数は減らせるはずですが,膨大な時間を要するという点は変わらないように思えます。
ChatGPTに聞いてみる
どうしたものか…せや!こんなときこそAIだ! ChatGPTに質問してみました。図1にその様子を貼り付けます。

import numpy as np import random import math def initial_matrix(): numbers = list(range(1, 26)) random.shuffle(numbers) return np.array(numbers).reshape(5, 5) def calculate_score(matrix): return abs(np.linalg.det(matrix)) def get_neighbor(matrix): new_matrix = matrix.copy() i1, i2 = random.sample(range(25), 2) x1, y1 = divmod(i1, 5) x2, y2 = divmod(i2, 5) new_matrix[x1][y1], new_matrix[x2][y2] = new_matrix[x2][y2], new_matrix[x1][y1] return new_matrix def simulated_annealing(iterations=100000, initial_temp=1000, cooling_rate=0.003): current = initial_matrix() current_score = calculate_score(current) best = current best_score = current_score temp = initial_temp for step in range(iterations): neighbor = get_neighbor(current) neighbor_score = calculate_score(neighbor) delta = neighbor_score - current_score if delta > 0 or random.random() < math.exp(delta / temp): current = neighbor current_score = neighbor_score if current_score > best_score: best = current best_score = current_score temp *= (1 - cooling_rate) return best, best_score # 実行例 if __name__ == "__main__": best_matrix, best_det = simulated_annealing() print("最大行列式:", best_det) print("対応する行列:\n", best_matrix)
実行しますかと問われたので,実行してくださいとお願いしました。すると,下図のような結果が得られました。

という答えを叩き出しました! 680万に迫るか!
ローカルでも試す
ChatGPTの提示したPythonコードをローカルのJupyterLabでも走らせてみました。筆者は最近,UMPCを1台新たに導入しました。Zwide NA08Hです。図3のように若干重いながらもBlenderを動かすこともできます。以前使用していた愛機ASUS*2 TransBook T90 Chiの代わりですね。

ランダムで生成している初期行列が異なるためか,このような結果が得られます。683万まで来ました!
まとめ
その後もパラメータを変えて試行錯誤してみましたが,680万前後となって劇的に変わることはありませんでした。どうやらビンゴ行列の行列式の最大値は680万あたりであろうことは分かりました。真の最大値は分かるのでしょうか? 別のアルゴリズムで探してみるなど他にもアプローチがあるかもしれません。
今回は,思いついた数学の問題に対してAIの力を借りるという試行でした。今後,制御工学やパワーエレクトロニクスの勉強・野良研究を続けていく上でAIが味方になってくれるのであれば大変心強いですね。