`
cgs1999
  • 浏览: 536176 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【算法】基于时间段的有限资源算法

阅读更多
1、案例描述
最近做会议管理系统,预约会议需要一个算法来判断在指定的时间段内是否有可用的资源,这个算法是这样的:一个企业可以同时并发的会议数是有限的,预约会议时需要判断在预约的会议时间段内是否有可用的资源,资源没有达到限制数量时可预约会议,一旦资源达到限制的数量则预约会议失败。

举个例子:某企业在同一时间段内可同时并发的最大会议数为4个,企业在2012-12-19已经预订了以下时间段的会议:

编号开始时间结束时间
12012-12-19 09:00:002012-12-19 09:30:00
22012-12-19 09:00:002012-12-19 10:00:00
32012-12-19 09:00:002012-12-19 10:30:00
42012-12-19 09:30:002012-12-19 11:00:00
52012-12-19 10:00:002012-12-19 10:30:00
62012-12-19 10:00:002012-12-19 11:00:00
72012-12-19 11:00:002012-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之间,该时间段已预订有以下会议:
编号开始时间结束时间
32012-12-19 09:00:002012-12-19 10:30:00
42012-12-19 09:30:002012-12-19 11:00:00
52012-12-19 10:00:002012-12-19 10:30:00
62012-12-19 10:00:002012-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、完整源代码
完整源代码  点击这里  下载
  • 大小: 12.5 KB
  • 大小: 6.7 KB
分享到:
评论

相关推荐

    基于云计算环境的蚁群优化计算资源分配算法

    ### 基于云计算环境的蚁群优化计算资源分配算法 #### 概述 随着信息技术的飞速发展,云计算作为一种新兴的服务模式,以其强大的计算能力和灵活的服务方式受到了广泛关注。云计算的核心理念是通过互联网提供计算...

    编写程序实现基于优先级的时间片轮转调度算法

    本实验聚焦于“基于优先级的时间片轮转调度算法”,这是一种兼顾响应时间和系统效率的调度策略。以下是对该算法及其相关知识的详细阐述。 时间片轮转调度算法是一种多任务调度方式,它的基本思想是将所有就绪进程放...

    模拟操作系统 进程模拟调度算法 基于时间片

    ### 模拟操作系统进程调度算法——基于时间片轮转法 在计算机科学中,操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的计算机程序。它负责处理硬件资源的分配、进程管理、内存管理、设备管理以及...

    基于Dijkstra和时间窗规划的AGV小车(电动汽车)调度算法(MATLAB)

    本文将探讨基于Dijkstra算法和时间窗规划的AGV小车调度方法,并以MATLAB源码为载体进行详细解释。 Dijkstra算法是图论中解决单源最短路径问题的经典算法,由荷兰计算机科学家艾兹格·迪科斯彻提出。在AGV调度问题中...

    基于蚁群算法的资源均衡优化决策及其MATLAB实现.pdf

    资源均衡问题,是指在网络计划中,通过合理安排各工序的开始工作时间,使资源在各个时间段的使用尽可能均衡。资源均衡问题在工程项目管理中非常常见,如在建筑施工、制造生产以及计算机网络等项目中,都需要对人力、...

    本算法采用了基于蚁群算法的遗传算法对车辆进行调度,车辆能够找到最优路径,实现最短时间调度,matlab源码

    本项目采用了一种结合蚁群算法与遗传算法的混合优化策略来解决这一问题,旨在为车辆规划出最短的行驶路线,以达到在限定时间内完成所有任务的目标。下面我们将详细探讨这两种算法以及它们在MATLAB中的应用。 1. 蚁...

    基于蚁群算法和Dijkstra算法的二维路径规划

    Dijkstra算法基于贪心策略,每次扩展当前最短路径节点,直到到达目标节点。虽然Dijkstra算法在处理大规模网络时效率较低,但它能够保证找到精确的最短路径,对于简单的二维路径规划问题非常适用。 结合蚁群算法和...

    基于物品的协同过滤算法 (mapreduce)

    6. **优化与迭代**:为了提高推荐质量,可以进行迭代更新,例如使用近似算法降低计算复杂度,或者引入其他因素如时间衰减、冷启动策略等。 在大数据环境下,基于物品的协同过滤算法与MapReduce的结合不仅提升了推荐...

    基于PBFT共识算法的区块链改进方案.pdf

    传统的PBFT算法在主节点出现故障时,需要进行视图变更,过程中会有一段时间系统的共识过程是停滞的,导致系统的可用性降低。通过引入备用主节点机制,在主节点出现问题时可以迅速切换到备用节点继续进行共识流程,...

    基于遗传算法的BP神经网络图像复原算法研究.pdf

    ### 基于遗传算法的BP神经网络图像复原算法研究 #### 摘要与背景 本研究探讨了一种结合遗传算法(Genetic Algorithm, GA)与BP神经网络(Back Propagation Neural Network, BPNN)的方法,在图像复原领域的应用。...

    基于多层编码遗传算法的车间调度算法

    该描述表明,这个项目不仅关注于解决车间调度问题,同时也作为一个学习资源,帮助用户理解遗传算法的原理和实现方式,特别是如何利用MATLAB编程语言来构建和执行这种算法。MATLAB作为一种强大的数值计算和数据可视化...

    Matlab实现基于RD算法的雷达成像

    【Matlab实现基于RD算法的雷达成像】是针对雷达信号处理领域的一种基本教程,主要适用于本科和硕士级别的教研学习。RD算法,全称为Range-Doppler Algorithm(范围多普勒算法),是一种广泛应用于雷达系统中的信号...

    基于字符串模式匹配算法的病毒感染检测问题_算法_数据结构_

    本话题将深入探讨如何利用C语言实现基于字符串模式匹配算法的病毒感染检测。 首先,我们需要了解字符串模式匹配的基本概念。在这一背景下,我们有一个目标字符串(通常代表一段文件内容)和一个模式字符串(可能是...

    基于hadoop的apriori算法设计于实现

    通过实验对比,基于Hadoop平台优化后的Apriori算法相比于传统Apriori算法在处理时间和计算效率方面都有显著提升。特别是在处理大规模数据集时,优化后的算法能够更快地完成计算任务,大大提高了数据处理能力。 ####...

    基于多时间段优化贝叶斯网络的车载容迟网络路由算法.docx

    ### 基于多时间段优化贝叶斯网络的车载容迟网络路由算法 #### 引言及背景 本文探讨了一种新型的车载容迟网络(VDTN)路由算法,该算法利用多时间段优化的贝叶斯网络(BN)来提高消息的投递效率。面对自然灾害如地震或...

    基于遗传算法和蚁群算法的网格任务调度策略

    网格计算是解决科学计算、工程计算和商业计算等大规模计算的下一代极具潜力的计算平台。... 3)根据基本遗传算法和蚁群算法的本质特征以及网格计算环境对任务调度的要求,设计了基于遗传算法和议群算法的网格任务调度策略

    C-C算法求时间延迟_c-c算法_时间延迟_

    这个时间段即为单个cell的传输时间。通过多次测量,我们可以得到多个cell传输时间的样本,从而计算平均值作为平均传输时间。 4. **调整参数**:在实际应用中,可能会遇到网络拥塞、丢包等问题,这会导致传输时间的...

    基于CCS的卷积算法

    在基于CCS的卷积算法仿真实验中,我们首先需要理解卷积运算的数学基础,包括线性代数和离散时间信号处理的基本概念。接着,我们需要熟悉CCS的工作流程,创建项目、编写源代码、配置编译器选项以及设置调试参数。源...

Global site tag (gtag.js) - Google Analytics