为一组参与者寻找最佳时间段的算法

6

你建议我使用什么算法来解决以下问题?

我想解决一个问题,即根据参与者的日历可用性找到最佳的时间安排。我正在使用Java,并希望为这些参与者安排会议。我拥有一天中半小时段落的参与者可用性数据。我要找到一个时间,当所有这些参与者都可以。

可用性问题如下所示

|Participant   | 09:00 | 09:30 | 10:00     | 10:30 | 11:00 | 11:30 |
|Person 1      | Free  | Busy  | **Free**  | Free  | Busy  | Free  | 
|Person 2      | Free  | Busy  | **Free**  | Free  | Busy  | Busy  | 
|Person 3      | Free  | Busy  | **Free**  | Free  | Busy  | Busy  | 
|Person 4      | Free  | Busy  | **Free**  | Free  | Busy  | Busy  | 
|Person 5      | Free  | Busy  | **Free**  | Free  | Busy  | Free  |

我希望能够选择适合每个人的时间段。理想情况下,我希望算法至少会选择一个选项。然后,我可以对所选择的时间应用约束条件以找到最优解。

6
计算每个时间段内的可用时间总数,选择可用时间最长的时间段。 - Subir Kumar Sao
1
@SubirKumarSao 如果参与者需要参加多次会议,那么这将不是最优解。 - Geoffrey De Smet
你会推荐使用哪种数据结构来存储许多参与者的时间和可用性,以实现最高效的方式?谢谢。 - cdugga
2个回答

12
可用性日程可以转换为位数组,其中Free为1,Busy为0。下面是一个示例,供参考:
|Participant | 09:00 | 09:30 | 10:00 | 10:30 | 11:00 | 11:30 |
|Person 1    | Free  | Busy  | Free  | Free  | Busy  | Free  |

Person 1的位数组如下:1 | 0 | 1 | 1 | 0 | 1

由于您以30分钟为增量设置时间段,因此24小时时间范围内的位数组不会超过48个。在Java中,long数据类型足以容纳此位数组的值。将每个参与者的可用时间段转换为位数组。然后,对每个参与者的可用日程的位数组表示应用按位运算符AND。得到的位数组将是所有参与者的共同空闲时间。


2

建立一个这样的数据结构。

地图

键的范围实际上可以从第1天到第N天。我假设接下来的30天,所以键将从Day1到Day30。

假设需要10个人预订会议。每个人都应该在该时间段内免费。

我假设一天有30分钟的时间,在8小时的工作日中,将有16个时段。

因此,对于Day1->,您将把10个人的可用性保存为10 x 16二维int数组/矩阵。每个单元格将保持0或1。 0表示该人不可用,1表示该人可用。

关键是迭代地对每个人/时隙进行AND匹配。 (Person1在时隙0的可用性)和(Person2在时隙0的可用性)。 如果为0,立即退出循环,因为我们无法找到此时隙的匹配项。 如果在特定日期/时隙组合上重复AND的结果为1,则达到该时隙的完全匹配。以下是我的代码:

package com.ramesh.tests;
    import java.util.Map;
    import java.util.Random;
    import java.util.TreeMap;

    public class CalendarFinder {

        public static void main(String[] args) {
            int n=10 ;// no. of persons
            int m=30 ;//no.of days
            Map<String,int[][]> personCalendar = preparePersonCalendars(n,m);
            printPersonCalendar(personCalendar);
            Map<String,int[][]> testData = prepareTestData(n,m);
            printPersonCalendar(testData);
            meetingSlotFinder(testData);
            meetingSlotFinder(personCalendar);
        }

        private static Map<String,int[][]> preparePersonCalendars(int n, int m) {
            Random rnd = new Random();
            Map<String,int[][]> personCalendar = new TreeMap<String,int[][]>();
            for(int i=0; i<m; i++) { //iterate over days
                int[][] daysSlots = new int[n][16];
                for(int j=0;j<n;j++) { //iterate over persons
                    for(int slot=0;slot<16;slot++) { 
                        daysSlots[j][slot] = rnd.nextInt(2);
                    }
                }
                personCalendar.put(i<9 ? "Day_0"+(i+1) : "Day_"+(i+1), daysSlots);
            }
            return personCalendar;
        }

        private static Map<String,int[][]> prepareTestData(int n, int m) {
            Map<String,int[][]> testData = new TreeMap<String,int[][]>();
            for(int i=0; i<m; i++) { //iterate over days
                int[][] daysSlots = new int[n][16];
                for(int j=0;j<n;j++) { //iterate over persons
                    for(int slot=0;slot<16;slot++) { 
                        daysSlots[j][slot] = i%5==0 && slot%6==0 ? 1 : 0;
                    }
                }
                testData.put(i<9 ? "Day_0"+(i+1) : "Day_"+(i+1), daysSlots);
            }
            return testData;
        }

        private static void printPersonCalendar(Map<String,int[][]> personCalendar) {
            for(Map.Entry<String, int[][]> calendar: personCalendar.entrySet()) {
                System.out.println("Printing Calendar availability for : " + calendar.getKey());
                int[][] pCalArray = calendar.getValue();
                for(int i=0; i<pCalArray.length; i++) {
                    System.out.println("Person : " + (i+1));
                    for(int j=0;j<pCalArray[0].length;j++) {
                        System.out.print(" " + pCalArray[i][j]);
                    }
                    System.out.print("\r\n");
                }
            }
        }

        private static void meetingSlotFinder(Map<String,int[][]> personCalendar) {
            int ctr=0;
            for(Map.Entry<String, int[][]> calendar: personCalendar.entrySet()) {
                int[][] pCalArray = calendar.getValue();
                for(int j=0;j<pCalArray[0].length;j++) { // iterate over slots
                    int result = 1;
                    for(int i=0; i<pCalArray.length-1; i++) { //iterate over persons
                        ctr++;
                        result = result & pCalArray[i][j]& pCalArray[i+1][j];
                        if(result==0) break;
                    }
                    if(result == 1)
                        System.out.println("**** Meeting match at Day : " + 
                                calendar.getKey() + " and at slot: " + j);
                    else
                        System.out.println("Couldn't find any meeting match at Day : " + 
                                calendar.getKey() + " and at slot: " + j);
                }
            }
            System.out.println("#@$&* Total Iterations performed : " + ctr); 
        }

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接