1

(注:この質問は、IBMのILOG CPLEX C ++ API、2007年頃のドキュメントがここでHTTP経由でPDFになっていること、およびIBMのFTP経由で入手できる「バージョン12」の現在の資料に関連しています)

行列変数があり、それらの値を行列パラメーターに転送したいと思います。これは私がしたことです:

typedef IloArray<IloNumArray> NumMatrix;
typedef IloArray<IloBoolVarArray> BoolVarMatrix;

NumMatrix ystar(env,I);
for(IloInt i = 0; i < I; i++){
    ystar[i] = IloNumArray(env, T);
}

BoolVarMatrix y(env,I);
for(IloInt i = 0; i < I; i++){
    y[i] = IloBoolVarArray(env, T);
}

for(IloInt i = 0; i < I; i++)
    cplex_master.getValues(ystar[i],y[i]);

しかし、どうやらgetValues()でのみ動作しIloNumVarArrayます。どうすればこれを修正できますか?

4

2 に答える 2

1

ゲームの時間を推測します!cplex_master:-)私はそれがタイプであると推測するつもりですIloCplex

2つの新しく初期化された2次元行列があります。1つは「ブール変数」で、もう1つは「非変数浮動小数点数」です。でブール変数を解き、y結果をで浮動小数点数として表すようにしystarます。

  1. 空白の行列を互いに解決することで何が達成されるかわからないので、実際のコードでは空白ではないふりをします

  2. あなたのシナリオがブール行列を行方向に浮動小数点数に変換しているのかわかりませんが、それはどういうわけか正当なことかもしれません

とにかく、IloCplexの4つのバリアントを提供します。これらはすべて、 varvalgetValues()という名前の2つのパラメーターで動作するようです。

public void getValues(const IloIntVarArray var, IloNumArray val) const
public void getValues(IloNumArray val, const IloIntVarArray var) const
public void getValues(const IloNumVarArray var, IloNumArray val) const
public void getValues(IloNumArray val, const IloNumVarArray var) const

それらはすべて、次のような効果のある同様のドキュメントを持っています。

このメソッドは、配列varで指定された整数変数の解の値を配列valに入れます。配列valは配列varと同じサイズにサイズ変更され、val[i]には変数var[i]の解の値が含まれます。

値によって渡されているという事実にもかかわらず、valが変更されているという点で、珍しい設計上の選択があります。これは非常に非C++スタイルです。整数を扱っている場合は、たとえば、次のようなコードを記述します。

void myCopy(const int source, int destination) {
    /* what could go here? */
}

void someFunction() {
   int a = 10;
   int b;
   myCopy(a, b);
}

myCopy()...そのプロトタイプでルーチンを作成する方法はありません。宛先は値によって渡されたため、呼び出し元myCopy()に戻っての値を変更することはできません。b適切なC++は、ポインタまたは参照を使用して(を介して&)それを行います。

void myCopy(const int source, int& destination) {
    destination = source;
}

したがって、このCPLEX C ++は、内部で何らかのトリックを使用します。その不思議なenvパラメーターを介して、別の方法で処理を実行すると思います。それは、人々が奇妙な言語ラッパーを書き、イディオムを知らないときに起こる典型的なケースに苦しんでいます。ここでは別の投稿が非常に重要です。

それは私だけですか、それともCplex Concert APIでいくつかの改善を使用できますか?

あなたの質問は、 varvalとしてaをとることが幸せであるのに、なぜがvarvalとしてIloCplexとらないのかということかもしれません。結局のところ、継承は...同じスロットで使用できるべきではないでしょうか?IloBoolVarArrayIloNumArray IloIntVarArrayIloNumArray IloBoolVarArrayIloIntVarArray

ただし、メソッドのこれらの値渡しのセマンティクスは、他のgetValue()方法では機能していた可能性のある自然な継承を抑制します。ポインタまたは参照を渡す場合は、基本クラスの代わりに派生クラスのみを渡すことができます。だから、これに行かないでください。

IloBoolVarArrayの代わりに本当に使用したい場合はIloIntVarArray、中間を通過する必要があると思います。

typedef IloArray<IloNumArray> NumMatrix;
typedef IloArray<IloBoolVarArray> BoolVarMatrix;
typedef IloArray<IloIntVarArray> IntVarMatrix;

NumMatrix ystar(env,I);
for(IloInt i = 0; i < I; i++){
    ystar[i] = IloNumArray(env, T);
}

BoolVarMatrix y(env,I);
for(IloInt i = 0; i < I; i++){
    y[i] = IloBoolVarArray(env, T);
}

IntVarMatrix yint(env,I);
for(IloInt i = 0; i < I; i++){
    for(IloInt t = 0; t < T; t++) {
        yint[i][t] = y[i][t];
    }
}

for(IloInt i = 0; i < I; i++)
    cplex_master.getValues(ystar[i],yint[i]);

本当の問題は、IloBoolvs 。を使用するIloInt価値があるかどうかということかもしれません。それは後付けのように見えます:

このタイプ定義は、ConcertTechnologyのブール値を表します。これらの値はIloTrueとIloFalseです。実際、ブール値はIloInt型の整数です。IloFalseは0(ゼロ)であり、IloTrueは1(1)です。このタイプは、標準C++用に提案された組み込みのboolタイプを想定しています。このタイプを使用することにより、アプリケーションのコンサートテクノロジーコンポーネントが、異なるハードウェアプラットフォーム間でソースを変更することなく、この点で確実に移植されます。

配列はソルバーで一流の扱いを受けていないようですが、個々の変数には次のような扱いがあります。

IloBoolVarのインスタンスは、クラスIlcBoolVar(ILOG Solverリファレンスマニュアルにも記載されています)のインスタンスとしてIloSolver(ILOG Solverリファレンスマニュアルに記載されています)によって抽出されます。

IloBoolVarのインスタンスは、IloCplex(ILOG CPLEXリファレンスマニュアルに記載されています)によって、IloBoolVarで指定された境界を持つBool型の数値変数を表す列として抽出されます。

それを完全に回避することが最善の答えだと思います。

于 2012-04-26T00:19:53.997 に答える
1

IloCplex :: getValueは、任意のIloNumVarに使用できます。戻り値はdoubleであるため、Concertデータ構造に制限されません。式y[i][t]は、IloNumVarを提供します。

   for(IloInt i = 0; i < I; i++)
        for (IloInt t = 0; t < T; ++t)
        ystar[i][t] = cplex_master.getValue(y[i][t]);
于 2012-04-26T03:20:37.837 に答える