今天晚上看了规划问题的经典部分——运送货物的问题。采用Lingo编程,十分的简介,在规划问题运筹学问题上,Lingo 的优势是无可比拟的。
题目:
具体数据:
可以抽象出:
[displaystyle min quad sum_{i=1}^{n}sum_{j=1}^{m}c_{ij}x_{ij}]
限制条件是:
[left{
egin{array}{ll}
displaystyle sum_{j=1}^{n}x_{ij}leq a_{i}(mathrm{Customer}) \[3mm]
displaystyle sum_{i=1}^{m}x_{ij} = b_{j}(mathrm{WareHouse})
end{array}
ight.
]
实现代码是:
model: sets: warehouse/1..3/:a; customer/1..4/:b; routes(warehouse,customer):c,x; endsets data: a=30,25,21; b=15,17,22,12; c=6,2,6,7, 4,9,5,3, 8,8,1,5; enddata min = @sum(routes:c*x); @for(warehouse(i):[SUP] @sum(customer(j):x(i,j))<=a(i)); @for(customer(j):[DEM] @sum(warehouse(i):x(i,j))=b(j)); end
下面是另外一个经典的规划问题——指派问题。指派问题可以抽像为一个0-1问题。下面给出一个例题:
题目:
设有$n$个人,计划作$n$项工作,其中$c_{ij}$表示第$i$个人做第$j$项工作的收益,现求一种指派方式,使得每个人完成一项工作,使收益最大。
数据:
抽象为0-1问题:
[displaystyle min quad sum_{i=1}^{n}sum_{j=1}^{m}c_{ij}x_{ij}]
subject to 是:
[left{
egin{array}{ll}
displaystyle sum_{j=1}^{n}x_{ij}=1\[3mm]
displaystyle sum_{i=1}^{m}x_{ij} = 1
end{array}
ight.
]
其中,$x_{ij}=0mathrm{or}1$。
实现代码:
sets: flight/1..6/; Assign(flight,flight):c,x; endsets data: c=20,15,16,5,4,7, 17,15,33,12,8,6, 9,12,18,16,30,13, 12,8,11,27,19,14, -99,7,10,21,10,32, -99,-99,-99,6,11,13; enddata !solve the problem of assignments; max = @sum(Assign:c*x); !subject to; @for(flight(i): @sum(flight(j):x(i,j))=1; ); @for(flight(j): @sum(flight(i):x(i,j))=1; ); end
转运问题:
只是在指派问题的基础上加上转运点,比上面的情况稍微复杂一点。
题目:设有两个工厂A, B, 产量分别为9, 8个单位. 四个顾客1, 2, 3, 4, 需求量分别为3, 5, 4, 5. 和三个仓库x, y, z. 其中工厂到仓库、仓库到顾客的运费单价分别由表7-4所示.试求总运费最少的运输方案,以及总运费。
抽象的数学模型:
[displaystyle min quad sum_{i=1}^{m}sum_{j=1}^{l}c_{ij}x_{ij}^{1}+sum_{j=1}^{l}sum_{k=1}^{n}c_{jk}x_{jk}^{2}]
subject to:
[left{
egin{array}{ll}
displaystyle sum_{j=1}^{l}x_{ij}^{1}leq a_{i} \[3mm]
displaystyle sum_{i=1}^{m}x_{ij}^{1} = sum_{k=1}^{n}x_{ij}^{2}\[3mm]
displaystyle sum_{j=1}^{l}x_{ij}^{2}=b_{k}
end{array}
ight.
].
Lingo代码如下:
!TP问题; sets: plant/A,B/:produce; warehouse/x,y,z/; customer/1..4/:require; link1(plant,warehouse):c1,x1; link2(warehouse,customer):c2,x2; endsets data: produce=9,8; require=3,5,4,5; c1=1,2,100, 3,1,2; c2=5,7,100,100, 9,6,7,100, 100,8,7,4; enddata min = @sum(link1:c1*x1)+@sum(link2:c2*x2); !subject to; @for(plant(i):[SUP] @sum(warehouse(j):x1(i,j))<=produce(i)); @for(warehouse(j):[MID] @sum(plant(i):x1(i,j))=@sum(customer(k):x2(j,k))); @for(customer(k):[DEM] @sum(warehouse(j):x2(j,k))=require(k)); end
在此,强调,Lingo代码语句的规范性很重要!!!!=-=因为一个问题搞了好长时间。