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”);
完整工作日=(工作日)