Algorithm 复杂职业管理中的日期计算算法
各位堆栈溢出器您好,Algorithm 复杂职业管理中的日期计算算法,algorithm,date,Algorithm,Date,各位堆栈溢出器您好, 我有一个情况,我需要一些帮助来选择使算法工作的最佳方式,目标是管理资源的占用(让我们考虑资源A)有多个任务,并且每个任务需要一个指定的时间来完成。在第一阶段,我不想涉及多个变量,所以让我们保持简单的方式,让我们考虑他只有一个工作日的时间表。 例如: 1-我们有1个资源,资源A 资源A从周一到周五的上午8点工作到下午4点,为了保持简单,他现在没有午餐,所以每天工作8小时 3-资源A有5项任务要完成,为了避免这一级别的复杂性,让我们假设每项任务需要整整10个小时才能完成 4-资
我有一个情况,我需要一些帮助来选择使算法工作的最佳方式,目标是管理资源的占用(让我们考虑资源A)有多个任务,并且每个任务需要一个指定的时间来完成。在第一阶段,我不想涉及多个变量,所以让我们保持简单的方式,让我们考虑他只有一个工作日的时间表。 例如:
1-我们有1个资源,资源A 资源A从周一到周五的上午8点工作到下午4点,为了保持简单,他现在没有午餐,所以每天工作8小时 3-资源A有5项任务要完成,为了避免这一级别的复杂性,让我们假设每项任务需要整整10个小时才能完成 4-资源A将于2018年5月16日下午2点开始执行该任务 问题: 现在,我只需要知道所有5项任务的正确完成日期,但考虑到之前的所有限制 在这种情况下,他有6个工作日,第7天额外有2个小时。 我想要的预期结果是:2018-05-24(下午4点) 实施: 我考虑了两个选项,希望能得到关于这个选项的反馈,或者其他我可能没有考虑的选项 算法1 1-创建一个“时段”列表,其中每个“时段”代表1小时,持续x天 2-将此插槽列表与资源的小时计划交叉,以删除资源不在此处的所有插槽。这将返回一个列表,其中包含他可以实际工作的插槽 3-用我为他准备的任务占据剩余的时间 4-最后,检查最后一个占用插槽的日期/小时<强>缺点:我认为这可能是一个过激的解决方案,考虑到我不想考虑他将来的职业,我只想知道任务什么时候完成。 算法2
1-将任务小时数(50小时)添加到开始日期,获得预期的完成日期。(预计完成日期=2018-05-18(下午4点)) 2-将开始日期和预期完成日期之间的时间与计划交叉,以获得他不工作的小时数。(基本上会得到不可用的小时数,每天16小时,将导致剩余小时数FORCALC=32小时) 3-使用不可用小时数计算新的预期完成日期,将这32小时添加到之前的2018-05-18(下午4点) 4-使用新的expectedFinishDate重复第2点和第3点,直到剩余小时ForCalc=0 缺点:这将导致一个递归方法或一个非常奇怪的while循环,同样,我认为这对于计算一个简单的日期来说可能是过分的你有什么建议?有没有其他我可能没有考虑过的方案可以让事情变得更简单?或者你认为有一种方法可以改进这两种算法中的任何一种,使其发挥作用吗?我同意算法1是过分的 我想我会确保我有合适的条件:每天8小时,工作日(周一、周二、周三、周四、周五)。然后将所需的小时数(5*10=50)除以每天的小时数,这样我就知道最少需要多少工作日(50/8=6)。稍微高级一点,先除以每周小时数(50/40=1周)。从开始日期开始计算工作日,以便在结束日期获得第一次拍摄。该部门可能还有剩余部分,因此使用此项确定任务是否可以在今天结束或运行到下一个工作日。改进版:
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String args[]) throws Exception
{
Date d=new Date();
System.out.println(d);
d.setMinutes(0);
d.setSeconds(0);
d.setHours(13);
Calendar c=Calendar.getInstance();
c.setTime(d);
c.set(Calendar.YEAR, 2018);
c.set(Calendar.MONTH, Calendar.MAY);
c.set(Calendar.DAY_OF_MONTH, 17);
//c.add(Calendar.HOUR, -24-5);
d=c.getTime();
//int workHours=11;
int hoursArray[] = {1,2,3,4,5, 10,11,12, 19,20, 40};
for(int workHours : hoursArray)
{
try
{
Date end=getEndOfTask(d, workHours);
System.out.println("a task starting at "+d+" and lasting "+workHours
+ " hours will end at " +end);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
public static Date getEndOfTask(Date startOfTask, int workingHours) throws Exception
{
int totalHours=0;//including non-working hours
//startOfTask +totalHours =endOfTask
int startHour=startOfTask.getHours();
if(startHour<8 || startHour>16)
throw new Exception("a task cannot start outside the working hours interval");
System.out.println("startHour="+startHour);
int startDayOfWeek=startOfTask.getDay();//start date's day of week; Wednesday=3
System.out.println("startDayOfWeek="+startDayOfWeek);
if(startDayOfWeek==6 || startDayOfWeek==0)
throw new Exception("a task cannot start on Saturdays on Sundays");
int remainingHoursUntilDayEnd=16-startHour;
System.out.println("remainingHoursUntilDayEnd="+remainingHoursUntilDayEnd);
/*some discussion here: if task starts at 12:30, we have 3h30min
* until the end of the program; however, getHours() will return 12, which
* substracted from 16 will give 4h. It will work fine if task starts at 12:00,
* or, generally, at the begining of the hour; let's assume a task will start at HH:00*/
int remainingDaysUntilWeekEnd=5-startDayOfWeek;
System.out.println("remainingDaysUntilWeekEnd="+remainingDaysUntilWeekEnd);
int completeWorkDays = (workingHours-remainingHoursUntilDayEnd)/8;
System.out.println("completeWorkDays="+completeWorkDays);
//excluding both the start day, and the end day, if they are not fully occupied by the task
int workingHoursLastDay=(workingHours-remainingHoursUntilDayEnd)%8;
System.out.println("workingHoursLastDay="+workingHoursLastDay);
/* workingHours=remainingHoursUntilDayEnd+(8*completeWorkDays)+workingHoursLastDay */
int numberOfWeekends=(int)Math.ceil( (completeWorkDays-remainingDaysUntilWeekEnd)/5.0 );
if((completeWorkDays-remainingDaysUntilWeekEnd)%5==0)
{
if(workingHoursLastDay>0)
{
numberOfWeekends++;
}
}
System.out.println("numberOfWeekends="+numberOfWeekends);
totalHours+=(int)Math.min(remainingHoursUntilDayEnd, workingHours);//covers the case
//when task lasts 1 or 2 hours, and we have maybe 4h until end of day; that's why i use Math.min
if(completeWorkDays>0 || workingHoursLastDay>0)
{
totalHours+=8;//the hours of the current day between 16:00 and 24:00
//it might be the case that completeWorkDays is 0, yet the task spans up to tommorrow
//so we still have to add these 8h
}
if(completeWorkDays>0)//redundant if, because 24*0=0
{
totalHours+=24*completeWorkDays;//for every 8 working h, we have a total of 24 h that have
//to be added to the date
}
if(workingHoursLastDay>0)
{
totalHours+=8;//the hours between 00.00 AM and 8 AM
totalHours+=workingHoursLastDay;
}
if(numberOfWeekends>0)
{
totalHours+=48*numberOfWeekends;//every weekend between start and end dates means two days
}
System.out.println("totalHours="+totalHours);
Calendar calendar=Calendar.getInstance();
calendar.setTime(startOfTask);
calendar.add(Calendar.HOUR, totalHours);
return calendar.getTime();
}
}
import java.util.Calendar;
导入java.util.Date;
公共班机{
公共静态void main(字符串args[])引发异常
{
日期d=新日期();
系统输出打印ln(d);
d、 设置分钟(0);
d、 设置秒(0);
d、 设定时间(13);
Calendar c=Calendar.getInstance();
c、 设定时间(d);
c、 set(日历年,2018年);
c、 设置(日历.月份,日历.五月);
c、 设置(日历日/月/日,17);
//c、 添加(日历小时,-24-5);
d=c.getTime();
//int工时=11小时;
国际小时数组[]={1,2,3,4,5,10,11,12,19,20,40};
对于(整数工作小时:小时)
{
尝试
{
日期结束=getEndOfTask(d,工作时间);
System.out.println(“从“+d+”开始并持续“+工作小时”的任务
+“小时将在“+结束时结束);
}
捕获(例外e)
{
System.out.println(e.getMessage());
}
}
}
公共静态日期getEndOfTask(Date StartToTask,int workingHours)引发异常
{
int totalHours=0;//包括非工作时间
//开始任务+总小时数=结束任务
int startHour=startofstask.getHours();
如果(StartOur16)
抛出新异常(“任务不能在工作时间间隔之外启动”);
System.out.println(“startHour=“+startHour”);
int startDayOfWeek=startOfTask.getDay();//开始日期的星期几;星期三=3
System.out.println(“startDayOfWeek=“+startDayOfWeek”);
如果(startDayOfWeek==6 | | startDayOfWeek==0)
抛出新异常(“任务不能在星期六和星期天开始”);
剩余整数小时数截止日期=16 startHour;
System.out.println(“remainingHoursUntilDayEnd=“+remainingHoursUntilDayEnd”);
/*这里有一些讨论:如果任务在12:30开始,我们有3小时30分钟
*但是,getHours()将返回12,这是
*从16中减去将得到4h。如果任务在12:00开始,则工作正常,
*或者,通常在一小时的开始;让我们假设一项任务将在HH:00开始*/
int remainingDaysUntilWeekEnd=5-开始工作周;
System.out.println(“remainingDaysUntilWeekEnd=“+remainingDaysUntilWeekEnd”);
完整工作日=(工作日)