はじめに
本記事シリーズは母国語のプログラミング言語が存在するという文化的価値をアピールするためのもので、プログラミング一般の入門を意図するものではありません。とはいっても題材としては定番アルゴリズムのいくつかを疑似言語ではなくコンパイル・実行可能なプログラミング言語の日本語で書いてみようというたてつけとなります。
Mind(マインド)
プログラミング言語Mind(マインド)は自然な日本語で記述できるスタック指向の軽量中間コードコンパイラ言語です。ただし単語間の分かち書きが必須であくまで形式言語です。逆ポーランド記法1の範囲で分かち書きされた日本語単語の語順が自然と日本語の語順となるという意味の「自然さ」で書くことができ、独自の軽量中間コードのランタイム実行で非常に高速です。実装言語はCまたはMind。初版の登場は1985年で2025年は生誕40周年となりました。
Mind(マインド)の入手方法
無償版のMind version 8 (windows版linux版)を下記の公式サイトからダウンロードできます。フリーメールでかまいませんのでメールアドレスをご登録くださいませ。
定番アルゴリズム:負閉路検出付きワーシャル‐フロイド法とは
アルゴリズムは、問題を解決するための手順や計算方法を意味します。アルゴリズムにはいくつかの定番ロジックが存在します。
ここではその中のひとつ「負閉路検出付きワーシャル‐フロイド法」を扱ってみます。「ワーシャル‐フロイド法」はすべての頂点から他のすべての頂点への最短距離と経路を求めるためのロジックです。今回は負閉路を想定した状態で考察します。
負閉路を想定しない「ワーシャル‐フロイド法」はこちらの記事をご参照ください。
お題のソースコード
今回は下記のような経路を想定します。数字は頂点の番号で4つの頂点があるとします。かっこ値は頂点間のかっこ値は頂点間の距離(コスト:重み)を意味します。
コスト:重みはおおむね距離(単位:長さ)と考えて問題はありませんが、マイナスのコストを考慮する場合は、その他の属性ウエイト:重みを加味したなんらかの総合値と考えた方がよい場合があります。(距離に近い属性であれば方向とか)
1 --(4)--> 2 --(6)--> 3 --(2)--> 4
^ |
| |
+ --(-7)-- +
上記のグラフの頂点間の関係を分割すると下記のようになります。
1 → 2 (距離 4)
2 → 3 (距離 6)
3 → 4 (距離 2)
4 → 3 (距離 -7) 負閉路:3 → 4 → 3(2 + (-7) = -5)
Mindの配列の添え字の基数は1から始まりますので、下記のような2次元配列で上記の経路を記述します。
距離[1, 2] = 4;
距離[2, 3] = 6;
距離[3, 4] = 2;
距離[4, 3] = -7;← 3→4→3 が負閉路(2 + (-7) = -5)
また、上記の疑似言語表現では一般的なプログラミング言語の配列表現でかぎカッコを使っていますが、Mindの場合はかっこ()表記となります。
頂点数最大は 定数 4頂点。
グラフは 構造体
頂点は 変数
頂点距離は 変数
各頂点距離は 頂点と 頂点数最大の 頂点距離
全体は 頂点数最大の 各頂点距離。
Mindの場合、2次元配列は構造体で定義されます。(引用時は基底の変数名を中かっこでインデックス1、2で表現します。)
初期化処理は頂点番号1と2の2重ループによるものとしています。
グラフを初期化するとは (・ → ・) 本定義
頂点No1は 変数
頂点No2は 変数
頂点No1に 1を 入れ
頂点数最大で 回数指定し
頂点No2に 1を 入れ
頂点数最大で 回数指定し
頂点No1と 頂点No2が 等しい
ならば
頂点距離(頂点No1、頂点No2)に 0を 入れ
さもなければ
頂点距離(頂点No1、頂点No2)に ∞を 入れ
つぎに
頂点No2を 一つ増加
繰り返す
頂点No1を 一つ増加
繰り返し
頂点距離(1、2)に 4を 入れ
頂点距離(2、3)に 6を 入れ
頂点距離(3、4)に 2を 入れ
頂点距離(4、3)に -7を 入れること。
同じ頂点番号の場合は0を、そうでなければ∞をセットします。その後、頂点同士の距離をセットします。
∞は 定数 1000000000。 (10億)
∞は経路の距離に対して十分大きな無限大と言える値です。今回も10億としています。
「ワーシャル‐フロイド法」の場合、負閉路の最短距離はインデックス1,2の値が同じ配列に集約されますので、下記のように1重ループで負閉路の存在を判定できます。
負閉路を検出するとは (・ → 真偽) 本定義
検出済は 変数
検出済を クリアし
頂点数最大で 回数指定し
頂点距離(回数、回数)が 0より 小さい
ならば
検出済を セットし
打ち切り
つぎに
繰り返し
検出済を 返すこと。
下記がソースコード全文となります。
∞は 定数 1000000000。 (10億)
頂点数最大は 定数 4頂点。
グラフは 構造体
頂点は 変数
頂点距離は 変数
各頂点距離は 頂点と 頂点数最大の 頂点距離
全体は 頂点数最大の 各頂点距離。
グラフを初期化するとは (・ → ・) 仮定義。
負閉路を検出するとは (・ → ・) 仮定義。
ワーシャル‐フロイド法で最短経路を求めるとは (・ → ・) 仮定義。
結果を表示するとは (・ → ・) 仮定義。
メインとは (・ → ・)
グラフを初期化し
ワーシャル‐フロイド法で最短経路を求め
結果を表示し
負閉路を検出した
ならば
「負閉路の存在を検出しました。」を 一行表示し
つぎに。
グラフを初期化するとは (・ → ・) 本定義
頂点No1は 変数
頂点No2は 変数
頂点No1に 1を 入れ
頂点数最大で 回数指定し
頂点No2に 1を 入れ
頂点数最大で 回数指定し
頂点No1と 頂点No2が 等しい
ならば
頂点距離(頂点No1、頂点No2)に 0を 入れ
さもなければ
頂点距離(頂点No1、頂点No2)に ∞を 入れ
つぎに
頂点No2を 一つ増加
繰り返す
頂点No1を 一つ増加
繰り返し
頂点距離(1、2)に 4を 入れ
頂点距離(2、3)に 6を 入れ
頂点距離(3、4)に 2を 入れ
頂点距離(4、3)に -7を 入れること。
負閉路を検出するとは (・ → 真偽) 本定義
検出済は 変数
検出済を クリアし
頂点数最大で 回数指定し
頂点距離(回数、回数)が 0より 小さい
ならば
検出済を セットし
打ち切り
つぎに
繰り返し
検出済を 返すこと。
ワーシャル‐フロイド法で最短経路を求めるとは (・ → ・) 本定義
頂点Noは 変数
頂点No1は 変数
頂点No2は 変数
新しい距離は 変数
頂点Noに 1を 入れ
頂点数最大で 回数指定し
頂点No1に 1を 入れ
頂点数最大で 回数指定し
頂点No2に 1を 入れ
頂点数最大で 回数指定し
頂点距離(頂点No1、頂点No)と ∞が 等しい
または 頂点距離(頂点No、頂点No2)と ∞が 等しい
でなければ
頂点距離(頂点No1、頂点No)と 頂点距離(頂点No、頂点No2)を 加えて
新しい距離に 入れ
新しい距離が 頂点距離(頂点No1、頂点No2)より 小さい
ならば
頂点距離(頂点No1、頂点No2)に 新しい距離を 入れ
つぎに
つぎに
頂点No2を 一つ増加
繰り返す
頂点No1を 一つ増加
繰り返し
頂点Noを 一つ増加
繰り返すこと。
結果を表示するとは (・ → ・) 本定義
頂点No1は 変数
頂点No2は 変数
「各頂点間の最短距離結果」を 一行表示し
頂点No1に 1を 入れ
頂点数最大で 回数指定し
「頂点No1:」を 表示し 頂点No1を 数値表示し 改行し
頂点No2に 1を 入れ
頂点数最大で 回数指定し
「 頂点No2:」を 表示し 頂点No2を 数値表示し 改行し
頂点距離(頂点No1、頂点No2)が ∞を 2で 割った 以上
ならば
「 ∞」を 一行表示し
さもなければ
「 」を 表示し 頂点距離(頂点No1、頂点No2)を 数値表示し 改行し
つぎに
頂点No2を 一つ増加
繰り返す
頂点No1を 一つ増加
繰り返すこと。
お題のソースコードをコンパイル
では、コンパイルしてみます。Mind8によるコンパイル結果です。
C:\developments\vscode\mind9\algorithm>mind floydwarshallnegative file
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> floydwarshallnegative.exe
実行結果
実行結果です。
C:\developments\vscode\mind9\algorithm>floydwarshallnegative
各頂点間の最短距離結果
頂点No1:1
頂点No2:1
0
頂点No2:2
4
頂点No2:3
5
頂点No2:4
7
頂点No1:2
頂点No2:1
∞
頂点No2:2
0
頂点No2:3
1
頂点No2:4
3
頂点No1:3
頂点No2:1
∞
頂点No2:2
∞
頂点No2:3
-5
頂点No2:4
-3
頂点No1:4
頂点No2:1
∞
頂点No2:2
∞
頂点No2:3
-12
頂点No2:4
-10
負閉路の存在を検出しました。
かなり芸のない出力ですが、各頂点同士の距離が算出され、負閉路が検出されました
「ワーシャル‐フロイド法」は頂点数でしか回さないので、その回数の中で見つかった一番小さい値が算出されています。
| from\to | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| 1 | 0 | 4 | 5 | 7 |
| 2 | ∞ | 0 | 1 | 3 |
| 3 | ∞ | ∞ | -5 | -3 |
| 4 | ∞ | ∞ | -12 | -10 |
おわりに
いかがでしたでしょうか?わたしはわが国に母語によるプログラミング言語が存在することを誇りに思っております。言語は文化。こんにちの日本語のポップスやアニメソングなどが海外でそのまま歌われるような近況を鑑みますと、純然たる技術基盤として超強力な米欧発プログラミング言語勢と存在意義を争うこともなく、日本語の文化として海外でも日本語プログラミング言語の愛される日が来るのやもしれません。
-
演算子を被演算子の中間に記述する中置記法 1 + 2、前に記述する前置記法(ポーランド記法)+ 1 2、後に記述する後置記法(逆ポーランド記法)1 2 +がある。日本語は1と 2を 足す。 ↩