挚爱/Sunsgne° 发表于 2013-7-23 14:50

Lingo求解一问题

wujianjack2 发表于 2013-7-23 19:31

本帖最后由 wujianjack2 于 2013-7-27 14:42 编辑

第一次回答:
看似简单,实则不易的问题啊!
问题清晰明了,如果单从编程的角度来思考,则可能的程序代码如下:
MODEL:
SETS:
XY_VAL/1..89/:XX,YMAX;
ENDSETS
DATA:
L1=30;L2=10;L3=20;
PI=3.1415926535;
@TEXT('ymax_forum.txt')=@WRITEFOR(XY_VAL(I):@NAME(YMAX),'',YMAX,@NEWLINE(1));
ENDDATA
MAX=YMAX;
XX(1)=-44;
@FOR(XY_VAL(I)|I#LT#89:XX(I+1)=XX(I)+1);
@FOR(XY_VAL(I):L1*@COS(A)+L2*@COS(A+B)+L3*@COS(A+B+C)=XX(I));
@FOR(XY_VAL(I):L1*@SIN(A)+L2*@SIN(A+B)+L3*@SIN(A+B+C)=YMAX(I));
@BND(-2*PI/3,A,2*PI/3);
@BND(-PI/3,B,PI/3);
@BND(-PI/3,C,PI/3);
END

然而很遗憾的是,经过实践,这并不是一种可行的方案,运行提示错误21,集合名使用不当。我的看法是一个LINGO程序中可能只允许存在一个求最大或最小值的目标函数,而上述问题则希望求解89个最大值。

那如果把它分成89个问题来求,则可能的程序代码如下(以X=-44为例):
MODEL:
DATA:
L1=30;L2=10;L3=20;
PI=3.1415926535;
ENDDATA
MAX=YMAX;
L1*@COS(A)+L2*@COS(A+B)+L3*@COS(A+B+C)=-44;
YMAX=L1*@SIN(A)+L2*@SIN(A+B)+L3*@SIN(A+B+C);
@BND(-2*PI/3,A,2*PI/3);
@BND(-PI/3,B,PI/3);
@BND(-PI/3,C,PI/3);
END

运行结果为(仅给出重要数据):
  Local optimal solution found.
  Objective value:                              33.66191
  Infeasibilities:                             0.5288794E-06
  Extended solver steps:                            5
  Total solver iterations:                           314
  YMAX        33.66191            0.000000
        A        2.094395           -83.08978
        B       0.7882759            0.000000
        C        0.000000            0.000000
我目前掌握的知识也很有限,无法很好地解决楼主提出的问题,抱歉!
如果楼主有什么好的想法,望不吝赐教!

第二次回答:
  上一次回答略显仓促,解答不是很完美。然而个人认为这个问题还是很有价值的,现在我给出我的第二种方案,比较好地解决了楼主提出的问题,程序代码如下:

MODEL:
SETS:
X_VALUE:XX,A,B,C;
ENDSETS
DATA:
KK=89;
L1=30;L2=10;L3=20;
PI=3.1415926535;
X_VALUE=1..KK;
ENDDATA
SUBMODEL YMAX_SERIES:
MAX=YMAX;
L1*@COS(A(I_S))+L2*@COS(A(I_S)+B(I_S))+L3*@COS(A(I_S)+B(I_S)+C(I_S))=XX(I_S);
YMAX=L1*@SIN(A(I_S))+L2*@SIN(A(I_S)+B(I_S))+L3*@SIN(A(I_S)+B(I_S)+C(I_S));
@BND(-2*PI/3,A(I_S),2*PI/3);
@BND(-PI/3,B(I_S),PI/3);
@BND(-PI/3,C(I_S),PI/3);
ENDSUBMODEL
CALC:
@DIVERT('YMAX_VALUES.txt');
@FOR(X_VALUE(I):XX(I)=I-45;
I_S=I;
@SOLVE(YMAX_SERIES);
@WRITE(' ',I,'  ',@FORMAT(YMAX,'8.4f'));
@WRITE(@NEWLINE(1)););  
@DIVERT();
ENDCALC
END

如果不选用Global Solver,可能只能计算到X=24的时候,如果选用,则所有结果均可以计算出来,用时大约4-5秒,还有一点,本程序一定要在LINGO 10及其以上版本才能运行通过,我用到了LINGO 9还没有的功能。

运行结果如下(为缩减篇幅,仅给出前26项的结果):
1   33.6619
2   36.7511
3   39.0575
4   40.9474
5   42.5639
6   43.9808
7   45.2421
8   46.3768
9   47.4050
10   48.3414
11   49.1971
12   49.9808
13   50.6992
14   51.3579
15   51.9615
16   52.5262
17   53.0660
18   53.5817
19   54.0740
20   54.5436
21   54.9909
22   55.4166
23   55.8211
24   56.2050
25   56.5685
26   56.9122

如果楼主还有什么更好的解决方案,一定要告诉我啊!同时欢迎大家指正我的不足与错误,谢谢!

希恩杰 发表于 2013-7-26 20:10

wujianjack2 发表于 2013-7-23 19:31 static/image/common/back.gif
看似简单,实则不易的问题啊!
问题清晰明了,如果单从编程的角度来思考,则可能的程序代码如下:
MODE ...

这题是不是求对应的89个x的89个y中最大值,那直接@bnd(-44,x,44);@gin(x);就行了?

wujianjack2 发表于 2013-7-26 20:16

希恩杰 发表于 2013-7-26 20:10 static/image/common/back.gif
这题是不是求对应的89个x的89个y中最大值,那直接@bnd(-44,x,44);@gin(x);就行了?

  多谢你的想法!
  不过我的理解是对每一个X值求出对应的Y的最大值,而不是单求Y序列中的最大值。
  有时间我会再尝试解决这个问题的,当然你如果有什么新的想法也可以与我交流,谢谢支持!
页: [1]
查看完整版本: Lingo求解一问题