C++类初始化属性无法在Ipopt的eval_f等函数中访问
问题分析与解决:Ipopt优化类属性访问为空
问题根源
你在startOptimization函数里新建了一个全新的ipoptOptimizer实例,而非使用main函数中已经通过initilize()初始化好的对象。这个新实例的a和startPoint都是C++默认初始化值(int默认0,vector默认空容器),所以eval_f中访问的是这个空实例的属性,自然输出0和0。
关键问题代码:
// startOptimization函数内,创建了与main中独立的新实例 SmartPtr<TNLP> mynlp = new ipoptOptimizer();
解决方案
有两种可靠的修正方式:
方法一:使用当前已初始化的实例(推荐)
修改startOptimization函数,直接将当前对象的this指针包装为SmartPtr传给Ipopt,避免新建实例:
void ipoptOptimizer::startOptimization() { SmartPtr<TNLP> mynlp = this; // 使用当前已完成初始化的实例 SmartPtr<IpoptApplication> app = IpoptApplicationFactory(); app->Options()->SetNumericValue("tol", 3.82e-6); app->Options()->SetStringValue("mu_strategy", "adaptive"); app->Options()->SetStringValue("output_file", "ipopt.out"); ApplicationReturnStatus status; status = app->Initialize(); if (status != Solve_Succeeded) std::cout << std::endl << std::endl << "*** Error during initialization!" << std::endl; status = app->OptimizeTNLP(mynlp); if (status != Solve_Succeeded) std::cout << std::endl << std::endl << "*** Error during optimizing!" << std::endl; }
方法二:将startOptimization改为静态函数,接收外部实例
如果希望startOptimization作为独立工具函数使用,可改为静态方法并传入已初始化的对象:
- 头文件修改函数声明:
class ipoptOptimizer : public TNLP { // ... 其他属性与函数 ... static void startOptimization(ipoptOptimizer* optimizer); };
- cpp文件实现静态函数:
void ipoptOptimizer::startOptimization(ipoptOptimizer* optimizer) { SmartPtr<TNLP> mynlp = optimizer; SmartPtr<IpoptApplication> app = IpoptApplicationFactory(); // 其余配置与优化代码保持不变 }
- main函数调用方式:
int main() { ipoptOptimizer optimizer; optimizer.initilize(); ipoptOptimizer::startOptimization(&optimizer); return 0; }
额外提示
你的初始化函数名拼写为initilize(缺少一个字母i,正确应为initialize),虽然不影响功能,但建议修正拼写以避免后续混淆。
内容的提问来源于stack exchange,提问作者mary
相关产品推荐
相关产品推荐

