lingo学习

day1 上午

求获利最大有目标函数以及约束函数:

max = 72*x1+64*x2;
x1+x2<50;
12*x1+8*x2<480;
3*x1<100;

在lingo中,

①默认变量为>=0,若需要变成实数则需要@free(x1)

②<与<=是等价的

运行所得到的结果:

做灵敏度分析(只能用在连续型,不能离散型)的话还需要调整选项:

然后点击range才会出现。

回到最初的问题:

1.最大获利为:3360,x1为20,x2为30。

2.在范围允许的前提下,牛奶的影子价格为48,所以值!

3.因为工人的影子价格为2,所以最多为2.

4.价格为30时,系数为90,在范围之内,不会改变最优计划20和30

day1 下午

基本语法

MODEL:
Title Location;
sets:
	demand/1..6/:a,b,d; #demand为变量名,abd表示其属性,1..6表示1-6
	supply/1..2/:x,y,e;
	link(demand,supply):c;
endsets
data:
a = 1.25,8.75,0.5,5.75,3,7.25;
b = 1.25,0.75,4.75,5,6.5,7.75;
d = 3,5,4,7,6,11;e = 20,20;
x,y = 5,1,2,7;  #a表示5,1先赋给x,y
enddata
END

上述集的表示为隐式举例,显式举例就是在//中一个一个列举出来,除此之外还有元素过滤法

link(demand,supply):c

并不是普通的集,属于派生集,link属于名字。

稠密集可以用隐式举例,稀疏集数据大的时候只能看是否可以用过滤举例

sets: 
             !学生集:性别属性sex,1表示男性,0表示女性;年龄属性age. ;
  students/John,Jill,Rose,Mike/:sex,age; 
             !男学生和女学生的联系集:友好程度属性friend,[0,1]之间的数。 ;
  linkmf(students,students)|sex(&1) #eq# 1 #and# sex(&2) #eq# 0: friend; 
             !男学生和女学生的友好程度大于0.5的集;
  linkmf2(linkmf) | friend(&1,&2) #ge# 0.5 : x; 
endsets
data: 
    sex,age = 1 16 
    0 14 
    0 17 
    0 13; 
    friend = 0.3 0.5 0.6; 
enddata

        用竖线 | 来标记一个成员资格过滤器的开始。#eq#是逻辑运算符,用来判断 是否“相等”,&1 可看作派生集的第 1 个原始父集的索引,它取遍该原 始父集的所有成员;&2 可看作派生集的第 2 个原始父集的索引,它取遍该原始父集 的所有成员;&3,&4,……,以此类推。注意如果派生集 B 的父集是另外的派生集 A, 那么上面所说的原始父集是集 A 向前回溯到最终的原始集,其顺序保持不变,并且 派生集 A 的过滤器对派生集 B 仍然有效。因此,派生集的索引个数是最终原始父集 的个数,索引的取值是从原始父集到当前派生集所作限制的总和。

 标量变量

data: 
 interest_rate,inflation_rate = .085 .03; 
enddata

 模型的初始部分:init(用于非线性作为初始点,不要也可以,但一个好的初始点可以减少时间)

init:
    x = 0.1;
endinit

运算符的优先级

数学函数

上述题目的总解决代码为:

MODEL:
Title Location;
sets:
	demand/1..6/:a,b,d;
	supply/1..2/:x,y,e;
	link(demand,supply):c;
endsets
data:
a = 1.25,8.75,0.5,5.75,3,7.25;
b = 1.25,0.75,4.75,5,6.5,7.75;
d = 3,5,4,7,6,11;e = 20,20;
x,y = 5,1,2,7;
enddata
[obj]min = @sum(link(i,j):c(i,j)*((x(j)-a(i))^2+(y(j)-b(i))^2)^(0.5));
@for(demand(i):[demand_con] @sum(supply(j):c(i,j)) = d(i););
#注意函数结束都需要;结束
@for(supply(j):[supply_con] @sum(demand(i):c(i,j)) <=e(j););
end
#[]中的内容都是参数名字

        非线性问题是指未知数的指数,例一中x(i)均为已知量,所以为线性,而对于此题,xj以及yj都是未知量,所以要将其初始化。

MODEL:
Title Location;
sets:
	demand/1..6/:a,b,d;
	supply/1..2/:x,y,e;
	link(demand,supply):c;
endsets
data:
a = 1.25,8.75,0.5,5.75,3,7.25;
b = 1.25,0.75,4.75,5,6.5,7.75;
d = 3,5,4,7,6,11;e = 20,20;
enddata
!x,y = 5,1,2,7;
init:
	x,y = 5,1,2,7;
endinit
[obj]min = @sum(link(i,j):c(i,j)*((x(j)-a(i))^2+(y(j)-b(i))^2)^(0.5));
@for(demand(i):[demand_con] @sum(supply(j):c(i,j)) = d(i););
@for(supply(j):[supply_con] @sum(demand(i):c(i,j)) <=e(j););
@for(supply:@free(x);@free(y););
@for(supply:@bnd(0.5,x,8.75); @bnd(0.75,y,7.75););
end

day2 上午

代码如下:

model:
sets:
citys/1..9/:L;
roads(citys,citys)/9,6 9,7 9,8 6,4 6,5 7,4 7,5 8,4 8,5 4,2 4,3 5,2 5,3 2,1 3,1/:D,p;
endsets
data:
D = 6 3 3 6 5 8 6 7 4 6 7 8 9 5 6;
enddata
@for(citys(i)|i#gt#1:
	L(i) = @min(roads(i,j):d(i,j)+l(j)));
end

上述代码只能求出L(i),但不能将路径指出来,若想指出来,在roads中指定属性p,增加如下代码:

@for(roads(i,j):p(i,j)= @if(l(i)#eq#d(i,j)+l(j),1,0));

该代码是指各俩点之间的最短路径的p赋值为1,路径为9——8——5——2——1。

day2 下午

文件的输入以及输出

MODEL:
SETS:
  MYSET / @FILE(‘myfile.txt’) / : @FILE(‘myfile.txt’);
#第一次是调用城市名字,第二次是掉用花费啥的东西
ENDSETS
MIN = @SUM( MYSET( I):
           SHIP( I) * COST( I));
  @FOR( MYSET( I): 
          [CON1] SHIP( I) > NEED( I);
          [CON2] SHIP( I) < SUPPLY( I));
DATA:
  COST = @FILE(‘myfile.txt’);
  NEED = @FILE(‘myfile.txt’);
  SUPPLY = @FILE(‘myfile.txt’);
#输出文件语句,也可以在后面加上文字,例如 @text('d:\out.txt')=days '至少需要的职员数为' start; 
  @TEXT(‘result.txt’)=SHIP, @DUAL(CON1), @DUAL(CON2);#后面这玩意还不知道干嘛的
ENDDATA
END

@file()表示文件的调用,在文件内容中的每一行需要以~结尾,例如:

🔺在 LINGO 中不允许 嵌套调用@file 函数

Seattle,Detroit,Chicago,Denver~

COST,NEED,SUPPLY,SHIP~

12,28,15,20~

1600,1800,1200,1000~

1700,1900,1300,1100

每调用一次@file即为调用一行。 

@min,@max函数:

MAXB=@MAX(PAIRS( I, J): BENEFIT( I, J));

MINB=@MIN(PAIRS( I, J): BENEFIT( I, J));

@for,@sum函数: 

源代码如下:

自己看到的例题:/4.6

         职员时序安排模型 一项工作一周 7 天都需要有人(比如护士工作), 每天(周一至周日)所需的最少职员数为 20、16、13、16、19、14 和 12,并要求每 个职员一周连续工作 5 天,试求每周所需最少职员数,并给出安排。注意这里我们 考虑稳定后的情况

model:
sets:
day/mon..sun/:required,start;
endsets
data:
required = 20 16 13 16 19 14 12;
enddata
min = @sum(day:start);
@for(day(j):@sum(day(i)|i#lE#5:start(@wrap(j+i+2,7)))>=required(j)
);
end

关于排班问题中的@wrap的理解:点他就对了 

day3 上午

@OLE:调用excel里面的内容

MODEL:
SETS:
  MYSET: COST,SHIP,NEED,SUPPLY;#省略了名字的命名,在data中实现
ENDSETS
MIN = @SUM( MYSET( I):     SHIP( I) * COST( I));
  @FOR( MYSET( I): 
          [CON1] SHIP( I) > NEED( I);
          [CON2] SHIP( I) < SUPPLY( I));
DATA:
   MYSET =@OLE('D:\JXIE\BJ2004MCM\mydata.xls','CITIES'); 
   COST,NEED,SUPPLY =@OLE(mydata.xls); #用一个即可自动赋值给相应的名字
   @OLE(mydata.xls,'SOLUTION')=SHIP; #若“solution”叫做“ship”,即可省略
ENDDATA
END

自己的补充学习

①下料问题

理解:对于一根原钢管,有不同的下料方法,比如对于一根19m的,可以分成4根4m的,但又因为题目说不超过三种,所以只能有三种下料方法。

method/A,B,C/:x;

 既有:

代码如下:

model:
sets:
method/A,B,C/:x;
material/a..d/:need,L;
link(method,material):N;
endsets
data:
need = 50 10 20 15;
l = 4 5 6 8;
ol = 19;
enddata
min = @sum(method:x);!目标函数
@for(material(j):@sum(method(i):N(i,j)*x(i)>=need(j)));
@for(method(i):x(i)>=0);
@for(method(i):@sum(link(i,j):n(i,j)*l(j))<=ol);
@for(method(i):@sum(link(i,j):n(i,j)*l(j))>=16);
@for(link:@gin(n);@for(method:@gin(x)));      !设置nx都是整数@gin
end

 

②配料问题

model:
sets:
meal/1..6/:price,x;
needs/1..5/:need;
eachadd(meal,needs):c;
endsets
data:
price = 2.1 1.0 1.8 1.2 2.0 1.2;
c = 0.45 20 415 22 0.3
0.45 28 4065 5 0.35
0.65 40  850 43 0.6
0.4 25 75 27 0.2
0.5 26 76 48 0.4
0.5 75 235 8 0.6;
need = 6 125 12500 345 5;
enddata
min = @sum(meal(i):price(i)*x(i));
@for(meal(i):@gin(x(i)));
@for(meal(i):x(i)>=1);
x(2)<=3; x(4)<=2;
@sum(meal(i):x(i)) = 14;
@for(meal(i)|i#ne#2 #and# i#ne#4:x(i)<=4);
@for(needs(j):@sum(eachadd(i,j):x(i)*c(i,j))>need(j));
enddata
end

结果为    :

 

 ③选址问题

第一题代码:

model:
sets:
work/1..6/:x,y,need;
company/1..2/:x1,y1,e;
link(company,work):n;
endsets
data:
x = 1.25 8.75 0.5 5.75 3 7.25;
y = 1.25 0.75 4.75 5 6.5 7.75;
need = 3,5,4,7,6,11;
x1 = 5,2;
y1 = 1,7;
e = 20,20;
enddata
min = @sum(link(i,j):n(i,j)*((x(j) - x1(i))^2 +(y(j) - y1(i))^2)^0.5);
@for(company(i):@sum(link(i,j):n(i,j))<=e(i));
@for(work(j):@sum(link(i,j):n(i,j))=need(j));
end

第二题:

因为料场重建,直接将原来的料场坐标取消即可,也可以对其进行初始化

init:

x1 = 5,2;

y1 = 1,7;

endinit

 

④指派问题(使用了0-1规划)

    

model:
sets:
people/1..5/;
work/1..5/;
link(people,work):time,x;
endsets
data:
time = 8,6,10,9,12,
9,12,7,11,9,
7,4,3,5,8,
9,5,8,11,8,
4,6,7,5,11;
enddata
min = @sum(link:time*x);
@for(work(j):@sum(link(i,j):x(i,j))= 1);
@for(people(i):@sum(link(i,j):x(i,j)) = 1);
@for(link:@bin(x));
end

⑤装箱问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值