CPLEX C APIを使用したMIP最適化中に、現在のノード(つまり、nノードごと)の線形緩和(二重変数、コスト削減など)を取得できますか?CPLEX MIP現在のノードLP緩和
新しいノードが利用可能になるたびに通知されるようにコールバック関数(CPXsetsolvecallbackfunc)を登録しました。コールバックでは、CPXgetcallbackinfoを使用してノード情報を取得し、CPXgetcallbacknodelpを使用してリニアリラクゼーションを取得しますが、残念ながらCPXソリューションは解決策が存在せず、MIP最適化が終了します。
ここでは、環境と問題が適切に初期化されていると想定されるIBM exampleから始まるサンプルコードを示します。
struct noderange {
int startnode;
int endnode;
};
typedef struct noderange NODERANGE;
NODERANGE nodeswritten;
nodeswritten.startnode = -1;
nodeswritten.endnode = 2100000000;
status = CPXsetsolvecallbackfunc(environment, usersolve, &nodeswritten);
if(status) {goto TERMINATE;}
status = CPXmipopt(environment, problem);
if(status) {goto TERMINATE;}
私は問題を発見
static int CPXPUBLIC usersolve(CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p) {
int status = 0;
int nodecount;
static int count = 0;
CPXLPptr nodelp;
NODERANGE *nodeswritten;
*useraction_p = CPX_CALLBACK_DEFAULT;
nodeswritten = (NODERANGE *)cbhandle;
/* Find out what node is being processed */
status = CPXgetcallbackinfo(env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT, &nodecount);
if (status) goto TERMINATE;
if (nodecount >= nodeswritten->startnode && nodecount <= nodeswritten->endnode) {
/* Get pointer to LP subproblem, then write a SAV file. */
status = CPXgetcallbacknodelp(env, cbdata, wherefrom, &nodelp);
if (status) goto TERMINATE;
int rows = CPXgetnumcols(env, nodelp);
int cols = CPXgetnumrows(env, nodelp);
int lpstat;
double objval;
double* x = (double*)malloc(sizeof(double) * CPXgetnumcols(env, nodelp));
double* dj = (double*)malloc(sizeof(double) * CPXgetnumcols(env, nodelp));
double* pi = (double*)malloc(sizeof(double) * CPXgetnumrows(env, nodelp));
double* slack = (double*)malloc(sizeof(double) * CPXgetnumrows(env, nodelp));
status = CPXsolution(env, nodelp, &lpstat, &objval, x, pi, slack, dj);
printf("Solutionstatus = %d\n", lpstat);
if (status) { goto TERMINATE; } // <--- HERE it returns no solution exists
free(x);
free(dj);
free(pi);
free(slack);
printf("[%d]\trows = %d cols = %d\t sol stat = %d\t z = %f\n", nodecount, rows, cols, lpstat, objval);
if (nodecount == nodeswritten->endnode) status = 1;
count++;
}
TERMINATE:
return (status);
}
あなたの投稿には多くのことが間違っています...コードはありません。実際の説明はありません。投稿する前に何か試してみる気にならないか分かりません。 – schaiba
あなたは非常に正しいです、私はより詳細な情報で投稿を更新しています。 – acco93