- 浏览: 530190 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
zfx1982:
楼主能把doubango和webrtc2sip的源码发我一份么 ...
CentOS下编译webrtc2sip实战 -
zfx1982:
请问在编译doubango的时候configure总是说少sr ...
CentOS下编译webrtc2sip实战 -
cgs1999:
845896876 写道老师你好,我发现// 自定义属性 ...
使用Java操作LDAP案例 -
845896876:
老师你好,我发现// 自定义属性 a ...
使用Java操作LDAP案例 -
myitela:
NAT即地址转换,也可以是内网地址与外网地址的转换。如nat1 ...
NAT与NAT穿越学习总结
1、案例描述
最近做会议管理系统,预约会议需要一个算法来判断在指定的时间段内是否有可用的资源,这个算法是这样的:一个企业可以同时并发的会议数是有限的,预约会议时需要判断在预约的会议时间段内是否有可用的资源,资源没有达到限制数量时可预约会议,一旦资源达到限制的数量则预约会议失败。
举个例子:某企业在同一时间段内可同时并发的最大会议数为4个,企业在2012-12-19已经预订了以下时间段的会议:
那么,是否可以预订2012-12-19 10:00:00至2012-12-19 10:40:00的会议?是否可以预订2012-12-19 10:50:00至2012-12-19 11:20:00的会议?
2、案例分析
将已预订的会议和待预订的会议放时间轴上进行分析,如下图所示:
从上图分析可知,在10:00 至10:40之间,该时间段已预订有以下会议:
在时间轴标示如下图所示,10:00 至10:40可划分成10:00 至10:30和10:30 至10:40两个时间段来统计资源使用情况。
由上图可知,10:00 至10:30使用了4个,而10:30 至10:40则使用了2个。10:00 至10:30期间并发的会议已达到最大会议数4个的限制,若预订了10:00 至10:40的会议,则在10:00 至10:30期间将超出可并发的最大会议数限制,由此可知,不能再预订10:00至10:40的会议。
同理可知,10:50至11:20之间,可划分为10:50 至11:00和11:00 至11:20两个时间段来统计资源使用情况,其中10:50 至11:00使用了2个,而11:00 至11:20使用了1个,两个时间段都没有达到最大会议数4个的限制,由此可知,可以预订10:50至11:20的会议。
综合上述的分析过程,可以得出处理步骤如下:
(1)获取所有已预约会议中与当前要预约会议时间上有交叉的会议,若获取到的会议数量小于最大会议并发数限制时,则可以预约会议,否则进入(2);
(2)根据获取的时间上有交叉的已预约会议的开始时间和结束时间,以及当前要预约会议的开始时间和结束时间,划分时间段,并计算在当前要预约会议内每个时间段已使用的资源数;
(3)判断每个时间段已使用的资源数是否已经达到最大会议并发数限制,若有存在某个时间段已使用的资源数已达到,即当前要预约的会议的某个时间段没有资源,不能预约会议,否则可以预约;
3、解决过程
(1)时间段模型TimePeriod
(2)获取交叉会议
(3)获取时间点
(4)对时间点进行排序
(5)划分时间段
(6)计算每个时间段已使用资源数
(7)判断是否有可用资源
4、解决结果
(1)测试代码
(2)运行结果
(3)结论
从运行结果可知,测试结果正确,问题解决。
5、完整源代码
完整源代码 点击这里 下载
最近做会议管理系统,预约会议需要一个算法来判断在指定的时间段内是否有可用的资源,这个算法是这样的:一个企业可以同时并发的会议数是有限的,预约会议时需要判断在预约的会议时间段内是否有可用的资源,资源没有达到限制数量时可预约会议,一旦资源达到限制的数量则预约会议失败。
举个例子:某企业在同一时间段内可同时并发的最大会议数为4个,企业在2012-12-19已经预订了以下时间段的会议:
编号 | 开始时间 | 结束时间 |
1 | 2012-12-19 09:00:00 | 2012-12-19 09:30:00 |
2 | 2012-12-19 09:00:00 | 2012-12-19 10:00:00 |
3 | 2012-12-19 09:00:00 | 2012-12-19 10:30:00 |
4 | 2012-12-19 09:30:00 | 2012-12-19 11:00:00 |
5 | 2012-12-19 10:00:00 | 2012-12-19 10:30:00 |
6 | 2012-12-19 10:00:00 | 2012-12-19 11:00:00 |
7 | 2012-12-19 11:00:00 | 2012-12-19 12:00:00 |
那么,是否可以预订2012-12-19 10:00:00至2012-12-19 10:40:00的会议?是否可以预订2012-12-19 10:50:00至2012-12-19 11:20:00的会议?
2、案例分析
将已预订的会议和待预订的会议放时间轴上进行分析,如下图所示:
从上图分析可知,在10:00 至10:40之间,该时间段已预订有以下会议:
编号 | 开始时间 | 结束时间 |
3 | 2012-12-19 09:00:00 | 2012-12-19 10:30:00 |
4 | 2012-12-19 09:30:00 | 2012-12-19 11:00:00 |
5 | 2012-12-19 10:00:00 | 2012-12-19 10:30:00 |
6 | 2012-12-19 10:00:00 | 2012-12-19 11:00:00 |
在时间轴标示如下图所示,10:00 至10:40可划分成10:00 至10:30和10:30 至10:40两个时间段来统计资源使用情况。
由上图可知,10:00 至10:30使用了4个,而10:30 至10:40则使用了2个。10:00 至10:30期间并发的会议已达到最大会议数4个的限制,若预订了10:00 至10:40的会议,则在10:00 至10:30期间将超出可并发的最大会议数限制,由此可知,不能再预订10:00至10:40的会议。
同理可知,10:50至11:20之间,可划分为10:50 至11:00和11:00 至11:20两个时间段来统计资源使用情况,其中10:50 至11:00使用了2个,而11:00 至11:20使用了1个,两个时间段都没有达到最大会议数4个的限制,由此可知,可以预订10:50至11:20的会议。
综合上述的分析过程,可以得出处理步骤如下:
(1)获取所有已预约会议中与当前要预约会议时间上有交叉的会议,若获取到的会议数量小于最大会议并发数限制时,则可以预约会议,否则进入(2);
(2)根据获取的时间上有交叉的已预约会议的开始时间和结束时间,以及当前要预约会议的开始时间和结束时间,划分时间段,并计算在当前要预约会议内每个时间段已使用的资源数;
(3)判断每个时间段已使用的资源数是否已经达到最大会议并发数限制,若有存在某个时间段已使用的资源数已达到,即当前要预约的会议的某个时间段没有资源,不能预约会议,否则可以预约;
3、解决过程
(1)时间段模型TimePeriod
class TimePeriod { private String startTime; private String endTime; TimePeriod() { } TimePeriod(String startTime, String endTime) { this.startTime = startTime; this.endTime = endTime; } public String getStartTime() { return startTime; } public void setStartTime(String startTime) { this.startTime = startTime; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } }
(2)获取交叉会议
// 获取列表中与指定时间段有交叉的时间段列表 private static List<TimePeriod> filterPeriods(final TimePeriod source, final List<TimePeriod> resources) { List<TimePeriod> results = new ArrayList<TimePeriod>(0); String ss = source.getStartTime(); String se = source.getEndTime(); for(TimePeriod resource : resources) { String rs = resource.getStartTime(); String re = resource.getEndTime(); if(!(greaterTime(ss, re) || lessTime(se, rs))) { System.out.println("[" + rs + " ~ " + re + "]"); results.add(resource); } } return results; } // 时间比较,time1>=time2时返回true,否则false private static boolean greaterTime(final String time1, final String time2) { return time1.compareTo(time2)>=0; } // 时间比较,time1<=time2时返回true,否则false private static boolean lessTime(final String time1, final String time2) { return time1.compareTo(time2)<=0; }
(3)获取时间点
// 获取列表中与给定时间段内的所有时间点 private static Map<String, String> listPoints(final TimePeriod source, final List<TimePeriod> resources) { Map<String, String> points = new HashMap<String, String> (0); addPoint(source, points); for(TimePeriod resource : resources) { addPoint(source, resource, points); } return points; } // 加入时间点 private static void addPoint(final TimePeriod source, Map<String, String> points) { addPoint(source, source, points); } // 加入时间点 private static void addPoint(final TimePeriod source, final TimePeriod period, Map<String, String> points) { addPoint(source, period.getStartTime(), points); addPoint(source, period.getEndTime(), points); } // 加入时间点 private static void addPoint(final TimePeriod source, final String time, Map<String, String> points) { if(greaterTime(time, source.getStartTime()) && lessTime(time, source.getEndTime())) { if(!points.containsKey(time)) { points.put(time, time); } } }
(4)对时间点进行排序
private static String[] sortPoints(final Map<String, String> points) { int index = 0; String[] results = new String[points.size()]; for(String key : points.keySet()) { results[index ++] = key; } Arrays.sort(results); return results; }
(5)划分时间段
// 根据排序好的时间点,划分相关时间段 private static List<TimePeriod> listPeriods(final String[] points) { List<TimePeriod> spans = new ArrayList<TimePeriod> (0); String start = points[0]; for(int i=1; i<points.length; i++) { spans.add(new TimePeriod(start, points[i])); start = points[i]; } return spans; }
(6)计算每个时间段已使用资源数
// 计算每个时间段已使用的资源数 private static int[] cacl(final List<TimePeriod> periods, final List<TimePeriod> resources) { int[] results = new int[periods.size()]; for(TimePeriod resource : resources) { for(int i=0; i<periods.size(); i++) { if(checkSpan(periods.get(i), resource)) { results[i] ++; } } } printResult(periods, results); return results; } // 检查是否已指定时间段有交叉 private static boolean checkSpan(final TimePeriod period, final TimePeriod resource) { String ss = period.getStartTime(); String se = period.getEndTime(); String rs = resource.getStartTime(); String re = resource.getEndTime(); return(greaterTime(ss,rs) && lessTime(se,re)); } // 打印输出各时间段资源使用情况 private static void printResult(final List<TimePeriod> periods, final int[] results) { for(int i=0; i<results.length; i++) { TimePeriod r = periods.get(i); System.out.println("[" + r.getStartTime() + " ~ " + r.getEndTime() + "]=" + results[i]); } }
(7)判断是否有可用资源
// 判断是否有可用资源,有则返回true,否则返回false private static boolean canBooked(final int max, final TimePeriod source, final List<TimePeriod> resources) { return canBooked(max, cacl(listPeriods(sortPoints(listPoints(source, resources))), resources)); } // 判断已使用的资源数是否存在已超过或等于最大值,是则返回false,否则返回true private static boolean canBooked(final int max, final int[] results) { for(int result : results) { if(result>=max) { return false; } } return true; }
4、解决结果
(1)测试代码
public static void main(String[] args) { int maxResource = 4; TimePeriod source1 = new TimePeriod("2012-12-19 10:00:00","2012-12-19 10:40:00"); TimePeriod source2 = new TimePeriod("2012-12-19 10:50:00","2012-12-19 11:20:00"); List<TimePeriod> resources = new ArrayList<TimePeriod> (0); resources.add(new TimePeriod("2012-12-19 09:00:00","2012-12-19 09:30:00")); resources.add(new TimePeriod("2012-12-19 09:00:00","2012-12-19 10:00:00")); resources.add(new TimePeriod("2012-12-19 09:00:00","2012-12-19 10:30:00")); resources.add(new TimePeriod("2012-12-19 09:30:00","2012-12-19 11:00:00")); resources.add(new TimePeriod("2012-12-19 10:00:00","2012-12-19 10:30:00")); resources.add(new TimePeriod("2012-12-19 10:00:00","2012-12-19 11:00:00")); resources.add(new TimePeriod("2012-12-19 11:00:00","2012-12-19 12:00:00")); if(canBooked(maxResource, source1, resources)) { System.out.println("Yes"); } else { System.out.println("No"); } System.out.println(); if(canBooked(maxResource, source2, resources)) { System.out.println("Yes"); } else { System.out.println("No"); } }
(2)运行结果
[2012-12-19 09:00:00 ~ 2012-12-19 10:30:00] [2012-12-19 09:30:00 ~ 2012-12-19 11:00:00] [2012-12-19 10:00:00 ~ 2012-12-19 10:30:00] [2012-12-19 10:00:00 ~ 2012-12-19 11:00:00] [2012-12-19 10:00:00 ~ 2012-12-19 10:30:00]=4 [2012-12-19 10:30:00 ~ 2012-12-19 10:40:00]=2 No [2012-12-19 09:30:00 ~ 2012-12-19 11:00:00] [2012-12-19 10:00:00 ~ 2012-12-19 11:00:00] [2012-12-19 11:00:00 ~ 2012-12-19 12:00:00] [2012-12-19 10:50:00 ~ 2012-12-19 11:00:00]=2 [2012-12-19 11:00:00 ~ 2012-12-19 11:20:00]=1 Yes
(3)结论
从运行结果可知,测试结果正确,问题解决。
5、完整源代码
完整源代码 点击这里 下载
发表评论
-
MySQL中Update的执行效率测试及验证
2016-12-06 16:22 67991、引言 某日,在讨论解决生产环境的问题时,一同事问说增加条件 ... -
MySQL定时器实战
2016-11-29 17:38 21171、引言 项目商用环境上,用户反馈有个统计存在问题,排查后 ... -
用Java实现N*N的标准数独及对角线数独解题
2016-10-11 11:25 34931、引言 前一段时间迷 ... -
在Spring项目中实现动态创建数据库
2017-06-21 16:31 51621、问题描述 在使用Sprin ... -
改进现有架构支持HTTPS服务
2016-06-23 16:57 01、引言 nginx使用ssl模块配置HTTPS支持 ht ... -
CentOS下从源码安装Asterisk实战
2016-05-20 20:23 35860、引言 在研究WebRTC服 ... -
EasyUI学习(1)- 入门
2015-12-14 17:20 00、引言 前段时间,在项目开发过程中使用了EasyUI的部分组 ... -
JS实现的3级联动例子
2015-06-17 23:10 1350朋友项目需要实现3级联动,需要JS实现的,网上找的例子有些复杂 ... -
JSBuilder2介绍及应用范例
2014-08-27 17:58 01、引言 Web项目开发过程中,使用到多个第三方的插件,同时, ... -
实现CSS样式文件中图标的可视化
2014-06-26 14:39 4937关键词: CSS,EasyUI ... -
jquery选择器学习范例
2014-04-22 20:54 0http://www.w3school.com.cn/jque ... -
通过webrtc2sip实现web客户端sipML5与SIP客户端Jtisi对通
2014-01-13 19:53 00、引言 在研究WebRTC服 ... -
NAT与NAT穿越学习总结
2013-12-23 19:19 204401、引言网络地址转换 ... -
完全清除Desktop_1.ini和Desktop_2.ini
2013-12-06 17:21 71481、引言 Windows7工作机进入系统就会弹出“deskto ... -
CentOS下搭建Asterisk+SIPml5实战
2013-11-14 14:53 00、引言 在研究SIPml5信令处理时,需要搭建环境SIPml ... -
CentOS下编译webrtc2sip实战
2013-11-13 10:39 151850、引言 在研究WebRTC服 ... -
Java实现RTP流转发服务器
2013-10-24 17:36 00、引言 在做多方视频会议系统时,需要有代理服务器来转发视频平 ... -
利用mysql日志排查数据异常问题
2013-03-21 16:52 01、案例描述 2、MySQL日志 3、解决过程 (1) ... -
Java中通过MySQL的行锁解决并发写的问题
2012-12-22 12:45 01、案例描述 开发会议管理项目中,涉及会议管理系统和视频会议平 ... -
API测试范例
2012-10-29 18:38 01、MessagesAPITest package com ...
相关推荐
模拟操作系统 进程模拟调度算法 基于时间片
本文以大规模成品油二次配送路径规划为对象,研究了具有成品油物流特征的多车场带时间窗的车辆路径问题的数学模型,提出了新的基于子问题分解的两阶段优化算法....
网格计算是解决科学计算、工程计算和商业计算等大规模计算的下一代极具潜力的计算平台。... 3)根据基本遗传算法和蚁群算法的本质特征以及网格计算环境对任务调度的要求,设计了基于遗传算法和议群算法的网格任务调度策略
针对以完工时间最小化为目标的置换流水车间调度问题(PFSP),提出了一种基于分布估计算法的二阶段置换流水车间调度算法。首先,在算法的第一阶段采用分布估计算法对PFSP进行优化得到一个局部最优解;为了进一步提高...
基于并行人工免疫算法的大规模TSP问题求解-基于并行人工免疫算法的大规模TSP问题求解.pdf 摘 要: 为求解大规模TSP 问题,提出了并行人工免疫系统的塔式主从模型 ,和基于TMSM的并行免疫记忆克隆选择算法 . TMSM是...
根号n段归并排序算法时间复杂度分析过程: 1.合并 根号n向下取整 段子数组使用的是自底向上两两归并的策略 2.根号n段归并排序算法时间复杂度的数学推导
另外,在语音识别领域,应用动态规划技术的动态时间伸缩算法DTW取得了很大成功,当词汇表较小以及各个词条不易于混淆时,DTW可以有效的解决孤立词识别时说话速度不均匀的难题,从而自20世纪60年代末期掀起了语音识别...
基于多时间段优化贝叶斯网络的车载容迟网络路由算法.docx
图像尺寸为1 024像素×768像素时算法时间复杂度为12.72 s,图像尺寸为3 000像素×2 000像素时算法时间复杂度为639.93 s。与已有的复制粘贴算法相比,所提算法能够快速精准地定位篡改区域,且具有较好的稳健性。
通过松弛各时间段剩余人数概率的关联约束,提出了基于拉格朗日松弛的求解算法,其松弛问题通过动态规划求解,对偶问题通过经典的次梯度法求解.数值实验表明,针对小规模的预约段数,该算法都能找到最优解;当预约段数较大...
最近最久未使用置换算法(LRU): 以“最近的过去”作为“最近的将来”的近似,选择最近一段时间最长时间未被访问的页面淘汰出内存 Clock置换算法:为进入内存的页面设置一个访问位,当内存中某页被访问,访问位置一,...
多段图算法时间复杂度图像
每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的...
首先将所研究的时间段进行时段划分, 然后基于每个路段在每个时段内的历史平均速度给出了改进的Dijkstra算法, 它可以给出任意时刻从任意节点位置出发到达任一目的地的行程...
该算法基于周期性任务系统的特点,引入时间帧控制和改变本地周期性任务调度来限制任务迁移,从而实现对PFair算法的改进。为了评估算法的迁移开销和公平性,通过实验对普通PFair算法及所提出的改进算法ERfair进行对比...
1、 主体结构是基于对 LOF 算法进行改进而来 2、 主要提高的地方是大大减少了 LOF 算法的时间复杂度以及运行时间(就最近一段时间阅 1、 提出了当 LO
研究了一种移动数据的预估聚类分析算法。首先建立移动数据的数学模型,然后在此模型的基础上,提出一个基于微簇的移动数据的聚类分析算法,并对移动微簇...提出的新算法可以预测一定时间段内的任意时刻数据的聚类情况。
GSP算法也是Apriori类算法,在算法的过程中也会进行连接和剪枝操作,不过在剪枝判断的时候还加上了一些时间上的约束等条件。详细介绍链接 PreFixSpan PreFixSpan算法是另一个序列模式挖掘算法,在算法的过程中不会...
针对MapReduce中允许map和shuffle阶段重叠的优化模型需要自适应性的问题,提出了基于此模型的机器学习的资源调度算法,利用贝叶斯分类器依据作业对系统资源的需求和系统环境的匹配程度对作业进行调度,并不断更新...