主讲人:雒兴刚东北大学系统工程研究所Email:luoxinggang@ise.neu.edu.cnTel:83682292优化软件与应用第九章ILOGOPL建模语言OPL数据类型1、整型:范围例:inti=25;intn=3;intsize=n*n;//注意这种初始化很特别2、浮点型:双精度,IEEE754standardfloatf=3.2;第九章ILOGOPL建模语言OPL数据类型3、字符串型例如{string}Tasks={masonry,carpentry,plumbing,ceiling,roofing,painting,windows,facade,garden,moving};定义字符串一个集合。字符串中的特殊字符:字符串换行:第九章ILOGOPL建模语言OPL数据结构1、Range:给定最小和最大值。rangeRows=1..10;intn=8;rangeRows=n+1..2*n+1;用途1:数组定义rangeR=1..100;intA[R];//Aisanarrayof100integers用途2:循环rangeR=1..100;forall(iinR){//elementofaloop...}用途3:变量定义dvarintiinR;第九章ILOGOPL建模语言OPL数据结构2、数组一维数组:inta[1..4]=[10,20,30,40];floatf[1..4]=[1.2,2.3,3.4,4.5];stringd[1..2]=[Monday,Wednesday];inta[Days]=[10,20,30,40,50,60,70];即元素下标可以是字符串,如a[Monday],...,a[Sunday].tupleEdges{intorig;intdest;}{Edge}Edges={1,2,1,4,1,5};inta[Edges]=[10,20,30];即下标也可以是Tuple,a[1,2],a[1,4],anda[1,5]第九章ILOGOPL建模语言OPL数据结构2、数组多维数组:inta[1..2][1..3]=...;inta[Days][1..3]=...;//混合下标{string}Warehouses=...;{string}Customers=...;tupleRoute{stringw;stringc;}{Route}routes=...;inttransp[routes]=...//实际上transp是二维数组{string}Warehouses...;{string}Customers...;tupleRoute{Warehousesw;Customersc;}{Route}routes=...;inttransp[routes]=...可能是稀疏矩阵两种哪个好些?第九章ILOGOPL建模语言OPL数据结构3、Tuple:结构体tuplePoint{intx;inty;};Pointpoint[iin1..3]=i,i+1;Pointp=2,3;Pointpoint[iin1..3]=i,i+1;//Tuple数组{Point}points={1,2,2,3};//Tuple集合tupleRectangle{Pointll;Pointur;}//Tuple的TuplePointp=2,3;intx=p.x;//取Tuple的成员但是,Tuple的定义里不能出现Tuple集合和Tuple数组!第九章ILOGOPL建模语言OPL数据结构4、集合:可以写成{T},或者setof(T){int}setInt=...;setof(Precedence)precedences=...;集合初始化:tuplePrecedence{intbefore;intafter;}{Precedence}precedences={1,2,1,3,3,4};第九章ILOGOPL建模语言OPL决策变量和约束OPL决策变量使用关键字dvardvarinttransp[Orig][Dest]in0..100;//二维数组变量;限制决策变量范围tupleRoute{Cityorig;Citydest}{Route}routes=...:dvarinttransp[routes]in0..100;//以有限tuple集routes为索引rangeCapacity=0..limitCapacity;dvarinttransp[Orig][Dest]inCapacity;//in后面是rangedvarintaverageDelayin0..maxDelay;//in后面接变量如果不同决策变量的范围不同,可以这样定义intcapacity[route]=...;dvarinttransp[rinroutes]in0..capacity[r];第九章ILOGOPL建模语言OPL决策变量和约束也可以用+关键字限制决策变量只能为正:dvarint+x;//nonnegativeintegerdecisionvariabledvarfloat+y;//non-negativedecisionvariabledvarbooleanz;//booleandecisionvariable上述定义等价于:dvarintxin0..maxint;dvarfloatyin0..infinity;dvarintzin0..1;其中maxint、infinity为OPL关键字。二维决策变量数组也可以逐个元素给定范围:dvarfloattransp[oinOrig][dinDest]in0..cap[o][d];约束可以单个定义,也可以定义成数组形式,如:constraintcapCstr[Machines];第九章ILOGOPL建模语言OPL数据初始化总的来说,OPL数据初始化可以分为2种,一种是在mod文件完成,另一种是在dat文件完成。1、数组初始化初始化多维数组:/*.modfile*/inta[1..2][1..3]=...;/*.datfile*/a=[[10,20,30],[40,50,60]];按照(index,value)的方式初始化数组:但注意要用#[…]#方式元素次序无关。参见下页例子:/*.modfile*/inta[Days]=...;/*.datfile*/a=#[Monday:1,Tuesday:2,Wednesday:3,Thursday:4,Friday:5,Saturday:6,“Sunday”:7]#;第九章ILOGOPL建模语言OPL数据初始化前面的整型索引数组的初始化也可以写成:/*.modfile*/inta[1..2][1..3]=...;/*.datfile*/a=#[2:[40,50,60],1:[10,20,30]]#;数组初始化也可以用ILOG脚本实现,如:rangeR=1..10;inta[R];execute{for(variinR){a[i]=i+1;}}行下标,注意这里故意颠倒了次序,但结果相同第九章ILOGOPL建模语言OPL数据初始化也可以用表达式方式初始化,例如上面的例子也可写为:inta[iin1..10]=i+1;多维数组也可以用这种方式,如:intm[iin0..10][jin0..10]=10*i+j;也可以用一个已知数组初始化,如:intm[Dim1][Dim2]=...;intt[jinDim2][iinDim1]=m[i][j];也可以用index:item方式初始化,如:inta[1..10]=[i-1:i|iin2..11];//效果同前面的2个例子intm[0..10][0..10]=[i:[j:10*i+j]|i,jin0..10];第九章ILOGOPL建模语言OPL数据初始化再如,下面的ILOG脚本初始化:GasTypegas[Gasolines];execute{for(vargingasData){gas[g.name]=g;}}用index:item方式可以写成:GasTypegas[Gasolines]=[g.name:g|gingasData];第九章ILOGOPL建模语言OPL数据初始化2、Tuple初始化单个变量初始化直接用…给出成员即可,如:Pointp=3,2;Tuple中含有数组的初始化:tupleRectangle{intid;Pointp[2];}Rectangler=1,[0,0,10,10];Tuple中含有集合的初始化:{string}Task...;tuplePrecedence{Taskname;{string}after;}Precedencep=a1,{a2,a3,a4,a5};第九章ILOGOPL建模语言OPL数据初始化3、集合初始化结合采用一对大括号进行初始化,如:tuplePrecedence{intbefore;intafter;}{Precedence}precedences=...;precedences={1,2,1,3,3,4};可以在初始化时使用集合运算符,如:{int}s1={1,2,3};{int}s2={1,4,5};{int}i=s1inters2;{int}j={1,4,8,10}inters2;{int}u=s1union{5,7,9};{int}d=s1diffs2;结果是:i={1},u={1,2,3,5,7,9},d={2,3},sd={2,3,4,5}.注意inter等是集合运算符第九章ILOGOPL建模语言OPL数据初始化可以利用range初始化集合,如:{int}s=asSet(1..10)//初始化s为{1,2,..,10}asSet是内置函数,功能是将range转换为集合也可以用表达式方式初始化,格式是pinS:condition,如:{int}s={i|iin1..10:imod3==1};//结果是{1,4,7,10}.也可以定义集合数组(数组元素为一个集合),如:{int}a[iin3..4]={e|ein1..10:emodi==0};初始化a[3]为{3,6,9},a[4]为{4,8}第九章ILOGOPL建模语言OPL数据初始化集合很多时候可以用来表示稀疏矩阵,如:{string}Nodes...;intedges[Nodes][Nodes]=...;tupleEdge{Nodeso;Nodesd;}{Edge}setEdges={o,d|o,dinNodes:edges[o][d]==1};另一个稍复杂一些的例子:{string}Resources...;{string}Tasks...;Tasksres[Resources]=...;tupleDisjunction{{string}first;{string}second;}{Disjunction}disj={i,j|rinResources,orderedi,jinres[r]};关键字,强制ij关键字,强制ij第九章ILOGOPL建模语言OPL数据一致性为了保证输入数据的正确性,可以通过assert语句来判定数据的一致性。这样在程序运行前,可以通过编译系统提前发现问题。例如,原是的需求和供应数据具有关联性(总和相等):intdemand[Customers]=...;intsupply[Suppliers]=...;assertsum(sinSuppliers)supply[s]==sum(cinCustomers)demand[c];再如,如果是多产品的情况:intdemand[Customers][Products]=...;intsupply[Suppliers][Products]=...;assertforall(pinProducts)sum(sinSuppliers)supply[s][p]==sum(cinCustomers)demand[c][p];第九章ILOG