式クラス
QUBO++の最も重要な機能は、組み合わせ最適化問題を解くための式を作成できることです。 この目的のために、以下の3つのクラスが使用されます:
| クラス | 内容 | 詳細 |
|---|---|---|
qbpp::Var |
変数 | 32ビットIDと表示用文字列 |
qbpp::Term |
積項 | ゼロ個以上の変数と整数係数 |
qbpp::Expr |
式 | ゼロ個以上の項と整数定数項 |
qbpp::Var class
このクラスのインスタンスは変数を記号的に表現する。 多くの場合、二進変数を表現するために使用される。 ただし、このクラスは特定の変数属性に関連付けられておらず、そのインスタンスはあらゆる型の変数を記号的に表現するために使用できる。
各 qbpp::Var インスタンスは単純に以下で構成される:
- 一意の32ビットID、および
- 表示用に使用される文字列。
例えば、以下のプログラムは qbpp::Var オブジェクトxを作成します。
このオブジェクトには自動生成されたIDが割り当てられ、表示用に文字列 "x" を文字列として表示します:
auto x = qbpp::var("x");
std::cout << x << std::endl;
これは単に x。
変数シンボルと同じ文字列を使用することが推奨されますが、
別の表示文字列を使用することも可能です:
auto x = qbpp::var("symbol_x");
std::cout << x << std::endl;
これは symbol_x.
qbpp::Term class
このクラスのインスタンスは、以下の要素を含む積項を表します:
- 整数係数、および
- ゼロ個以上の
qbpp::Varオブジェクト。
たとえば、次のプログラムは qbpp::Term オブジェクトtを作成します。
整数係数 2 と変数 x と y:
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto t = 2 * x * y;
std::cout << t << std::endl;
このプログラムは以下を出力します:
2*x*y`
qbpp::Expr class
このクラスのインスタンスは、以下の要素を含む式を表します:
- 整数定数項、および
- ゼロ個以上の
qbpp::Termオブジェクト。
例えば、次のプログラムは qbpp::Expr 定数項を持つfオブジェクトを作成します 3 と項 2*x*y と 3*x:
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto f = 3 + 2 * x * y + 3 * x;
std::cout << f << std::endl;
このプログラムは
3 +2*x*y +3*x
式は、基本演算子である +, -,) ,
および括弧( と* を使用して記述できます。
式は自動的に展開され、オブジェクトとして保存されます。 qbpp::Expr オブジェクトとして自動的に展開・保存されます。
例えば、以下のプログラムは qbpp::Expr オブジェクトfを作成します:
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto f = (x + y - 2) * (x - 2 * y + 3);
std::cout << f << std::endl;
このプログラムは以下を出力します:
-6 +x*x +y*x -2*x*y -2*y*y +3*x +3*y -2*x +4*y
これらの数学演算は式を展開するだけであることに注意してください。 式を簡略化するには、以下に示すように明示的に簡略化関数を呼び出す必要があります:
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto f = (x + y - 2) * (x - 2 * y + 3);
f.simplify();
std::cout << f << std::endl;
このプログラムは以下を出力します:
-6 +x +7*y +x*x -x*y -2*y*y
利用可能な簡略化関数と演算子の詳細については、 基本演算子と関数を参照してください。
式に関する重要な注意事項
qbpp::Term クラスは qbpp::Exprよりも単純なデータ構造であるため、
より少ないメモリを必要とし、操作オーバーヘッドも低くなります。
ただし、 qbpp::Term オブジェクトは完全な式を格納できません。
例えば、以下のQUBO++プログラムはコンパイルエラーとなる。
なぜなら t は qbpp::Term オブジェクトであるためです:
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto t = 2 * x * y;
t += 3 * x;
std::cout << t << std::endl;
式を保存・操作するには、明示的に
qbpp::Expr 関数qbpp::toExpr()を使用して明示的にオブジェクトを作成する必要があります。以下に示します:
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto t = qbpp::toExpr(2 * x * y);
t += 3 * x;
std::cout << t << std::endl;
このプログラムは qbpp::Expr オブジェクトtを作成し、以下を出力します:
2*x*y +3*x
オブジェクトが式を格納することを意図している場合、
整数、変数、または項からそれを構築するために qbpp::toExpr() 関数を使用して整数、変数、または項から構築することを推奨します:
auto x = qbpp::var("x");
auto f = qbpp::toExpr(0);
auto g = qbpp::toExpr(x);
auto h = qbpp::toExpr(3 * x);
std::cout << "f = " << f << std::endl;
std::cout << "g = " << g << std::endl;
std::cout << "h = " << h << std::endl;
このプログラムでは、 f, g, および h はすべて qbpp::Expr オブジェクトとして作成されます。
もし qbpp::toExpr() が使用されない場合、それらは代わりに int,
qbpp::Var、および qbpp::Termとなる。
例えば、以下のプログラムは
オブジェクト `f:` を使用して式を段階的に構築します。 qbpp::Expr オブジェクト `f:
auto x = qbpp::var("x", 4);
auto f = qbpp::toExpr(-1);
for (size_t i = 0; i < x.size(); ++i) {
f += x[i];
}
std::cout << f << std::endl;
このプログラムは以下を出力します:
-1 +x[0] +x[1] +x[2] +x[3]
ただし、 qbpp::toExpr() が使用されない場合、 f は int 変数となり、
演算子 += 演算子を適用する際にコンパイルエラーが発生します。