GAMS使用小记(三)

引言

前段时间使用GAMS进行了一些工作,本以为已经达到了通过java调整模型参数后运行并获得输出的目的(见本系列前两篇博文),但后续在整理数据的过程中发现有不合逻辑之处,进一步发现直接求解原模型和按之前的方法把完全相同的参数值赋给模型再运行得到的结果不同,本文记录这一问题的思考和探索。

问题

通过以下的代码从文件中加载、运行DICE模型,之后通过OutDB()可以查看模型的结果(这里以查看变量“TATM”的前17个值为例),也可以将OutDB()导出,再从GAMS studio里查看。

GAMSWorkspaceInfo  wsInfo  = new GAMSWorkspaceInfo();
wsInfo.setWorkingDirectory(workingdir);
// create a workspace and related checkpoint
GAMSWorkspace ws = new GAMSWorkspace(wsInfo);
GAMSCheckpoint cp = ws.addCheckpoint();
// load the original model and initialize checkpoint
GAMSJob dice = ws.addJobFromFile(modeldir);
dice.run(cp);
dice.OutDB().export("original");
System.out.println("dice: ");
for (int i = 1; i < 18; i++) {
      double temp = dice.OutDB().getVariable("TATM").findRecord(String.valueOf(i)).getLevel();
      System.out.print(temp);
      }

这里的结果和直接在GAMS studio中运行原模型是一样的。之前我按照上篇博文中的方法借助ModelInstance来实现三个参数的更新,然而我发现,当我把与原模型相同的参数值传入时,从SyncDB()得到的“TATM”的前17个值却是不同的,这令我十分困惑。

探索尝试

后续我又仿照教程的Transport5.java使用下面的代码来更新参数。

ws.addJobFromString("gA1=0.066" +  "; solve CO2 maximizing UTILITY using nlp; ", cp);

结果发现这样尝试改变的结果和使用ModelInstance的结果是相同的,但都和dice.OutDB()的内容不同。并且在对应的.lst文件中有如下的提示。

*** Record not part of the model: aL(s0)
*** Record not part of the model: sigma(s0)
— Scenario s0: Records read: 3 Record ignored: 2

这使我意识到这两个参数应该是没有起到实际作用(因为ignored了),通过将SyncDB()导出可以查看其中的内容,我发现aL、sigma的值确实改变了,但是最终的结果没有变化。之后继续摸索尝试,首先发现通过java去改变参数相当于一个新的.gms文件,换句话说就是在初始的.gms文件执行后再执行这个.gms文件(默认命名为_gams_java_gjo+数字),这意味着之前已经计算过的参数不会更新了,(比如原文件中a=10,b=a+2,之后我添加了a=11这条语句,最终的效果是a会变成11,但b仍然是12),这意味着由要改变的参数计算得到的其他所有的值都要在改变之后再执行(将前面的顺序调整为a=10,a=11,b=a+2,这样b最终就等于13了)。进一步的问题在于这是一个树状的影响链条,一个参数值的变化是根节点,会带动许多参数值的变化,并且如果把参数计算部分放到后面,模型部分便也会报错,类似于“symbol defined but not assigned value”,所以等于说参数的调整实际上要放到最前面,其他部分的顺序可以保持不变,这个可以通过注释和$include命令来实现,具体方法为先将参数定义之后的内容全部复制到另一个文件,再将原文件中这些内容全部注释,最后再在java中先改变参数,再把后面的内容$include进去,示例如下。

dice = ws.addJobFromString("gA1=" +rand[0][i]+  "; gsigma1=" +rand[1][i]+ "; a2base=" +rand[2][i] +";\n"+
                            "$include Include\\statements.gms \n"+
                            "solve CO2 maximizing UTILITY using nlp;"
                    , cp);

至此,通过addJobFromString方法来改变参数得到了符合逻辑的结果,借助ModelInstance的方法我也尝试过,但始终会出现aL和sigma的Record not part of the model,推测是尽管这两个参数都出现在了模型的equation部分,但起到的仍然是“准备工作”这样一个作用,换句话说还是中间量,没有出现在最终的模型中,对应来看a2base这个参数就是在模型中的。(感觉有些反常,但也有合理之处吧。。。)

感想

上次遇到问题时完全手足无措,这次tough了许多,上周参加了一个量化交易的比赛,看了挺多日志,这次对日志看得比较仔细,也看出一些门道。一方面还是给技术支持发了邮件,一方面自己也在摸索,最终另一位技术支持人员说软件过了支持的周期,不提供支持,emmm,主要还是得靠自己啊。

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值