电梯问题

/**
 * 电梯问题,要求路程长度最短。
 * 类似加油站选址。
 * 
 * f(i, k) = min{f(j, k-1) + g(j+1, i)}, k-1<=j<i
 * 
 * 先求出g,中位数原理。
 * 
 * 如果每层人数不定,则是带权中位数原理。
 * 
 *
 */
public class Elevator {

	
	public static int find(int[] a, int stops){
		assert(true);
		int n = a.length;
		int[][] g = new int[n][n];
		//任意两点之间,中位数求最短值。
		for(int i=0; i<n; i++){
			for(int j=i; j<n; j++){
				int mid = (i+j)/2;
				for(int k=i; k<=j; k++){
					g[i][j] += (a[mid]-a[k])>0 ? (a[mid]-a[k]) : (a[k]-a[mid]);
				}
			}
		}
		Tools.printArray(g);
		//初始化j=1那一列,表示前i个数选一个,最短值。
		int[][] f = new int[n+1][stops+1];
		for(int i=1; i<=n; i++){
			f[i][1] = g[0][i-1];
		}
		//第i行第j列,取决于前i-1行的第j-1列
		for(int i=1; i<=n; i++){
			for(int j=2; (j<=stops)&&(j<=i); j++){
				int min = -1;
				for(int k=i-1; k>=j-1; k--){
					int x = f[k][j-1] + g[k][i-1];
					if(min==-1 || x<min){
						min = x;
					}
				}
				f[i][j] = min;
			}
		}
		System.out.println();
		Tools.printArray(f);
		return f[n][stops];
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] a = {1,2,3,4,5};
		int x = Elevator.find(a, 3);
		System.out.println(x);
	}

}

1. 楼层由上至下依次编号为9,8,7,6,5,4,3,2,1,0。每层都有向上和向下两个按钮,对应20个变量callup[0...9]和calldown[0...9]。电梯内10个目标层按钮对应变量out[0...9]。有人按下某个按钮时,相应的变量就增1,一旦要求满足后,该变量就减1。当有多人的需求相同时,相应的处理时间就增长,用于模拟真实的情况。 2. 电梯处于三种状态之一:UP(上行),DOWN(下行)和Idle(等候)。如果电梯处于Idle状态且不在1层超过20个时间单位时,则驶回1层。当电梯处于Idle状态时,一旦收到前往另一层的命令,就转入UP或DOWN状态,执行相应的操作。 3. 其它重要的变量有: floor----当前电梯外乘客所在楼层; calling----当前电梯外按下按钮的乘客所在的楼层; up_or_down----电梯外某层按钮的状态(向上箭头或向下箭头); waittime----电梯空闲时的等待时间; total----电梯内的总人数(上限为15人); 电梯的数据结构: state ---- 电梯的状态(UP,DOWN,IDLE) current ----- 电梯目前所处楼层 imovingto ---- 电梯的目标楼层 队列成员的数据结构: floor―――所在楼层 up_down―――目标方向(向上或向下) struct queue *next―――指向下一个成员 4. 【进入排队】先在等候队列中查找,若有信息相同(所在楼层相同,目标方向一致)的成员,则对队列无任何操作。若没有,则在队列末尾插入该人。 5. 【进入电梯电梯根据人数停留一定时间单位,每进入一个人,从队列中删除该人,callup[ele.current]或者calldown[ele.current]减一,total加一。 6. 【走出电梯电梯根据人数停留一定时间单位,每出去一个人out[ele.current]减一. 7. 【电梯的活动】 E1.[在一楼停候]若有人按下一个按钮,则调用相关函数(比如入队,置楼层标志位为1等)处理当前事件. E2.[改变状态]如果电梯处于Up(或Down)状态,但该方向的楼层却无人等待,则要看反方向楼层是否有人等待,而决定置State为Down(或Up)还是Idle。 E3.[让人出入]如果电梯不空且out[ele.current]!=0时,则电梯等候在该楼层出电梯的人离开。接着检验在该楼层是否有等候前往同一方向去的乘客,若有则等候他们进入电梯。总原则是先下后上。 E4.[在某楼层(非1楼)停候]若电梯到达目标楼层后,队列为空,则电梯在该楼层停候一定时间,在停候期间若有新的呼叫,则立即转入处理程序处理,否则返回一楼停候。 8. 电梯在上升或下降过程中需要不停地对当前方向上的最终楼层作调整。比如当前向上,最终楼层为6楼,而有乘客在8楼按了按钮,则最终楼层调整为8楼。相反方向同理。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值