• LINGO与EXCEL之间的数据传递


    前言

    LINGO 作为非线性规划运算的专用软件,得出结果一般都是纯文本的一列数据,要想将数据呈现到论文当中,需要整理到 EXCEL 中,使用复制粘贴容易出错还费时,所以必须要动用函数来提高效率!

    案例场景

    有这样一个例子,求发电机厂一天7各时段对4台不同机型的发电机分配开启数量以及输出功率,用LINGO求解,最后需要将7*4=28的数量数据N,以及对应功率P,输出到EXCEL中。如下图所示:

    这里的台数和功率都是7行4列的数据。

    而利用LINGO算出来的纯文本导出数据长这样:

    没错,就这种一路排到底的输出格式,如果是手动复制粘贴,岂不是眼睛都要瞎掉?不过这里值得注意的是,数据的输出是按行输出的,先是N(1,:),再是N(2,:)

    EXCEL 之定义名称

    EXCEL中,使用定义名称,可以将某一块的数据赋予一个指定的名字,这样就和程序里的数据初始化一样,比如定义一个数组,首先要给他一个名字,然后再被其他函数调用。在EXCEL里定义名称的数据可以被宏函数调用。而LINGO也可以通过函数来调用EXCEL中定义了名称的数据。

    如何定义名称?

    以前面的台数表格为例,框选对应的 7*4 的数据区域,CTRL + F3 ,会弹出窗口(如果没反应,就点击顶部功能栏"公式",找到"定义名称",一样可以弹出窗口),设置名称为NUM,确定。同理可以给功率命名为 POW

    命名完了之后,在表格的左上角下拉可以看到已经命名好的数据,包括了NUMPOW

    最后将表格保存为 Q1_Output.xls ,(或者.xlsx格式,.xls格式时,在调用时可以省去后缀,而.xlsx格式必须加上后缀)。保存好了后,把表格打开,放在一边,不要关闭,因为LINGO写入数据时,可能因为权限不够的原因,关闭状态下的EXCEL无法写入,而后台打开状态时可以写入。

    LINGO 之 @OLE

    LINGO自带的ole函数可以负责与EXCEL传递数据。语法如下:

    !data为数据表,x为表格内标记为x名称的某块区域;
    
    X = @ole('data.xls','x');!从EXCEL导入数据到LINGO;
    
    @ole('data.xls','x') = X;!从LINGO导出数据到EXCEL;
    

    所以为了导出我们的N、P数据,我们写如下代码到 data:里

    @OLE('Q1_Output','NUM')=N;
    
    @OLE('Q1_Output','POW')=P;
    

    完整代码如下:

    model:
    sets:
    A /1..7/: T, D ;
    B /1..4/:N0,Pmax,Pmin,F,M,S;
    U(A,B):   N, P ;
    endsets
    
    data:
    T = 6 3 3 2 4 4 2;
    D = 11000 33000 25000 36000 25000 30000 18000;
    N0  = 10   5    8      4;
    Pmax=1800 1500 2000 3500;
    Pmin= 800 1000 1200 1800;
    F   =2200 1800 3800 4600;
    M   = 2.7  2.2  1.8  3.6;
    S   =4000 1500 2500 1000;
    @OLE('Q1_Output','NUM')=N;
    @OLE('Q1_Output','POW')=P;
    enddata
    
    W1 =@sum(B(j):N(1,j)*S(j))+@sum(A(i)|i#ge#2:
    @sum(B(j):(N(i,j)-N(i-1,j)+@abs(N(i,j)-N(i-1,j)))
    /2*S(j)));
    
    W2=@sum(A(i): @sum(B(j):N(i,j)*F(j)*T(i)));
    
    W3=@sum(A(i): @sum(B(j):(P(i,j)-Pmin(j))*
    N(i,j)*M(j)*T(i)));
    
    min =W1+W2+W3;
    
    @for(A(i): @sum(B(j):P(i,j)*N(i,j)) >=D(i));
    @for(U(i,j):N(i,j)>=0);
    @for(U(i,j):N(i,j)<=N0(j));
    @for(U(i,j):@gin(N(i,j)));
    @for(U(i,j):Pmin(j)<=P(i,j));
    @for(U(i,j):P(i,j)<=Pmax(j));
    
    end
    
    

    一键导出数据

    做好前面两步,即EXCEL数据输出区域命名,还有LINGO导出数据函数,最后把EXCEL打开放在屏幕左边,LINGO放右边,点击solve,坐等程序跑完,EXCEL中就惊现数据了,是不是很nice!?

  • 相关阅读:
    Android按返回键退出程序但不销毁,程序后台运行,同QQ退出处理方式
    android 下动态获取控件的id
    Android大图片裁剪终极解决方案 原理分析
    如何使用Android MediaStore裁剪大图片
    最新的Android Sdk 使用Ant多渠道批量打包
    nodejs学习(1)
    C#——企业微信一般操作之一
    html(1)——转圈等待效果+鼠标移动悬浮显示相关信息
    SQL注入小结
    Java实现二叉树地遍历、求深度和叶子结点的个数
  • 原文地址:https://www.cnblogs.com/gshang/p/11219489.html
Copyright © 2020-2023  润新知