HIT Software Construction Lab3 发现一个MultiIntervalSet<L>对象中的时间冲突比例

题目:发现一个MultiIntervalSet<L>对象中的时间冲突比例

           double calcConflictRatio(MultiIntervalSet<L> set)

思路从一篇关于计算两个MultiIntervalSet 的相似度的文章中获取

原文链接:https://blog.csdn.net/oOCryOo/article/details/118354059

该文章对两个MultiIntervalSet 的相似度进行如下计算:

分子为所有的相似度的总和,采用类似于括号匹配的方法来计算,设定一个double similar 来记录相似度总和:

指定一个标签label 从s1和s2中取出所有有关这个标签的集合并把它们放入一个treeset当中
当遇到一个start 的时候压栈,如果遇到end则弹栈,这一对区间必定属于A或者属于B
当遇到一个start压栈后,再次遇到start ,压栈,遇到end则弹栈,计算该end-start并将其加到similar当中
当遍历完所有(start,end)则结束计算,similar值即为相似度总和

分母的计算:取s1和s2中起始点最小值为min、s1和s2中结束点最大值为max,分母similarlength = max - min

计算一个MultiIntervalSet<L>对象中的时间冲突比例与之类似:

分母同上计算方法,分子为所有存在冲突的课程时间总和,设置一个ConflictSum来计算

将所有课程的起始时间放入startSet,结束时间放入endSet。

当遇到一个start 的时候压栈并从startSet中删去start,如果遇到end则弹栈并从endSet中删去end,这个区间即不存在时间冲突。
当遇到一个start后,再次遇到start ,说明即将迎来时间冲突,此时压栈并从startSet中删去start,遇到end则弹栈并从endSet中删去end,计算该end-start并将其加到ConflictSum当中。
当遇到一个start后,再次遇到start ,再遇到一个start时,说明可能迎来三重时间冲突,此时先计算当前的end-start,将startSet中的第一个时间点替换为endSet中的第一个时间点。

当遍历完所有(start,end)则结束计算,ConflictSum值即为冲突时间总和

代码如下:

    public double calcConflictRatio(MultiIntervalSet<L> set) {
		double ConflictSum = 0, min = POSITIVE_INFINITY, max = 0;
		Set<L> Labels = set.labels();
		Iterator<L> label = Labels.iterator();
		Stack<Long> stack = new Stack<Long>();
		stack.empty();
		LinkedList<Long> startSet = new LinkedList<>();
		LinkedList<Long> endSet = new LinkedList<>();	
		while (label.hasNext()) {
			TreeSet<time> tmpSet = new TreeSet<>();
			L tmpL = label.next();
			
			tmpSet.addAll(set.intervals(tmpL));
			for (time tmpTime : tmpSet) {
				if (tmpTime.start() < min)
					min = tmpTime.start();
				if (tmpTime.end() > max)
					max = tmpTime.end();
				startSet.add(tmpTime.start());
				endSet.add(tmpTime.end());
			}
			Collections.sort(startSet);
			Collections.sort(endSet);
	
		}

		while (!startSet.isEmpty() || !endSet.isEmpty())
		{
			if (stack.isEmpty()) { 
				Long tmp = startSet.getFirst();
				stack.push(tmp);
				startSet.removeFirst();
			} 
			else if (stack.size() == 2) {				
				System.out.println(endSet.getFirst()+"sdf"+stack.peek());
				ConflictSum += endSet.getFirst() - stack.pop();
				if(!startSet.isEmpty()&&(startSet.getFirst() < endSet.getFirst())){
					startSet.removeFirst();
					startSet.add(endSet.getFirst());
					endSet.removeFirst();
				}
				else
				    endSet.removeFirst();
			}
			else if(stack.size()==1){
				if (startSet.size() > 0) {
					if (startSet.getFirst() <= endSet.getFirst())
					{
						stack.push(startSet.getFirst());
						startSet.removeFirst();
					} else {
						stack.pop();
						endSet.removeFirst();
					}
				} else {
					stack.pop();
					endSet.removeFirst();
				}
			}
		}
		return ConflictSum / (max-min);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值