论坛首页 Java企业应用论坛

电梯问题

浏览 2354 次
锁定老帖子 主题:电梯问题
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-12-09   最后修改:2008-12-09

     昨天在网上看到有朋友问如何解决电梯问题,感觉比较有意思,便动手做了一下,有什么不合理的地方还望各位及时指出。
     主要思路是:
 1.创建对象:Lift(电梯)、Person(乘客)、Floor(楼层)以及RandomNum(产生随机数)。
 2.主要介绍Lift类中的start()方法(即电梯运行):其中包含了
            randomFloors();// 随机初始化等电梯的人  
            next(FLOOR_CURRENT);// 爬楼,包括上楼或下楼  
            printNextStat();// 爬楼状态打印  
            popSomePerson();// 出电梯  
            putSomePerson();// 上电梯  
            printLiftContent();// 打印电梯状态
 3.其中的next()爬楼方法是重点:
  next()方法把上楼和下楼分成两个方法,两个方法类似,现以上楼的liftUp方法为例说明其流程的伪代码:

 

上楼(当前楼层号){
 if (电梯前一动作为上楼时) {
            if (现在已到最高层) { //则开始下行
                return 下楼(最高层);   
            } else {// 未到最高层   
                if(电梯内有到更高层的){
                            取出
                }
                if(等待上行楼层有到更高层的,且等待楼层也比当前楼层高){
                    取出
           }
                if (上楼方向没有用户) {
                    return 下楼(最高层);   
                } 
                return 取出的层;   
            }   
        } else {// 电梯前一动作为下楼时。
            if (到最底层) {//则开始上行
                return 上楼(最底层);   
            }   
            if (等待下楼的层没有比当前更低的楼层) {
                return 上楼(当前层);   
            }   
            if (电梯内没有比当前更低的楼层) {
                return 上楼(当前层); 
            } else {   
               return 下楼(当前层);  
            }   
        }   
    }

 

 

以下是相关的源代码,仅供参考。

 

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * 电梯问题
 * 
 * @version 1.0
 * @author 点子二木
 * @date 2008-12-8
 * @right Copyright (C), 点子二木
 */
public class Lift {
	static final int INT_FLOOR_HIGHEST = 20;// 最高层
	static final int INT_FLOOR_LOWEST = 1;// 最低层
	static final int INT_PERSON_WAIT_MAX = 2;// 等电梯的人的最大值
	static final int LIST_CAPABILITY_SIZE_MAX = 1000;// 电梯最大负重
	static int LIST_CAPABILITY_CURRENT;// 当前电梯的已用大小总和

	private static final int INT_RANDOM_FLOOR_COUNT = 2;// 随机的楼层数
	private static int FLOOR_CURRENT = 1;// 电梯当前所在层
	private static final int INT_STOP_MAX = 5;// 电梯可停的次数最大值
	private static int INT_STOP_NUM = 0;// 电梯已停的次数
	private static boolean BLN_liftDirection;// 电梯运行的方向,false-向上,true-向下
	private static boolean BLN_OPEN;// 本层仍有乘客上下车,false-没有;true-有
	private static ArrayList<Person> liftPersonList = new ArrayList<Person>();// 梯中人列表
	private static ArrayList<Person> waitPersonList = new ArrayList<Person>();// 等待人列表

	public static void main(String[] args) {
		initLift();
		start();
	}

	/**
	 * 初始化电梯
	 */
	private static void initLift() {
		randomFloors();// 随机几层
		printLiftContent();// 打印电梯状态
	}

	/**
	 * 电梯启动,到下一停,并上下人
	 */
	private static void start() {

		while (true) {
			System.out.println("电梯停靠第" + (Lift.INT_STOP_NUM + 1) + "次");
			if (liftPersonList.isEmpty() && waitPersonList.isEmpty()) {
				randomFloors();// 随机几层
			}
			next(FLOOR_CURRENT);// 爬楼,包括上楼或下楼
			printNextStat();// 爬楼状态打印
			popSomePerson();// 出电梯
			putSomePerson();// 上电梯
			printLiftContent();// 打印电梯状态

		}
	}

	/**
	 * 随机几层
	 */
	@SuppressWarnings( { "static-access", "unchecked" })
	private static void randomFloors() {
		waitPersonList.clear();

		for (int index = 0; index < INT_RANDOM_FLOOR_COUNT; index++) {
			Floor floor = new Floor();
			ArrayList<Person> tempList = floor.waitPersonListOfFloor;
			for (Person per : tempList) {
				waitPersonList.add(per);
			}
		}

		// ///////////////// 固定数据测试 start///////////////////////
		// for (int num = 0; num < 2; num++) {
		// Person per = new Person(55 + num, 1, 16 + num);
		// per.setFrom(16);
		// waitPersonList.add(per);
		// }
		// ArrayList<Person> tempList = (ArrayList<Person>)
		// waitPersonList.clone();
		// for (Person per : tempList) {
		// waitPersonList.add(per);
		// }
		// ///////////////// 固定数据测试 end///////////////////////

		sortWaitPersonList();

	}

	/**
	 * 遍历打印电梯内列表
	 */
	private static void printLiftContent() {
		sortWaitPersonList();
		sortLiftPersonList();
		System.out.println("=========当前楼层:" + FLOOR_CURRENT + "=========");
		for (int num = 0; num < liftPersonList.size(); num++) {
			System.out.println("人物" + (num + 1) + "重量:"
					+ liftPersonList.get(num).getAnWeight() + "kg。要去楼层:"
					+ liftPersonList.get(num).getTo());
		}
		System.out.println("当前总重量:" + LIST_CAPABILITY_CURRENT + "kg,最大总重量:"
				+ LIST_CAPABILITY_SIZE_MAX + "kg");

		System.out.println("=========");
		for (int num = 0; num < waitPersonList.size(); num++) {
			System.out.println("随机人物" + (num + 1) + "重量:"
					+ waitPersonList.get(num).getAnWeight() + "kg。上客楼层:"
					+ waitPersonList.get(num).getFrom() + "。要去楼层:"
					+ waitPersonList.get(num).getTo());
		}
	}

	/**
	 * 电梯爬楼到下次停车(*****此方法是关键*****)
	 * 
	 * @param current
	 * @return 下次停车的楼层
	 */
	private static int next(int current) {

		int floorNO = 0;
		if (!BLN_liftDirection) {
			floorNO = liftUp(current);
		} else {
			floorNO = liftDown(current);
		}

		if (floorNO < INT_FLOOR_LOWEST) {
			System.out.println("@@@@@@@@@@@@@@@@@@@@暂无乘客,电梯停止@@@@@@@@@@"
					+ "目前停在" + FLOOR_CURRENT + "层@@@@@@@@@@@@@@@@@@@@");
			System.exit(0);
		}

		if (floorNO == FLOOR_CURRENT) {
			System.out.println("&&&&&&&&&&开门!!本层仍有乘客上下车!" + "&&&&&&&&&&");
			BLN_OPEN = true;
			return FLOOR_CURRENT;
		}
		FLOOR_CURRENT = floorNO;
		BLN_OPEN = false;
		return FLOOR_CURRENT;
	}

	/**
	 * 电梯上楼
	 * 
	 * @param current
	 * @return 上楼停车的楼层
	 */
	private static int liftUp(int current) {
		if (liftPersonList.size() < 1 && waitPersonList.size() < 1) {
			return INT_FLOOR_LOWEST - 1;
		}

		if (!BLN_liftDirection) {// 上楼方向
			if (current == INT_FLOOR_HIGHEST) {// 已到顶
				BLN_liftDirection = true;
				return liftDown(current);
			} else {// 未到顶
				// 电梯内有到更高层的
				int upMin = INT_FLOOR_HIGHEST + 1;// 上楼最小值
				for (Person inner : liftPersonList) {// 梯中人取到达楼层
					if (inner.getTo() < upMin && inner.getTo() >= current) {
						upMin = inner.getTo();
					}
				}
				// 等待上行楼层有到更高层的,且等待楼层也比当前楼层高
				for (Person wait : waitPersonList) {// 等待人取等待楼层
					if (wait.getFrom() >= current && wait.getFrom() < upMin
							&& wait.getTo() > wait.getFrom()) {//
						upMin = wait.getFrom();
					}
				}
				if (upMin > INT_FLOOR_HIGHEST) {// 说明上楼方向没有用户
					BLN_liftDirection = true;
					return liftDown(INT_FLOOR_HIGHEST);
				}

				return upMin;
			}
		} else {// 下楼方向
			// 到最低层则开始上行
			if (INT_FLOOR_LOWEST == current) {
				BLN_liftDirection = false;
				return liftUp(current);
			}
			// 等待下行楼层没有比当前更低的楼层
			int waitFrom = current;
			for (Person wait : waitPersonList) {// 
				if (wait.getFrom() > wait.getTo() && wait.getFrom() < current) {
					waitFrom = wait.getFrom();
				}
			}
			if (waitFrom >= current) {// 说明没有更低的等待
				BLN_liftDirection = false;
				return liftUp(current);
			}

			// 电梯内没有比当前更低的楼层
			int innerTo = current;
			for (Person inner : liftPersonList) {// 
				if (inner.getTo() < current) {
					innerTo = inner.getTo();
				}
			}
			if (innerTo >= current) {// 说明没有更低的坐梯人
				BLN_liftDirection = false;
				return liftUp(current);
			} else {
				BLN_liftDirection = true;
				return liftDown(current);
			}
		}

	}

	/**
	 * 电梯下楼
	 * 
	 * @param current
	 * @return 下楼停车的楼层
	 */
	private static int liftDown(int current) {
		if (liftPersonList.size() < 1 && waitPersonList.size() < 1) {
			return INT_FLOOR_LOWEST - 1;
		}

		if (!BLN_liftDirection) {// 上楼方向
			// 到最高层则开始下行
			if (INT_FLOOR_HIGHEST == current) {
				BLN_liftDirection = true;
				return liftDown(current);
			}
			// 等待上行楼层没有比当前更高的楼层
			int waitFrom = current;
			for (Person wait : waitPersonList) {// 
				if (wait.getFrom() < wait.getTo() && wait.getFrom() > current) {
					waitFrom = wait.getFrom();
				}
			}
			if (waitFrom <= current) {// 说明没有更高的等待
				BLN_liftDirection = true;
				return liftDown(current);
			}

			// 电梯内没有比当前更高的楼层
			int innerTo = current;
			for (Person inner : liftPersonList) {// 
				if (inner.getTo() > current) {
					innerTo = inner.getTo();
				}
			}
			if (innerTo <= current) {// 说明没有更高的坐梯人
				BLN_liftDirection = true;
				return liftDown(current);
			} else {
				BLN_liftDirection = false;
				return liftUp(current);
			}

		} else {// 下楼方向
			if (current == INT_FLOOR_LOWEST) {// 已到底
				BLN_liftDirection = false;
				return liftUp(current);
			} else {// 未到底

				// 电梯内有到更低层的
				int downMax = INT_FLOOR_LOWEST - 1;// 下楼最大的楼层号
				for (Person inner : liftPersonList) {// 梯中人取到达楼层
					if (inner.getTo() > downMax && inner.getTo() <= current) {
						downMax = inner.getTo();
					}
				}
				// 等待下行楼层有到更低层的,且等待楼层也比当前楼层低
				for (Person wait : waitPersonList) {// 等待人取等待楼层
					if (wait.getFrom() <= current && wait.getFrom() > downMax
							&& wait.getTo() < wait.getFrom()) {//
						downMax = wait.getFrom();
					}
				}
				if (downMax < INT_FLOOR_LOWEST) {// 说明下楼方向没有用户
					BLN_liftDirection = false;
					return liftUp(INT_FLOOR_LOWEST);
				}
				return downMax;
			}
		}

	}

	/**
	 * 爬楼状态打印
	 */
	private static void printNextStat() {
		if (BLN_OPEN) {// 重新开门不用打印
			return;
		}
		Lift.INT_STOP_NUM++;// 停的次数加一

		String direct = "";
		if (!BLN_liftDirection) {
			direct = "上升";
		} else {
			direct = "下降";
		}
		System.out.println(">>>>>" + direct + "中>>>>>>>>>>电梯即将到达("
				+ FLOOR_CURRENT + ")层:>>>>>>>>>>>>>>>>>>>>");
		if (INT_STOP_NUM >= INT_STOP_MAX) {// 不加可能进入死循环
			System.exit(0);
		}
	}

	/**
	 * 本层人上电梯
	 * 
	 * @return true-上梯成功;false-上梯失败
	 */
	@SuppressWarnings("unchecked")
	private static boolean putSomePerson() {
		boolean result = false;
		ArrayList<Person> waitclone = (ArrayList<Person>) waitPersonList
				.clone();
		for (Person per : waitclone) {
			if (per.getFrom() == FLOOR_CURRENT) {
				putOnePerson(per);
				popWaitOnePersonOfThisFloor(per);
				result = true;
			}
		}
		return result;
	}

	/**
	 * 一个人上电梯
	 * 
	 * @param person
	 * @return true-上梯成功;false-上梯失败
	 */
	private static boolean putOnePerson(Person person) {
		boolean result = false;
		LIST_CAPABILITY_CURRENT += person.getAnWeight();
		if (LIST_CAPABILITY_CURRENT <= LIST_CAPABILITY_SIZE_MAX) {// 该人进入后依旧满足
			liftPersonList.add(person);
			result = true;
		} else {
			LIST_CAPABILITY_CURRENT -= person.getAnWeight();
		}
		return result;
	}

	/**
	 * 本层到站人出电梯
	 * 
	 */
	@SuppressWarnings("unchecked")
	private static boolean popSomePerson() {
		boolean result = false;
		ArrayList<Person> liftclone = (ArrayList<Person>) liftPersonList
				.clone();

		for (Person person : liftclone) {
			if (FLOOR_CURRENT == person.getTo()) {// 如果到达楼层
				LIST_CAPABILITY_CURRENT -= person.getAnWeight();
				liftPersonList.remove(person);
				result = true;
			} else {

			}
		}
		return result;
	}
	

	/**
	 * 到站,清除本层等待的一个人
	 * 
	 * @param person
	 * @return true-成功删除;false-未删除
	 */
	private static boolean popWaitOnePersonOfThisFloor(Person person) {
		boolean result = false;

		if (FLOOR_CURRENT == person.getFrom()) {//
			waitPersonList.remove(person);
			result = true;
		} else {
		}
		return result;
	}

	/**
	 * 电梯中的人排序
	 */
	@SuppressWarnings("unchecked")
	private static void sortLiftPersonList() {
		Collections.sort(liftPersonList, new Person());// 按到达层数排序
	}

	/**
	 * 等待的人排序
	 */
	@SuppressWarnings("unchecked")
	private static void sortWaitPersonList() {
		Collections.sort(waitPersonList, new Person());// 按到达层数排序
	}
}


/**
 * 乘梯人
 */
@SuppressWarnings("unchecked")
class Person implements Comparator {
	private final int INT_WEIGHT_MAX = 200;// 一个人体重最大值
	private int anWeight;// 一个人的体重
	private int from;// 上梯楼层
	private int to;// 下梯楼层

	public int compare(Object o1, Object o2) {
		Person per1 = (Person) o1;
		Person per2 = (Person) o2;
		return per1.to - per2.to;

	}

	Person() {
		int wgh = RandomNum.randomInt(1, INT_WEIGHT_MAX);
		int fromfloor;
		int tofloor;
		do {
			tofloor = RandomNum.randomInt(Lift.INT_FLOOR_LOWEST,
					Lift.INT_FLOOR_HIGHEST);
			fromfloor = RandomNum.randomInt(Lift.INT_FLOOR_LOWEST,
					Lift.INT_FLOOR_HIGHEST);
		} while (tofloor == fromfloor);

		anWeight = wgh;
		from = fromfloor;
		to = tofloor;
	}

	Person(int anWeight, int from, int to) {
		this.anWeight = anWeight;// 一个人的体重
		this.from = from;// 上梯楼层
		this.to = to;// 下梯楼层

	}

	public void setTo(int to) {
		if (to > Lift.INT_FLOOR_LOWEST && to <= Lift.INT_FLOOR_HIGHEST
				&& to != this.from) {
			this.to = to;
		} else {
			this.to = 1;
		}
	}

	public void setFrom(int from) {
		if (from > Lift.INT_FLOOR_LOWEST && from <= Lift.INT_FLOOR_HIGHEST
				&& from != this.to) {
			this.from = from;
		} else {
			this.from = 1;
		}
	}

	public void setAnWeight(int anWeight) {
		if ((anWeight + Lift.LIST_CAPABILITY_CURRENT) < Lift.LIST_CAPABILITY_SIZE_MAX) {
			this.anWeight = anWeight;
		} else {
			this.anWeight = 0;
		}
	}

	// ///////=======getter=======//////////////
	public int getFrom() {
		return from;
	}

	public int getTo() {
		return to;
	}

	public int getAnWeight() {
		return anWeight;
	}

}

/**
 * 楼层
 */
class Floor {
	private int floorNO;// 楼层号
	private int waitNum;// 等待的人数
	 
	boolean upFlag;// 是否有人上楼的按钮
	boolean downFlag;// 是否有人下楼的按钮
	ArrayList<Person> waitPersonListOfFloor = new ArrayList<Person>();// 本层等待人列表

	Floor(int currentfloor) {
		int waitNum = RandomNum.randomInt(1, Lift.INT_PERSON_WAIT_MAX);
		this.floorNO = currentfloor;
		this.waitNum = waitNum;

		for (int num = 0; num < waitNum; num++) {
			Person per = new Person();
			per.setFrom(currentfloor);
			waitPersonListOfFloor.add(per);
			if (per.getTo() > floorNO) {
				upFlag = true;
			}
			if (per.getTo() < floorNO) {
				downFlag = true;
			}
		}

	}

	Floor() {

		this.floorNO = RandomNum.randomInt(Lift.INT_FLOOR_LOWEST,
				Lift.INT_FLOOR_HIGHEST);
		this.waitNum = RandomNum.randomInt(1, Lift.INT_PERSON_WAIT_MAX);

		for (int num = 0; num < waitNum; num++) {
			Person per = new Person();
			per.setFrom(floorNO);
			waitPersonListOfFloor.add(per);
			if (per.getTo() > floorNO) {
				upFlag = true;
			}
			if (per.getTo() < floorNO) {
				downFlag = true;
			}
		}

	}

}

/**
 * 产生随机数的方法 :Math.random()*(end-start+1)+start
 */
class RandomNum {

	/**
	 * 产生int型随机数
	 * 
	 * @param start起始范围
	 * @param end截止范围
	 * @return
	 */
	public static int randomInt(int start, int end) {
		int result = (int) (Math.random() * (end - start + 1) + start);
		return result;

	}

	/**
	 * 产生float型随机数
	 * 
	 * @param start起始范围
	 * @param end截止范围
	 * @return
	 */
	public static float randomFloat(float start, float end) {
		float result = (float) (Math.random() * (end - start + 1) + start);
		return result;

	}
}

 

 

 

 

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics