2012-06-11 71 views
0

我的應用庫需要調用的優化例程:Ç回調數值優化功能

err = optim(int n, double *x, double *f, void *obj) 

然後,該例程將調用目標函數來請求目標函數值。

void obj(int n, double *x, double *f) 

optim()是外部庫的一部分。 optim()和obj()的簽名是固定的。

功能obj()需要訪問包含在單個對象「模型」中的數據。所有其他函數都圍繞指向模型對象的指針傳遞。因此,調用運行優化程序可能是這樣:

err = doOptimize(model) 

doOptimize()將設置問題,並呼籲optim()

err= optim(model->n, model->x, model->f, model->obj) 

的問題是,可以在obj()函數訪問的變量駐留在model除了n,xfobj()功能需要調用需要的model對象做實際的計算等功能:

updateParms(model); 
    computeF(model); 

我不知道怎麼obj()可能使這些電話沒有實際處理?以下工作可以嗎?

updateParms(); 
    computeF();  

感謝,

+0

你說的是不是'N','x'和'F'成員的其他數據?你能提供一個更詳細的代碼示例,並指出你正在嘗試做什麼? –

回答

1

yes和no。

您的功能obj可以像其他任何內存一樣訪問模型,但我沒有看到任何機制讓它知道地址model

您需要將另一個參數添加到obj中,以便在其中傳遞model指針。

在C++中,您可能需要將obj設置爲Class Model的「成員」。然後編譯器會添加一個名爲this的隱藏參數(它爲所有成員函數執行),它將包含指向對象實例'model'的指針。如果你想在普通的C中獲得相同的結果,那麼你必須傳遞你自己的this指針(不過你可以隨意調用它)。

所以,這樣的事情:

... doOptimize (... model) 
{ 
    .... 
    optim (model->n, model->x, model->x, model) 
    .... 
} 

... optim (int n, double *x, double *f, ... model) 
{ 
    .... 
    model->obj (n, x, f, model); 
    .... 
} 

void obj (int n, double *x, double *f, ... model) 
{ 
    /* use n, x, and f */ 
    /* use model->stuff */ 
} 

當然,如果你總是使用相同nxf然後你只需要通過model

順便說一句,不要使用void *函數指針:這不是一個好主意。

+0

您的解決方案描述的問題比我的描述更好。 optim()是外部庫的一部分。 optim()和obj()的簽名是固定的。我無法如所提出的那樣提出問題的這一事實激發了這個問題。 – user151410

0

既然你不能修改的optim()obj()簽名,您將需要創建執行您obj()功能實際通話的中間步驟。根據電話多少優化需要進行一次,這可能是作爲一個全局/靜態變量保存模型指針,例如簡單:

void obj(struct model *m, int n, double *x, double *f) 
{ 
    /* Access to all information here */ 
} 

static struct model *optim_model; 

void obj_caller(int n, double *x, double *f) 
{ 
    obj(optim_model, n, x, f); 
} 

int doOptimize(struct model *m) 
{ 
    optim_model = m; 
    return optim(m->n, m->x, m->f, obj_caller); 
} 

或者,如果你需要更先進的或不喜歡有單一的全球性和有可能使用n個參數作爲您可以使用它打出來才能夠調用多個優化模型的標識符:

void obj(struct model *m, int n, double *x, double *f) 
{ 
    /* Access to all information here */ 
} 

#define MAX_MODELS (10) 
static struct model *optim_models[MAX_MODELS] = {0}; 

void obj_caller(int n, double *x, double *f) 
{ 
    for (int i = 0; i < MAX_MODELS; i++) 
    { 
     if (optim_models[i]->n == n) 
     { 
      obj(optim_models[i], n, x, f); 
      break; 
     } 
    } 
} 

int doOptimize(struct model *m) 
{ 
    return optim(m->n, m->x, m->f, obj_caller); 
} 

int main(void) 
{ 
    struct model m1; 
    struct model m2; 

    m1.n = 1; 
    optim_models[0] = &m1; 

    m2.n = 2; 
    optim_models[1] = &m1; 

    int err = doOptimize(&m2); 
} 

我敢肯定你承擔責任:水災找到存儲多個車型更合適的方法如果你需要的話,比如帶有真實標識符的鏈表。