ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

校车运输空返问题

2021-05-04 09:57:29  阅读:1007  来源: 互联网

标签:运输 school old 校车 sun time 空返 new sat


校车运输空返问题

记录2021年“工大出版社”数学建模竞赛A题的代码求解

背景

某学校每天有教职工从老校区乘车到新校区工作,工作后大多数人会返回。后勤集团每天会安排车辆在新老校区之间往返运行。但某些时段新老校区需要乘车的人数不均衡,如早上主要是老校区的教职工乘车到新校区,中午和下午下班时主要是教职工从老校区返回新校区。由于车辆有限,有时候为了满足当前校区车辆的需求,需要从另一校区调度空车返回(称为空返)。如何使空返的车辆数尽量少是后勤集团十分关心的问题。
该校班车运行时刻表如下:
一、周一至周五

  1. 老校区到新校区
    7:00,8:00,9:20、10:00、11:00、12:00、12:50、14:00、14:50、16:00、17:00、17:50、21:00、22:30。

  2. 新校区到老校区
    9:00、10:30、11:00、12:30、14:00、15:00、16:00、17:10、18:00、19:00、21:00、22:30。
    二、周六、周日

  3. 老校区到新校区
    8:00、9:20、12:50、14:00、18:00、20:00。

  4. 新校区到老校区
    9:00、 11:00、12:30、17:00、18:00、21:00。

    车辆在两校区运行时间时间为一个小时左右。为简化起见,假设每辆车从一个校区到另一个校区的时间都为一个小时。由于两校区不同时刻对车辆的需求不平衡,当某个校区需要的车辆数多,现有车辆不能满足需求,这时需要从另一个校区调度空车返回。空车可以在现有发车时刻表中某一时刻发车,也可以在需要的时候提前一个小时发车。
    该校总共有车辆20辆,每辆可载客人47人。请你建立数学模型仔细考虑下面问题。

模型概述

本道题一以贯之的是一个整数规划模型,决策变量为所有发车时刻的实际发车数和初始时刻两校区的校车数。目标函数则是空返车数,空返车数实际上就是实际发车数减去目标发车数。再对每个时刻求和。

题目

问题1

若某天(周一到周五)老校区到新校区对应14个发车时刻需要的车辆数为7、6、4、3、1、1、4、3、1、2、1、2、1、1;新校区到老校区需要的车辆数为2、3、2、6、2、1、7、6、4、2、1、1。通过计算探究能否实现车辆不空载。若能实现,给出车辆安排方式;若一定会出现空载,那么如何安排可使空返车辆数最少?若老校区到新校区需要车辆数为9、8、4、3、1、1、4、3、1、2、1、2、1、1,新校区到老校区需要的车辆数为3、4、2、6、2、1、7、8、4、2、1、1,情况又如何?请给出初始两校区车辆数,当天停止运行后两校区车辆数,总的空返车辆数。

Lingo代码:
在一二小问切换时,只需要讲target的注释修改即可

MODEL:
!定义集合;
SETS:
new/1..12/:new_school,new_time,target_new;
old/1..14/:old_school,old_time,target_old;
un/1..11/;
uo/1..13/;
initial/1/:old_init_num;
ENDSETS
DATA:
new_time=9,10.5,11,12.5,14,15,16,17,18,19,21,22.5;
old_time=7,8,9.3333,10,11,12,12.8333,14,14.8333,16,17,17.8333,21,22.5;
target_new=3,4,2,6, 2,1,7,8, 4,2,1,1;
target_old=9,8,4,3,1,1,4,3,1,2,1,2,1,1;
!target_new=2,3,2,6, 2,1,7,6, 4,2,1,1;
!target_old=7,6,4,3,1,1,4,3,1,2,1,2,1,1;
@ole('C://Users//86183//Desktop//output1_1.xlsx','A')=new_school;
@ole('C://Users//86183//Desktop//output1_1.xlsx','B')=old_school;
@ole('C://Users//86183//Desktop//output1_1.xlsx','S')=old_init_num;
ENDDATA
min=@sum(new(i):(new_school(i)-target_new(i)))+@sum(old(i):(old_school(i)-target_old(i)));
@for(initial(i):
	old_init_num(i)>=old_school(1)+old_school(2);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(new(i):
	new_school(i)>=target_new(i)
);
@for(old(i):
	old_school(i)>=target_old(i)
);
@for(new(i):
	@for(uo(j)|(old_time(j)+1)#le#new_time(i) #and# new_time(i)#lt#(old_time(j+1)+1):
			(20-old_init_num(1))+(@sum(old(k)|k#le#j:old_school(k))-@sum(new(k)|k#lt#i:new_school(k)))>=new_school(i)
	)
);
@for(old(i)|i#ge#3:
	@for(un(j)|(new_time(j)+1)#le#old_time(i) #and# old_time(i)#lt#(new_time(j+1)+1):
			old_init_num(1)+(@sum(new(k)|k#le#j:new_school(k))-@sum(old(k)|k#lt#i:old_school(k)))>=old_school(i)
	)
);
@for(new(i):
	@gin(new_school(i))
);
@for(old(i):
	@gin(old_school(i))
);

最终解得:
在这里插入图片描述
对于问题1第2小问,最少的空返数是5

问题2

如果保持每天连续运行,每天老校区各班次需要车辆数仍为9,8,4,3,1,1,4,3,1,2,1,2,1,1;新校区各班次需要的车辆仍为3,4,2,6, 2,1,7,8, 4,2,1,1,问如何安排可使一周(周一到周五)空返车辆数总数最少?
要求给出周一初始两校区车辆数,周五停止运行后两校区车辆数,总的空返车辆数。

Lingo代码:

MODEL:
!定义集合;
SETS:
new/1..12/:new_time,target_new;
old/1..14/:old_time,target_old;
un/1..11/;
uo/1..13/;
initial/1..5/:old_init_num;
days/1..5/;
dayso/1..4/;
newweek(days,new):new_school;
oldweek(days,old):old_school;
ENDSETS
DATA:
new_time=9,10.5,11,12.5,14,15,16,17,18,19,21,22.5;
old_time=7,8,9.3333,10,11,12,12.8333,14,14.8333,16,17,17.8333,21,22.5;
target_new=3,4,2,6, 2,1,7,8, 4,2,1,1;
target_old=9,8,4,3,1,1,4,3,1,2,1,2,1,1;
@ole('C:\Users\86183\Desktop\output2.xlsx','q')=new_school;
@ole('C:\Users\86183\Desktop\output2.xlsx','w')=old_school;
@ole('C:\Users\86183\Desktop\output2.xlsx','e')=old_init_num;
ENDDATA
min=@sum(newweek(i,j):(new_school(i,j)-target_new(j)))+@sum(oldweek(i,j):(old_school(i,j)-target_old(j)));
@for(initial(i):
	old_init_num(i)>=old_school(i,1)+old_school(i,2);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(newweek(i,j):
	new_school(i,j)>=target_new(j)
);
@for(oldweek(i,j):
	old_school(i,j)>=target_old(j)
);
!对于新校区;
@for(days(i):
	@for(new(j):
		@for(uo(n)|(old_time(n)+1)#le#new_time(j) #and# new_time(j)#lt#(old_time(n+1)+1):
		(20-old_init_num(i))+@sum(old(k)|k#le#n:old_school(i,k))-@sum(new(k)|k#lt#j:new_school(i,k))>=new_school(i,j)
		)
	)
);
!对于老校区;
@for(days(i):
	@for(old(j)|j#ge#3:
		@for(un(n)|(new_time(n)+1)#le#old_time(j) #and# old_time(j)#lt#(new_time(n+1)+1):
		old_init_num(i)+@sum(new(s)|s#le#n:new_school(i,s))-@sum(old(s)|s#lt#j:old_school(i,s))>=old_school(i,j)
		)
	)
);
@for(dayso(i):old_init_num(i+1)=old_init_num(i)
			-@sum(old(j):old_school(i,j))
			+@sum(new(j):new_school(i,j))
);
@for(newweek(i,j):
	@gin(new_school(i,j))
);
@for(oldweek(i,j):
	@gin(old_school(i,j))
);


最终解得:
在这里插入图片描述

对于问题2,最少的空返数是29

问题3

若周六老校区各班次需要车辆数为:5,4,6,4,3,2;新校区为:3,5,7,6,2,1。周日老校区各班次需要车辆数为:5,4,4,6,3,7;新校区为:2,6,5,3,3,1。考虑周一到周日共7天,如何安排使空返车辆数最少?
要求给出周一初始两校区车辆数,周日停止运行后两校区车辆数,总的空返车辆数。

Lingo代码:

MODEL:
!定义集合;
SETS:
new/1..12/:new_time,target_new;
old/1..14/:old_time,target_old;
sat_new/1..6/:new_sat_time,target_new_sat,new_school_sat;
sat_old/1..6/:old_sat_time,target_old_sat,old_school_sat;
sun_new/1..6/:new_sun_time,target_new_sun,new_school_sun;
sun_old/1..6/:old_sun_time,target_old_sun,old_school_sun;
un/1..11/;
uo/1..13/;
un_weekend/1..5/;
uo_weekend/1..5/;
initial/1..7/:old_init_num;
days/1..5/;
dayso/1..4/;
sat/1/;
sun/1/;
newweek(days,new):new_school;
oldweek(days,old):old_school;
ENDSETS
DATA:
new_time=9,10.5,11,12.5,14,15,16,17,18,19,21,22.5;
old_time=7,8,9.3333,10,11,12,12.8333,14,14.8333,16,17,17.8333,21,22.5;
new_sat_time=9,11,12.5,17,18,21;
old_sat_time=8,9.3333,12.8333,14,18,20;
new_sun_time=9,11,12.5,17,18,21;
old_sun_time=8,9.3333,12.8333,14,18,20;
target_new=3,4,2,6, 2,1,7,8, 4,2,1,1;
target_old=9,8,4,3,1,1,4,3,1,2,1,2,1,1;
target_new_sat=3,5,7,6,2,1;
target_old_sat=5,4,6,4,3,2;
target_new_sun=2,6,5,3,3,1;
target_old_sun=5,4,4,6,3,7;
@ole('C:\Users\86183\Desktop\output3.xlsx','q')=new_school;
@ole('C:\Users\86183\Desktop\output3.xlsx','w')=old_school;
@ole('C:\Users\86183\Desktop\output3.xlsx','e')=old_init_num;
@ole('C:\Users\86183\Desktop\output3.xlsx','a')=new_school_sat;
@ole('C:\Users\86183\Desktop\output3.xlsx','s')=old_school_sat;
@ole('C:\Users\86183\Desktop\output3.xlsx','d')=new_school_sun;
@ole('C:\Users\86183\Desktop\output3.xlsx','f')=old_school_sun;
ENDDATA
min=@sum(newweek(i,j):(new_school(i,j)-target_new(j)))+@sum(oldweek(i,j):(old_school(i,j)-target_old(j))) + 
	@sum(sat_new(i):(new_school_sat(i)-target_new_sat(i))) + @sum(sat_old(i):(old_school_sat(i)-target_old_sat(i)))+
	@sum(sun_new(i):(new_school_sun(i)-target_new_sun(i))) + @sum(sun_old(i):(old_school_sun(i)-target_old_sun(i)))	
;
@for(initial(i)|i#le#5:
	old_init_num(i)>=old_school(i,1)+old_school(i,2);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(initial(i)|i#eq#6:
	old_init_num(i)>=old_school_sat(1);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(initial(i)|i#eq#7:
	old_init_num(i)>=old_school_sun(1);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(newweek(i,j):
	new_school(i,j)>=target_new(j)
);
@for(oldweek(i,j):
	old_school(i,j)>=target_old(j)
);

@for(sat_new(i):
	new_school_sat(i)>=target_new_sat(i)
);
@for(sat_old(i) :
	old_school_sat(i)>=target_old_sat(i)
);

@for(sun_new(i):
	new_school_sun(i)>=target_new_sun(i)
);
@for(sun_old(i) :
	old_school_sun(i)>=target_old_sun(i)
);
!对于新校区;
@for(days(i):
	@for(new(j):
		@for(uo(n)|(old_time(n)+1)#le#new_time(j) #and# new_time(j)#lt#(old_time(n+1)+1):
		(20-old_init_num(i))+@sum(old(k)|k#le#n:old_school(i,k))-@sum(new(k)|k#lt#j:new_school(i,k))>=new_school(i,j)
		)
	)
);
@for(sat_new(i):
	@for(uo_weekend(j)|(old_sat_time(j)+1)#le#new_sat_time(i) #and# new_sat_time(i) #lt#(old_sat_time(j+1)+1):
	(20-old_init_num(6))+@sum(sat_old(k)|k#le#j:old_school_sat(k))-@sum(sat_new(k)|k #lt#i:new_school_sat(k))>=new_school_sat(i)
	)
);
@for(sun_new(i):
	@for(uo_weekend(j)|(old_sun_time(j)+1)#le#new_sun_time(i) #and# new_sun_time(i) #lt#(old_sun_time(j+1)+1):
	(20-old_init_num(7))+@sum(sun_old(k)|k#le#j:old_school_sun(k))-@sum(sun_new(k)|k #lt#i:new_school_sun(k))>=new_school_sun(i)
	)
);
!对于老校区;
@for(days(i):
	@for(old(j)|j#ge#3:
		@for(un(n)|(new_time(n)+1)#le#old_time(j) #and# old_time(j)#lt#(new_time(n+1)+1):
		old_init_num(i)+@sum(new(s)|s#le#n:new_school(i,s))-@sum(old(s)|s#lt#j:old_school(i,s))>=old_school(i,j)
		)
	)
);
@for(sat_old(i)|i#ge#2:
	@for(un_weekend(j)|(new_sat_time(j)+1)#le#old_sat_time(i) #and# old_sat_time(i)#lt#(new_sat_time(j+1)+1):
	old_init_num(6)+(@sum(sat_new(k)|k#le#j:new_school_sat(k))-@sum(sat_old(k)|k#lt#i:old_school_sat(k)))>=old_school_sat(i)
	)
);

@for(sun_old(i)|i#ge#2:
	@for(un_weekend(j)|(new_sun_time(j)+1)#le#old_sun_time(i) #and# old_sun_time(i)#lt#(new_sun_time(j+1)+1):
	old_init_num(7)+(@sum(sun_new(k)|k#le#j:new_school_sun(k))-@sum(sun_old(k)|k#lt#i:old_school_sun(k)))>=old_school_sun(i)
	)
);

@for(dayso(i):old_init_num(i+1)=old_init_num(i)
			-@sum(old(j):old_school(i,j))
			+@sum(new(j):new_school(i,j))
);
@for(sat(i):old_init_num(i+5)=old_init_num(5)
			-@sum(old(j):old_school(5,j))
			+@sum(new(j):new_school(5,j))
);
@for(sun(i):old_init_num(i+6)=old_init_num(6)
					-@sum(sat_old(j):old_school_sat(j))
					+@sum(sat_new(j):new_school_sat(j))
);

@for(newweek(i,j):
	@gin(new_school(i,j))
);
@for(oldweek(i,j):
	@gin(old_school(i,j))
);
@for(sat_new(i):
	@gin(new_school_sat(i));
);
@for(sat_old(i):
	@gin(old_school_sat(i));
);
@for(sun_new(i):
	@gin(new_school_sun(i));
);
@for(sun_old(i):
	@gin(old_school_sun(i));
);

最终解得:
在这里插入图片描述
对于问题3,最少的空返数是34

问题4

在实际车辆调度中,希望每周能持续运行。在问题3的要求下,若再要求周日停止运行后两校区的车辆数与周一初始两校区车辆数相同,如何安排使空返车辆数最少?
要求给出周一初始两校区车辆数或周日停止运行后两校区车辆数,总的空返车辆数。

Lingo代码:

MODEL:
!定义集合;
SETS:
new/1..12/:new_time,target_new;
old/1..14/:old_time,target_old;
sat_new/1..6/:new_sat_time,target_new_sat,new_school_sat;
sat_old/1..6/:old_sat_time,target_old_sat,old_school_sat;
sun_new/1..6/:new_sun_time,target_new_sun,new_school_sun;
sun_old/1..6/:old_sun_time,target_old_sun,old_school_sun;
un/1..11/;
uo/1..13/;
un_weekend/1..5/;
uo_weekend/1..5/;
initial/1..8/:old_init_num;
days/1..5/;
dayso/1..4/;
sat/1/;
sun/1/;
mon/1/;
newweek(days,new):new_school;
oldweek(days,old):old_school;
ENDSETS
DATA:
new_time=9,10.5,11,12.5,14,15,16,17,18,19,21,22.5;
old_time=7,8,9.3333,10,11,12,12.8333,14,14.8333,16,17,17.8333,21,22.5;
new_sat_time=9,11,12.5,17,18,21;
old_sat_time=8,9.3333,12.8333,14,18,20;
new_sun_time=9,11,12.5,17,18,21;
old_sun_time=8,9.3333,12.8333,14,18,20;
target_new=3,4,2,6, 2,1,7,8, 4,2,1,1;
target_old=9,8,4,3,1,1,4,3,1,2,1,2,1,1;
target_new_sat=3,5,7,6,2,1;
target_old_sat=5,4,6,4,3,2;
target_new_sun=2,6,5,3,3,1;
target_old_sun=5,4,4,6,3,7;
@ole('C:\Users\86183\Desktop\output4.xlsx','q')=new_school;
@ole('C:\Users\86183\Desktop\output4.xlsx','w')=old_school;
@ole('C:\Users\86183\Desktop\output4.xlsx','e')=old_init_num;
@ole('C:\Users\86183\Desktop\output4.xlsx','a')=new_school_sat;
@ole('C:\Users\86183\Desktop\output4.xlsx','s')=old_school_sat;
@ole('C:\Users\86183\Desktop\output4.xlsx','d')=new_school_sun;
@ole('C:\Users\86183\Desktop\output4.xlsx','f')=old_school_sun;
ENDDATA
min=@sum(newweek(i,j):(new_school(i,j)-target_new(j)))+@sum(oldweek(i,j):(old_school(i,j)-target_old(j))) + 
	@sum(sat_new(i):(new_school_sat(i)-target_new_sat(i))) + @sum(sat_old(i):(old_school_sat(i)-target_old_sat(i)))+
	@sum(sun_new(i):(new_school_sun(i)-target_new_sun(i))) + @sum(sun_old(i):(old_school_sun(i)-target_old_sun(i)))	
;
@for(initial(i)|i#le#5:
	old_init_num(i)>=old_school(i,1)+old_school(i,2);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(initial(i)|i#eq#6:
	old_init_num(i)>=old_school_sat(1);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(initial(i)|i#eq#7:
	old_init_num(i)>=old_school_sun(1);
	old_init_num(i)>=0;
	old_init_num(i)<=20;
);
@for(newweek(i,j):
	new_school(i,j)>=target_new(j)
);
@for(oldweek(i,j):
	old_school(i,j)>=target_old(j)
);

@for(sat_new(i):
	new_school_sat(i)>=target_new_sat(i)
);
@for(sat_old(i) :
	old_school_sat(i)>=target_old_sat(i)
);

@for(sun_new(i):
	new_school_sun(i)>=target_new_sun(i)
);
@for(sun_old(i) :
	old_school_sun(i)>=target_old_sun(i)
);
!对于新校区;
@for(days(i):
	@for(new(j):
		@for(uo(n)|(old_time(n)+1)#le#new_time(j) #and# new_time(j)#lt#(old_time(n+1)+1):
		(20-old_init_num(i))+@sum(old(k)|k#le#n:old_school(i,k))-@sum(new(k)|k#lt#j:new_school(i,k))>=new_school(i,j)
		)
	)
);
@for(sat_new(i):
	@for(uo_weekend(j)|(old_sat_time(j)+1)#le#new_sat_time(i) #and# new_sat_time(i) #lt#(old_sat_time(j+1)+1):
	(20-old_init_num(6))+@sum(sat_old(k)|k#le#j:old_school_sat(k))-@sum(sat_new(k)|k #lt#i:new_school_sat(k))>=new_school_sat(i)
	)
);
@for(sun_new(i):
	@for(uo_weekend(j)|(old_sun_time(j)+1)#le#new_sun_time(i) #and# new_sun_time(i) #lt#(old_sun_time(j+1)+1):
	(20-old_init_num(7))+@sum(sun_old(k)|k#le#j:old_school_sun(k))-@sum(sun_new(k)|k #lt#i:new_school_sun(k))>=new_school_sun(i)
	)
);
!对于老校区;
@for(days(i):
	@for(old(j)|j#ge#3:
		@for(un(n)|(new_time(n)+1)#le#old_time(j) #and# old_time(j)#lt#(new_time(n+1)+1):
		old_init_num(i)+@sum(new(s)|s#le#n:new_school(i,s))-@sum(old(s)|s#lt#j:old_school(i,s))>=old_school(i,j)
		)
	)
);
@for(sat_old(i)|i#ge#2:
	@for(un_weekend(j)|(new_sat_time(j)+1)#le#old_sat_time(i) #and# old_sat_time(i)#lt#(new_sat_time(j+1)+1):
	old_init_num(6)+(@sum(sat_new(k)|k#le#j:new_school_sat(k))-@sum(sat_old(k)|k#lt#i:old_school_sat(k)))>=old_school_sat(i)
	)
);

@for(sun_old(i)|i#ge#2:
	@for(un_weekend(j)|(new_sun_time(j)+1)#le#old_sun_time(i) #and# old_sun_time(i)#lt#(new_sun_time(j+1)+1):
	old_init_num(7)+(@sum(sun_new(k)|k#le#j:new_school_sun(k))-@sum(sun_old(k)|k#lt#i:old_school_sun(k)))>=old_school_sun(i)
	)
);

@for(dayso(i):old_init_num(i+1)=old_init_num(i)
			-@sum(old(j):old_school(i,j))
			+@sum(new(j):new_school(i,j))
);
@for(sat(i):old_init_num(i+5)=old_init_num(5)
			-@sum(old(j):old_school(5,j))
			+@sum(new(j):new_school(5,j))
);
@for(sun(i):old_init_num(i+6)=old_init_num(6)
					-@sum(sat_old(j):old_school_sat(j))
					+@sum(sat_new(j):new_school_sat(j))
);
@for(mon(i):old_init_num(i+7)=old_init_num(7)
					-@sum(sun_old(j):old_school_sun(j))
					+@sum(sun_new(j):new_school_sun(j))
);
@for(mon(i):old_init_num(i+7)=old_init_num(1)
);
@for(newweek(i,j):
	@gin(new_school(i,j))
);
@for(oldweek(i,j):
	@gin(old_school(i,j))
);
@for(sat_new(i):
	@gin(new_school_sat(i));
);
@for(sat_old(i):
	@gin(old_school_sat(i));
);
@for(sun_new(i):
	@gin(new_school_sun(i));
);
@for(sun_old(i):
	@gin(old_school_sun(i));
);

最终解得:
在这里插入图片描述
对于问题3,最少的空返数是49

标签:运输,school,old,校车,sun,time,空返,new,sat
来源: https://blog.csdn.net/qq_45757722/article/details/116394930

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有