No.21 Corticonでシフト表を自動作成する1/2
2017.10.05 Progress Corticon
本エントリーは株式会社アシスト様が寄稿したエントリー(https://www.ashisuto.co.jp/product/category/brms/progress_corticon/column/detail/brmstech21.html)を転載したものとなります。
Corticon とは何かを端的に説明する際、「AI」, 「意思決定自動化ツール」, 「超高速開発ツール」といったキーワードで表現をすることが多いです。それぞれCorticonの一面を捉えた正しい表現ですが、そういった観点とは別のより技術的観点でCorticonを表現すると、「Corticon とはプログラミング言語の一種である」と言えます。Corticonは、通常のプログラミング言語とは異なり、効率的なパターンマッチングを実現するアルゴリズム(DETI)とエクセルライクなGUI画面が標準でついており、その画面上で条件等のルールを記述していくだけなので、一見プログラミング言語には見えません。しかし、入出力のデータやルールの記述とその処理の内容を詳細に追っていくと、Corticonのプログラミング言語としての一面が見えてきます。
Corticonとはどのようなプログラミング言語かをもう少しくわしく説明すると、「Corticonとは宣言型のプログラミング言語のひとつで、入力データ(ツリー構造XMLなど)を再帰的に処理することに特化したドメイン固有のプログラミング言語」です。
Corticonと他のプログラミング言語と比較して分類した図が以下になります。
この分類図上では、CorticonはSQLやXSLTなどと近くなっています。特にXSLTは、処理する対象のデータがツリー構造のXMLをメインにしていること、処理の内容や実装が宣言的・再帰的であることから、Corticonと非常に近い言語であると言えます。
また、Corticonのルール実装の考え方は基本的に宣言型・関数型プログラムの特徴が強く出ています。しかし、一方でCorticonにはルールフローという処理の順番/分岐/ループなどを設定する機能があり、このルールフロー機能を利用すると命令型/手続き型プログラムに近い考え方で実装することができます。分類図上で、Corticonが少し命令型・手続き型のほうに寄っているのは、このためです。
実際の案件では、条件(ルール)の数が多かったりその条件の組み合わせが複雑になることはあっても一つ一つの条件はシンプルなことが多く、入出力データも量はともかく構造は比較的シンプルなツリー構造であることが多いため、Corticonがプログラミング言語であることを意識することはあまりありません。
しかしまれに比較的複雑なアルゴリズムの実装が必要になる場合もあり、そのような場合はCorticonのプログラミング言語としての側面を意識した実装が必要になります。
今回の記事では、シフト表を自動作成するサンプルを題材に、Corticon独特の挙動とアルゴリズムの実装方法を解説します。
[記事執筆環境]
Corticon 5.5.2.30, および 5.6.1.6
シフト表を自動作成するサンプルルール
まず最初にシフト表を自動作成するルールの条件ですが、以下1~4としました。
- ルール へのインプットは複数の担当者情報(個数は可変)
- 担当者を割り当てる枠は5個で固定(枠1, 枠2, 枠3, 枠4, 枠5)
- それぞれの担当者には、担当することができない枠を複数設定できる。
- 連続した枠に、同じ担当者が連続して入ることはない。
サンプルとしてわかりやすいルールになるように、担当者情報は人数も含めて可変(入力値)ですが、枠の数や情報は固定し、EXCELライクなルールシート上に直接記述します。
■語彙の作成
このシフト表を自動生成するサンプルの入出力構造体定義である語彙(ecore)は、以下の設定で作成しました。
<語彙の設定表>
エンティティ名 | 説明 | |
担当者 | 入力データ。担当者情報。 | |
属性名 | 型 | |
氏名 | 文字列 | 担当者の氏名 |
関連性名 | カーディナリティ | |
不可枠 (不可枠) | 1->* | 「不可枠」エンティティとの関連性 |
エンティティ名 | 説明 | |
不可枠 | 入力データ。各担当者情報に属する不可枠情報。 | |
属性名 | 型 | |
枠名 | 文字列 | その担当者が担当できない枠名 |
エンティティ名 | 説明 | |
シフト表 | 出力データ。シフト表の候補 | |
属性名 | 型 | |
枠1担当者 | 文字列 | 枠1の担当者 |
枠2担当者 | 文字列 | 枠2の担当者 |
枠3担当者 | 文字列 | 枠3の担当者 |
枠4担当者 | 文字列 | 枠4の担当者 |
枠5担当者 | 文字列 | 枠5の担当者 |
この語彙(ecore)をCorticon Studioで表示させた図は以下です。
■ルールシートとテスト(入力値)の作成
次に以下のルールシートを作成しました。
スコープの部分で同じ「担当者」エンティティを5個設定し、それらに「枠1担当」, 「枠2担当」, 「枠3担当」, 「枠4担当」, 「枠5担当」という別々のエイリアスを設定していること、それぞれのエイリアスの下の「不可枠」エンティティに対して「不可枠1」, 「不可枠2」, 「不可枠3」, 「不可枠4」, 「不可枠5」というエイリアスを設定していることに注意してください。
このルールシートを対象としたテストを作成し、入力値として以下の3つの担当者情報を作成しました。(※)
- ※担当者情報や不可枠情報は可変なので必ずしもこの入力値でないといけないわけではありませんが、
以下の解説はこの入力値を前提としています。
■ルールの実行結果と解説
作成したテストを実行すると、結果の出力は以下になります。
入力した担当者情報から、条件に合致した組み合わせのシフト表が2個自動出力されていることがわかります。
なぜ、作成したルールと入力値でこのような出力結果を得ることができるのか、以下の1~3のCorticonの基本的な動作から解説します。
1.入力された全データに対する再帰的な処理
Corticonでは、デフォルトで、処理対象とみなされたエンティティの全入力値が再帰的に処理されます。したがって、全入力値に対してループ処理したい場合は特別な指定をする必要はありません。(※)
- ※逆に、入力値の一部分だけ処理したい場合、Corticonでは命令形言語のように配列を取り扱わないので、工夫が必要です。
例えば入力されたエンティティデータが3個あって、2番目の入力だけ処理したい場合などです。その方法は次回の記事で解説します。
2.スコープのエイリアスとフィルタ
ルールシートのスコープ部でエンティティにエイリアスを設定すると、元エンティティのデータは、エイリアス計算用のデータとして一時的にコピーされます。ルールシート内で、そのエイリアスに関連する評価があった場合は、その計算用データが使用されます。(※)
また、同じエンティティに対して複数のエイリアスを設定することもできます。そうした場合、元エンティティのデータがそれぞれのエイリアスにコピーされ、元エンティティは同一であってもルールシート内ではあたかも別のエンティティのデータのように取り扱うことができるようになります。
なお、エイリアスに対してフィルタ設定を行うと、コピーされた計算用データを対象にフィルタリングされます。
- ※「長いエンティティ名を省略するため」や「コレクション演算子を使用するため」という用途でエイリアス機能を使用する場合には、
この挙動はあまり意識する必要はありません。
3.総当り評価
Corticonでは、条件部やアクション部で、一箇所に複数のエンティティもしくはエイリアスを記述すると、それぞれのデータの全組み合わせをパターンマッチングアルゴリヅムが総当りで評価します。
例えば、ルールシートの条件部で、「エンティティA.属性A = エンティティB.属性B」と記入し、エンティティAとエンティティBそれぞれのデータが複数あれば、「エンティティA.属性A」と「エンティティB.属性B」の全組み合わせについて総当りで一致しているかどうかの判定を行います。 つまり、エンティティAが10個、エンティティBが50個あると、10 * 50 = 500回の判定が行われます。これはエンティティではなくエイリアスであっても同様です。
今回のルールでは、これらの3つのCorticonの基本的な挙動の組み合わせによって、シフト表の候補を出しています。
具体的に今回のサンプルでのデータと処理の流れを追うと、以下の①~⑤のイメージです。
①エンティティ「担当者」の入力値は以下の3つ。
②スコープのエイリアス設定によって、エンティティ「担当者」の3つのデータが、それぞれのエイリアスの計算用データとしてコピーされる。
③フィルタ設定によってそれぞれのエイリアスの計算用データがフィルタリングされる。フィルタリングの条件は、それぞれの担当者情報の下の子エンティティ「不可枠」に該当する枠名が含まれているかどうか。
④条件部のルールで隣り合った担当者エイリアス同士がそれぞれ比較されてる。そのため、隣り合った各エイリアスの計算用データの全組み合わせを総当りで評価する。なお、条件部のルールは「隣り合っている担当者エイリアス間で同じ担当者が連続しない」というもの。
⑤全経路を評価した結果、同じ担当者が隣り合わない経路のときだけ、アクション部のnew演算子で出力データを作成する。この場合は正解の探索経路が2種類なので、「シフト表」エンティティを2個新規に作成する。
まとめ
いかがでしたでしょうか。Corticonはチューリング完全なプログラミング言語の一種なので、このような問題を解くことができます。
また、今回の記事の題材としてはシフト表でしたが、同じようなアルゴリズム(ナップサック問題、最短経路問題など)
のサンプルが、プログレス社のサイト にいくつかあります。
しかし、今回のような簡単なシフト表は説明のためのサンプルであり、実際には応用しにくいかもしれません。
今回のシフト表は担当者情報が可変であることを前提に作っているため、今回のシフト表をベースに少し修正すれば、担当者情報については様々な条件を足したりすることができます。しかし、ルールと語彙をシンプルにするために、枠情報の数は5個固定であり枠の方には何も条件がないことを前提としています。実際のシフト表では「枠数のほうも変えたい」や「枠のほうにも何か条件を入れたい」といった要件(つまり、枠の情報も入力データとしてパラメータ化したい)があると思われます。そのような要件の場合、ルールフローのループの機能などを利用し、もう少し複雑なアルゴリズムを実装する必要があります。
次回の記事では、枠の情報も入力データとしてパラメータ化した、もう少し本格的なシフト表のサンプルをご紹介します。
No.22 Corticonでシフト表を自動作成する2/2
著者紹介
情報基盤技術統括部 プログレス推進部 |