zoukankan      html  css  js  c++  java
  • 简学LINGO(三)——实例篇

    1. 装配线平衡模型

    一个装配线含有一系列的工作站。在终于产品的加工过程中每一个工作站运行一种或者是几种特定的任务。装配线周期是指全部工作站完毕分配给他们各自任务所花费时间的最大值。平衡装配线的目标是为每一个工作站分配加工任务。尽可能使每一个工作站运行同样数量的任务。其终于标准是转配线周期最短。

    不适当的平衡装配线将会产生瓶颈——有较少任务的工作站将被迫等待前面分配了较多任务的工作站。

    这个模型的目标是最小化装配线周期。有两类约束:

    (1)要保证每件任务仅仅能也必须分配至一个工作站来加工;

    (2)要保证满足任务件的全部优先关系。

    例  有1件任务(A-K)分配到四个工作站(1-4),任务按次序例如以下。每件任务所花时间例如以下

    任务

    时间

    A

    45

    B

    11

    C

    9

    D

    50

    E

    15

    F

    12

    G

    12

    H

    12

    I

    12

    J

    8

    K

    9

     

    这里给出求解模型

    model:
     !装配平衡模型;
    sets:
     !任务集合,有一个完毕时间属性T;
     TASK/A B C D E F G H I J K/:T;
     !人物之间的优先关系集合;
     PRED(TASK,TASK)/A,B B,C C,F C,G F,J G,J J,K
         D,E E,H E,I H,J I,J/;
     !工作站集合;
     STATION/1..4/;
     TXS(TASK,STATION):X;
     !X是派生集TXS的一个属性。

    假设X(I,K)=I,则表示第I个任务指派给第K个工作站完毕; endsets data: !任务A B C D E F G H I J K的完毕时间预计例如以下; enddata !当任务超过15个时,模型求解将变的非常慢: !每个作业必须指派到一个工作站中; @for(TASK(I):@SUM(STATION(K):X(I,K))=1); !对于每个存在有限关系的作业来说。前者相应的工作站I必须小于后者相应的工作站J; @for(PRED(I,J):@sum(STATION(K):K*X(J,K)-K*X(I,K))>=0); !对于每个工作站来说,其花费时间不应大于装配线周期; @for(STATION(K): @SUM(TXS(I,K):T(I)*X(I,K))<+CYCTIME); !目标函数时最小化转配线周期; min=CYCTIME; !指定X(I,J)为0/1变量; @for(TXS:@BIN(X)); end

     

     

    2.旅行售货员问题,又称货郎担问题

    有一个销售员,从城市1出发。要遍訪城市2,3,。。

    。,n个一次。最后返回城市1.已知从城市i到j的旅费为Cij,问他该按如何的次序訪问这些城市,是得总旅费最少?能够用多中方方法把TSP表示成整数规划模型。把该问题的每个解看做时一个巡回。

    在上述意义下,引入0-1整数变量
     

    经过若干证明。这里就不在阐述了,我们能够把TSP转化为一个混合整数规划问题

     

     

     这里我们能够利用这个问题来求解一个详细问题

     问题1  现须要一台机器上加工n个零件。这些零件能够依照随意先后顺序在机器上进行加工。我们希望加工完毕全部零件的总时间最小。因为加工工艺的要求,加工零件j时机器不许处在对应的状态Sj(如炉温)。设起始未加工不论什么零件时机器处于状态S0。且当全部零件加工完毕后需回复到S0状态。已知从状态Si调整到Sj须要时间Cij。零件j本身加工时间为Pj。

    为方便起见,引入一个徐零件0,当中加工时间为0。要求状态为S0。则{0,1,2,。。

    ,n}的一个圈置转换pi就表示对全部零件的一个加工顺序。则完毕全部加工所需时间为

     

    这里给出一个解决该模型的一个简单的代码。就是套用上面的模型

    !旅行售货员问题;
    model:
    sets:
      city/1..5/:u;
      link(city,city):dist,x;
    endsets
      n=@size(city);
    data:
      dist=@qrand(1);!随即产生。这里能够改为你要解决的问题的数据;
    enddata
     !目标函数;
    min=@sum(link:dist*x);
    @for(city(K):
      @sum(city(I)|I#ne#K:x(I,K))=1;
      @sum(city(J)|J#ne#K:x(K,J))=1;
    );
    
    !保证不出圈子;
    @for(city(I)|I#gt#1:
      @for(city(J)|J#gt#1 #and# I#ne#j:
         u(I)-u(J)+n*x(I,J)<=n-1);
    );
    !定义X为0/1变量;
    @for(link:@bin(x));
    end
    


    3.最短路问题

    给定N个点Pi组成集合{Pi}。由集合中任一点Pi到还有一点Pj的距离用Cij表示,假设Pi到Pj没有弧连接,则规定Cij=正无穷大,有规定Cii=0,指定一个终点PN。要求从Pi到PN的最短路线。这里我们用动态规划的方法来做。

     

     又LINGO我们能够非常方便的求解上述的模型

    !最短路问题;
    model:
    data:
      n=10;
    enddata
    sets:
      cities/1..n/:F;
      roads(cities,cities)/
    	1,2 1,3
    	2,4 2,5 2,6
    	3,4 3,5 3,6
    	4,7 4,8
    	5,7 5,8 5,9
    	6,8 6,9
    	7,10
    	8,10
    	9,10
    /:D,P;
    endsets
    data:
    D=
    	6 5                 !该矩阵即为传说中的权重矩阵
    	3 6 9
    	7 5 11
    	9 1
    	8 7 5
    	4 10
    	5
    	7
    	9;
    enddata
    F(n)=0;
    @for(cities(i)|i#lt#n:
      F(i)=@min(roads(i,j):D(i,j)+F(j));
    );
    !显然。假设P(i,j)=1,则点i到点n的最短路径的第一步是i——j,否则就不是
    由此,我们就可方便的确定出最短路径;
    @for(roads(i,j):
    	P(i,j)=@if(F(i)#eq#D(i,j)+F(j),1,0)
    );
    end

     

    4.分配问题或称指派问题

    这是给n个人分配n项工作以或得摸个最高效果的问题。

    第i个人完毕第j项工作须要的平均时间为Cij。

    要求给每一个人分配一项工作。并要求分配完这些工作,以使完毕所有任务的总时间最小。该问题能够表演示样例如以下
     

     这个模型能够用LINGO非常方便的求解

    model:
      !7个工人,7个工作的分配问题;
    sets:
    	workers/w1..w7/;
    	jobs/j1..j7/;
    	links(workers,jobs):cost,volume;
    endsets
      !目标函数;
    	min=@sum(links:cost*volume);
      !每一个人仅仅能有一份工作;
    	@for(workers(I):
    		@sum(jobs(J):volume(I,J))=1;
    	);
    data:
    	cost=6 2 6 7 4 2 5
    	     4 9 5 3 8 5 8
    	     5 2 1 9 7 4 3
    	     7 6 7 3 9 2 7
    	     2 3 9 5 7 2 6
    	     5 5 2 2 8 11 4
    	     9 2 3 12 4 5 10;
    enddata
    end 	


     

    5.二次分配问题

    这个问题与上面的分配问题 。大致相同。相同要引入0-1变量,并且和上述问题有相同的约束 。可是本问题又比约束问题要复杂。我们得到价格系数Cijkl,其解释是:在i(S上网一个元素)分配给j(T的一个元素)的同一时候把k(s的一个元素)分配给l(T的一个元素)所应承担的费用。显然仅仅有当xij=1且xkl=1时,才承担这样的费用。

    这时我们的模型要变成这样

     为了理解这个模型。我们在这里增加这个样例。

    首先觉得S是一个工厂的集合。T是n个城市的集合。本问题就是要在每个城市设置一个工厂,并要使工厂之间的总得通讯费用最少。通讯费用取决于:(1)每对工厂之间通讯的次数tik;(2)每对工厂所在两个城市之间的距离djl。所以就有cijkl=tik*djl(各位大仙凑活的看啊。。。)。

    因此总费用能够用上述的目标函数来表示。

    这里给出一个非常经典的题目,也是我遇到的第一道建模问题。想当年不知道lingo的优点。硬是凭着对C++的执拗,用了一堆栈啊。链表向量什么的用穷举给退出来啊,当时多么的自豪。哈哈哈

     

    例:有四名同学到一家公司去參加三个阶段的面试:公司要求每一个同学必须先找秘书初试,然后到部门主管去复制。最后到经理处去面试,而且不同意插队。因为四名同学的专业背景不同,所以没人在三个阶段的面试时间也不一样,例如以下表。

    这四名同学约定他们所有面试完毕以后一起离开公司,问他们最快用多长时间完毕面试?

     

    这里给出求解的代码

     

    !三阶段面试模型;
    model:
    sets:
    	students;!学生集三阶段面试模型;
    	phases;!阶段集;
    	sp(students,phases):t,x;
    	ss(students,students)|&1 #lt# &2:y;
    endsets
    data:
    	students=s1..s4;
    	phases=p1..p3;
    	t=
    		13 15 20
    		10 20 18
    		20 16 10
    		8  10 15;
    enddata
    	ns=@size(students);!学生数;
    	np=@size(phases);!阶段数
    	
    	!单个学生面试时间先后顺序的约束;
    	@for(sp(I,J)|J#LT#np:
    		x(I,J)+t(I,J)<=x(I,J+1)
    	);
    	!学生间的面试先后次序保持不变的约束;
    	@for(ss(I,K):
    		@for(phases(J):
    		x(I,J)+t(I,J)-x(K,J)<=200*y(I,K);
    		x(K,J)+t(K,J)-x(I,J)<=200*(1-y(I,K));
    		)
    	);
    	min=TMAX;
    	@for(students(I):
    		x(I,3)+t(I,3)<=TMAX
    	);
    	!把Y定义0-1变量;
    	!把Y定义0-1变量;
    	@for(ss:@bin(y));
    end
    
    


     以后假设遇到对应的更好的模型是,我会有选择的加上的。

     

     

     

     

     

  • 相关阅读:
    php stdClass转数组
    PHP 获取1970年前的时间戳,且为负
    springboot响应格式Resullt封装
    php使用elasticsearch
    day0620211207
    day0820211209
    day022021121
    day0520211206
    day0720211208
    day0320211202
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5319476.html
Copyright © 2011-2022 走看看