w
CSDN 论坛 http://bbs.csdn.net/wap/topics/390186917
对原帖的问题做严谨化处理,并对“公平”做出假设。
问题:
有n个人轮流在宿舍内煮晚饭,宿舍内每天只煮一次晚饭。当晚轮到谁煮饭且该人当晚回宿舍就必须煮饭,其他晚上只要回宿舍则一定在宿舍吃晚饭且不做饭。突然有一天其中一人需要离开宿舍一段日子,离开的日期和离开的天数都是随机的,但这个人肯定要回来,且在这个人离开之前和之后,无任何人离开宿舍。设计算法,如何安排那个人回宿舍后在哪一天煮饭最公平。
假设:
0-“公平”指“一段时间内,每个人吃饭次数、做饭次数二者比值相等”;
1-设离开的这个人在n个人做饭周期中在其离开前一直为第p次做饭,且除离开的这个人,n-1个人的做饭次序一直彼此相对不变;
定义:
0-设n个人依次从第一个人开始做饭到最后一个人结束做饭为一个“n个人做饭周期”,其天数为n,在该周期内,大家实现了“公平”的假设,则n-1个人依次从第一个人开始做饭到最后一个人结束做饭为一个“n-1个人做饭周期”,其天数为n-1,在该周期内,大家实现了“公平”的假设;
1-该人在在n个人做饭周期中的第x+1天的早上离开宿舍,且离开当天算起的在第y+1天的晚上回宿舍;
CSDN 论坛 http://bbs.csdn.net/wap/topics/390186917
public class Partner { //吃饭的天数 private double eatDayCount; //煮饭的天数 private double cookDayCount; //离开时距离下一次自己煮饭循环的天数 private double holdDayCount; //吃饭天数和煮饭天数的比值。 private double scale; //定义一个煮饭的int型标识符 private final int cookFlag; public int getCookFlag() { return cookFlag; } public double getEatDayCount() { return eatDayCount; } public void setEatDayCount(double eatDayCount) { this.eatDayCount = eatDayCount; } public double getCookDayCount() { return cookDayCount; } public void setCookDayCount(double cookDayCount) { this.cookDayCount = cookDayCount; } public double getHoldDayCount() { return holdDayCount; } public void setHoldDayCount(double holdDayCount) { this.holdDayCount = holdDayCount; } public double getScale() { return scale; } public void setScale(double scale) { this.scale = scale; } //定义一个构造函数,用于赋值。 public Partner(double cookDayCount,double eatDayCount,double scale,int cookFlag,double holdDayCount) { this.cookDayCount=cookDayCount; this.eatDayCount=eatDayCount; this.scale=scale; this.holdDayCount=holdDayCount; this.cookFlag=cookFlag; } //重载构造函数,缺少holdDayCount的值 public Partner(double cookDayCount,double eatDayCount,double scale,int cookFlag) { this.cookDayCount=cookDayCount; this.eatDayCount=eatDayCount; this.scale=scale; this.cookFlag=cookFlag; //将距离的天数设置成一个负值。 this.holdDayCount=-1; } //累加吃饭的天数 public void eat(Partner partner) { partner.setEatDayCount(partner.getEatDayCount()+1); } //累加煮饭的天数 public void cook(Partner partner) { partner.setCookDayCount(partner.getCookDayCount()+1); } //计算吃饭的天数和租房的天数的比值 public void caculateScale(Partner partner) { partner.setScale(partner.getEatDayCount()/partner.getCookDayCount()); } //定义一个外出的方法 public void goOutToDoSometing(int i,Cook cook,Partner partner) { //设置一个值,用于计算自己离开的那一天距离自己下一次煮饭的天数。 //如果离开的那一天正好是轮到我煮饭的那一天。 if((i%cook.getPersonNums())==partner.getCookFlag()) { //那么我哪天回来就该我直接煮饭。 this.setHoldDayCount(0); }//如果我离开的那一天该煮饭的人标识符大于我煮饭的标志符,意思是我已经煮了饭,而且我已经吃了几顿,不过还有几顿没有吃完。 else if((i%cook.getPersonNums())>partner.getCookFlag()) { //计算我还没有吃完的饭的顿数。 this.setHoldDayCount(cook.getPersonNums()+partner.getCookFlag()-i%cook.getPersonNums()); }//如果我离开的那一天该煮饭的人的标识符小于我租房的标志符。 else if(i%cook.getPersonNums()<partner.getCookFlag()) { //计算我还没有吃完的饭的顿数。 this.setHoldDayCount(partner.getCookFlag()-i%cook.getPersonNums()); } } public String toString() { return "Partner [cookDayCount=" + cookDayCount + ", cookFlag=" + cookFlag + ", eatDayCount=" + eatDayCount + ", holdDayCount=" + holdDayCount + ", scale=" + scale + "]"; } } /** * 外出方法类 * @author huxing * */ public class Egress { private int egressDate=0; private int backDate=0; public int getEgressDate() { return egressDate; } public void setEgressDate(int egressDate) { this.egressDate = egressDate; } public int getBackDate() { return backDate; } public void setBackDate(int backDate) { this.backDate = backDate; } //定义一个构造函数,用于生成Egress对象,其中分别给两个成员变量赋值。 //第一个参数i表示外出的那一天。第二个参数主要是想获取轮的日期。 public Egress(Cook cook) { this.egressDate=(int)(Math.random()*(cook.getDays()-4)+1); this.backDate=(int)((Math.random()*(cook.getDays()-4-egressDate))+egressDate); } //定义一个外出的方法。 public void beOut(Partner partner,int i) { } } /** * 煮饭类 * @author huxing * */ public class Cook { //需要一起做饭的天数 private int days; //一共有多少人参与了做饭 private int personNums; public int getPersonNums() { return personNums; } public void setPersonNums(int personNums) { this.personNums = personNums; } public int getDays() { return days; } public void setDays(int days) { this.days = days; } public Cook(int days,int personNums) { this.days=days; this.personNums=personNums; } public static void main(String args[]) { Cook cook=new Cook(30,4); //创建四个Partner对象 Partner huxing=new Partner(0,0,0,0,0); Partner xulei=new Partner(0,0,0,1,0); Partner kouhao=new Partner(0,0,0,2,0); Partner zhangzhonghua=new Partner(0,0,0,3,0); //产生一个随机数表示出去的日期。 //int beginDate=(int) (Math.random()*30+1); //产生一个随机数表示回来的日期 //int backDate=(int) (Math.random()*(30-beginDate)+beginDate); //构造一个做饭的实例, Egress egress=new Egress(cook); //选择我要离开一些天。 egress.beOut(huxing, egress.getEgressDate()); //开始做饭 for(int i=0;i<cook.getDays();i++) { //如果这一天我还没有出去,按照四个人的顺序做饭。或者在我出去后回来的日子里。按照我设计的思路开始煮饭(后面设计了要多吃的顿数)。 if(i<egress.getEgressDate()||i>=egress.getBackDate()+4) { switch(i%cook.getPersonNums()) { case 0:huxing.cook(huxing);break; case 1:xulei.cook(xulei);break; case 2:kouhao.cook(kouhao);break; case 3:zhangzhonghua.cook(zhangzhonghua);break; } huxing.eat(huxing); xulei.eat(xulei); kouhao.eat(kouhao); zhangzhonghua.eat(zhangzhonghua); }//在我出去的日子里面,按照三个人的顺序做饭。 else if(i>=egress.getEgressDate()&&i<egress.getBackDate()+huxing.getHoldDayCount()) { switch(i%(cook.getPersonNums()-1)) { case 0:xulei.cook(xulei);break; case 1:kouhao.cook(kouhao);break; case 2:zhangzhonghua.cook(zhangzhonghua);break; } xulei.eat(xulei); kouhao.eat(kouhao); zhangzhonghua.eat(zhangzhonghua); //我已经回来了,但先不忙煮饭,而是吃玩了我该吃的顿数才开始煮饭。 if(i>=egress.getBackDate()) { huxing.eat(huxing); } } } System.out.println(huxing.toString()); System.out.println(kouhao.toString()); System.out.println(xulei.toString()); System.out.println(zhangzhonghua.toString()); } }