需求未必是变态的,关键看怎么理解需求

 见这个问题
http://topic.csdn.net/u/20070921/22/f09d8bdb-ce93-4e7f-9847-6ec23d344d77.html?seed=1171977409

体能测试时间安排
某校按照教学计划安排各班学生进行体能测试,以了解学生的身体状况。测试包括身高与体重、立定跳远、肺活量、握力和台阶试验共5个项目,均由电子仪器自动测量、记录并保存信息。该校引进身高与体重测量仪器3台,立定跳远、肺活量测量仪器各1台,握力和台阶试验测量仪器各2台。
身高与体重、立定跳远、肺活量、握力4个项目每台仪器每个学生的平均测试(包括学生的转换)时间分别为10秒、20秒、20秒、15秒,台阶试验每台仪器一次测试5个学生,需要3分30秒。
每个学生测试每个项目前要录入个人信息,即学号,平均需时5秒。仪器在每个学生测量完毕后学号将自动后移一位,于是如果前后测试的学生学号相连,就可以省去录入时间,而同一班学生的学号是相连的。
学校安排每天的测试时间为8:00-12:10与13:30-16:45两个时间段。5项测试都在最多容纳150个学生的小型场所进行,测试项目没有固定的先后顺序。参加体能测试的各班人数见附表。
学校要求同一班的所有学生在同一时间段内完成所有项目的测试,并且在整个测试所需时间段数最少的条件下,尽量节省学生的等待时间。
请你用数学符号和语言表述各班测试时间安排问题,给出该数学问题的算法,尽量用清晰、直观的图表形式为学校工作人员及各班学生表示出测试时间的安排计划,并且说明该计划怎样满足学校的上述要求和条件。
最后,请对学校以后的体能测试就以下方面提出建议,并说明理由:如引进各项测量仪器的数量;测试场所的人员容量;一个班的学生是否需要分成几个组进行测试等。

附表  参加体能测试的各班人数
                                   
班号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
人数 41 45 44 44 26 44 42 20 20 38 37 25 45 45 45
班号 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
人数 44 20 30 39 35 38 38 28 25 30 36 20 24 32 33
班号 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
人数 41 33 51 39 20 20 44 37 38 39 42 40 37 50 50
班号 46 47 48 49 50 51 52 53 54 55 56
人数 42 43 41 42 45 42 19 39 75 17 17

----------------------------------------------------------------------------------------------------------------------------------
面对上面的这些条件,最后的建模必须做需求的分析:

1,测试时间都大于录入学号时间.可以同时测试同时录学号,每个设备多安排一个志愿者录学号就可以,所以那5秒是骗人的,几乎没影响.

2,,仪器效率最好是接近1:1:1:1,这样不会出现瓶颈,减少人流交叉.
体重测量仪器3台,每次一个人,10秒测完,效率是 3*1/10=3/10  (人/秒)
立定跳远1台,每次一个人,20秒测完,效率是 1*1/20=1/20  (人/秒)
肺活量测量仪器1台,每次一个人,20秒测完,效率是 1*1/20=1/20  (人/秒)
握力2台,每次一个人,15秒测完,效率是 1*1/15=1/15  (人/秒)
台阶试验测量仪器2台,每次5个人,210秒测完,效率是 2*5/210=1/21  (人/秒)

可见除了体重测量仪器和握力能力过剩,
瓶颈因素是立定跳远,肺活量,台阶试验测量仪器,应该建议学校补充其他设备,按照效率1:1:1:1配置.

3,按照目前的情况,不考虑在场地等待和录学号,每个人有效测试时间是260秒

在最慢的2个台阶试验测量仪器工作一个周期210秒内.流过了10人,如果这时候其他设备都不闲着.
体重测量仪器3台,可以流过3*210/10=62人
立定跳远1台,可以流过1*210/20=10.5人
肺活量测1台,可以流过1*210/20=10.5人
握力2台,可以流过2*210/15=28人

可以组织其他人充分利用其余设备,最快通过速度取决于台阶试验测量仪器,速度为一轮10个人,
(人数*210/10)=21*n 按照210取整 再加上5秒录学号(台阶测试仪器每台最好5个人录学号前).
 
就是说最少人数的班级17人独占场地的话,需要2轮, 需要最快425秒(7-8分钟)通过.
最多人数的班级75人,需要8轮,需要最快1680秒(28-30分钟)通过.

4,从上面分析可以看出,最好策略是一次只通知一个班级,场地几乎不会造成影响,只要场地多于最大班级人数就足够了,
按照上面的计算规则,计算出每个班级的最少时间,顺次通知各个班级就可以了,上午总共有250分钟,下午195分钟.平均每个班估计是10-15分钟的话,
一天可以搞30-40班,所以预计2天可以搞定.所以只有4个半天可以供决策.
先从班级人数最多的安排在每天上/下午第一个,依次往小了排就可以了.

用C#创建一个WebForm这样直观,而且方便通知大家,结果见www.dullwolf.cn/project3.htm 
代码如下:
C# code
   
   
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Text; namespace project3 { public partial class _Default : System.Web.UI.Page { // 输出图形 protected StringBuilder HTML = new StringBuilder( "" ); protected void Page_Load( object sender, EventArgs e) { // 班级人数数组。 int [] Arr = new int [] { 41 , 45 , 44 , 44 , 26 , 44 , 42 , 20 , 20 , 38 , 37 , 25 , 45 , 45 , 45 , 44 , 20 , 30 , 39 , 35 , 38 , 38 , 28 , 25 , 30 , 36 , 20 , 24 , 32 , 33 , 41 , 33 , 51 , 39 , 20 , 20 , 44 , 37 , 38 , 39 , 42 , 40 , 37 , 50 , 50 , 42 , 43 , 41 , 42 , 45 , 42 , 19 , 39 , 75 , 17 , 17 }; // 初始时间,两天的8:00-12:10与13:30-16:45共4个时间段Time slot,假设日期是2007-10-8号 TimeSlot[] TimeSlots = new TimeSlot[] { new TimeSlot( new DateTime( 2007 , 10 , 8 , 8 , 0 , 0 ), new DateTime( 2007 , 10 , 8 , 12 , 10 , 0 )), new TimeSlot( new DateTime( 2007 , 10 , 8 , 13 , 30 , 0 ), new DateTime( 2007 , 10 , 8 , 16 , 45 , 0 )), new TimeSlot( new DateTime( 2007 , 10 , 9 , 8 , 0 , 0 ), new DateTime( 2007 , 10 , 9 , 12 , 10 , 0 )), new TimeSlot( new DateTime( 2007 , 10 , 9 , 13 , 30 , 0 ), new DateTime( 2007 , 10 , 9 , 16 , 45 , 0 )) }; List < Class > Classes = new List < Class > (); for ( int i = 0 ; i < Arr.Length; i ++ ) { Classes.Add( new Class((i + 1 ).ToString(), Arr[i])); } // 按照学生数量排序 Classes.Sort( delegate (Class a, Class b) { return (Convert.ToInt32(b.MinPassTime.TotalMinutes - a.MinPassTime.TotalMinutes)); }); // 把班级加到计划里。 int tempTimeSlot = 0 ; int tempClass = 0 ; while (tempClass < Classes.Count) { int TimeSlotIndex = tempTimeSlot % TimeSlots.Length; TimeSlot timeSlot = TimeSlots[TimeSlotIndex]; List < Project > projects = timeSlot.Projects; Class currentClass = Classes[tempClass]; // Project p = new Project(currentClass); if (projects.Count == 0 ) { projects.Add(p); p.ArriveTime = timeSlot.BeginTime; p.LeaveTime = p.ArriveTime.Add(currentClass.MinPassTime); tempClass ++ ; } else { // 上一个计划的结束时间,是本计划的开始时间 Project lastProject = projects[projects.Count - 1 ]; // 判断时间是否够用;不够用就留到下一个时间段去处理; if (lastProject.LeaveTime.Add(currentClass.MinPassTime) < timeSlot.EndTime) { projects.Add(p); p.ArriveTime = lastProject.LeaveTime; p.LeaveTime = p.ArriveTime.Add(currentClass.MinPassTime); tempClass ++ ; } } tempTimeSlot ++ ; } // 关键时刻到了,打印结果,甘特图 long TimeSlotLeft = 180 ; int top = 0 ; for ( int i = 0 ; i < TimeSlots.Length; i ++ ) { TimeSlot timeSlot = TimeSlots[i]; List < Project > projects = timeSlot.Projects; long TimeSlotWidth = (timeSlot.EndTime.Ticks - timeSlot.BeginTime.Ticks) / TimeSpan.TicksPerMinute; HTML.Append( " <div style='z-index:100;border:1px solid black;width: " + TimeSlotWidth + " px;height:1680px;top:0px;left: " + TimeSlotLeft); HTML.Append( " px'>从 " + forMatDateTime(timeSlot.BeginTime, timeSlot.EndTime) + " </div>/n " ); for ( int j = 0 ; j < projects.Count; j ++ ) { top += 28 ; Project project = projects[j]; string ProjectBackGround = " white " ; if (((top / 28 ) % 2 ) == 0 ) { ProjectBackGround = " #CCCCCC " ; } Class currentClass = project.TheClass; long width = (project.LeaveTime.Ticks - project.ArriveTime.Ticks) / TimeSpan.TicksPerMinute; long left = TimeSlotLeft + (project.ArriveTime.Ticks - TimeSlots[i].BeginTime.Ticks) / TimeSpan.TicksPerMinute; // 时间 HTML.Append( " <div class='time' style='width: " + width + " px;top: " + top + " px;left: " + left + " px;'></div>/n " ); HTML.Append( " <div class='text' style='top: " + top + " px;left:0px;background-color: " + ProjectBackGround + " ;width:1070px;'> " + currentClass.ID); HTML.Append( " " + currentClass.Num + " " + forMatDateTime(project.ArriveTime, project.LeaveTime)); HTML.Append( " </div>/n " ); } top += 28 ; HTML.Append( " <div class='text' style='top: " + top + " px;left:0px;background-color:gray;width:1070px;'> " ); HTML.Append( " </div>/n " ); TimeSlotLeft += TimeSlotWidth; } } private string forMatDateTime(DateTime x, DateTime y) { string re = string .Empty; re += x.Day; re += " " ; re += x.Hour; re += " " ; re += x.Minute; re += " 分到 " ; re += y.Hour; re += " " ; re += y.Minute; re += " " ; return re; } } // 班级类 public class Class { public Class( string id, int num) { ID = id; Num = num; // 计算通过时间。 MinPassTime = TimeSpan.FromSeconds( 5 + 210 * Math.Ceiling(( double )num / 10 )); } // 编号,数量,最小通过时间(每轮10个人,4分钟,按秒计算是不值得的,因为毕竟是人!)。 public string ID; public int Num; public TimeSpan MinPassTime; } // 时间段类 public class TimeSlot { public TimeSlot(DateTime beginTime, DateTime endTime) { BeginTime = beginTime; EndTime = endTime; Projects = new List < Project > (); } // 开始时间,结束时间,计划列表。 public DateTime BeginTime; public DateTime EndTime; public List < Project > Projects; } public class Project { public Project(Class theClass) { TheClass = theClass; } // 到达时间,班级列表。 public Class TheClass; public DateTime ArriveTime; public DateTime LeaveTime; } } 前台Default.aspx文件内容:
HTML code
        
        
<% @ Page Language = " C# " AutoEventWireup = " true " CodeBehind = " Default.aspx.cs " Inherits = " project3._Default " %> < html > < head runat ="server" > < title > 计划甘特图 </ title > < meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" > < style > div { position : absolute ; font-size : 12px ; } div.time { background-color : Red ; z-index : 10 ; height : 28 ; } div.text { z-index : 1 ; height : 28 ; border : 1px solid black ; } </ style > </ head > < body > <% = HTML %> </ body > </ html >
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值