顺利的过了Amazon的OA1,所以开始准备OA2了。
在Leetcode上面刷了一些题。不过一亩三分地中大家反馈的OA2的题leetcode上面基本上没有了。
有一道把O变成X的题目,据说是比较类似其中一道的,但是示例输入我怎么都输入不进去,所以干脆放弃了。时间要紧。
所以第一道写了一亩三分地里面最近出现的比较多的Round Robin。给出几个Process的request time和duration求average waiting time。
示例输入:
request time: [0,1,3,9]
duration: [2,1,7,5]
q=3
average waiting time : 0.5
request time: [0,2,4,5]
duration: [7,4,1,4]
q=3
average waiting time : 7
=============================================================================
写这篇博客的时候有点把FCFS和Round Robin弄混了,这里的Average Time 应该是7. 谢谢 sinat_21293821 帮我指出来。
http://www.tutorialspoint.com/operating_system/os_process_scheduling_algorithms.htm 这个网页中讲的比较详细,同时Wikipedia里面关于Round Robin也是讲的比较好的。做一个马克,等我把明天的面试结束了再回来看看这篇文章中的差错。
=============================================================================
当然也可以自己手算。
拿第一个作为例子, i为序列号,第一次进去的肯定i=0,然后再剩下的里面找duration最小的,并且到达了开始时间的,i=2,接着虽然i=4的duration比较小,可是现在的时间是3(i=4到第9秒才发出请求),只能运行i=3。
同理第二个也是从i=0开始。运行7s。这里注意,有一个q,就是说运行了q秒之后,你需要停下来看看有没有请求开始,并且比现在的duration更短的。在这个例子中会停下来两次,但是总会发现还是现在运行的最短。注意,这个时候waiting time不能变多,因为没有换,duration时间最短的仍旧是i=0。
i=0在这里7s其实是连续运行完了的,接着运行i=2,运行时间为1s,然后是i=1,和i=3
我在处理这里的变化的时候的做法是改了原来输入数据的开始时间和运行时间。具体实现如下:
private static double roundRobin(int[] arrivetime, int[] executiontime, int q) {
// TODO Auto-generated method stub
LinkedList<process> que = new LinkedList<process>();
if(arrivetime.length < 1 || executiontime.length < 1)
return 0;
int currentTime = 0;
int waitTime = 0;
int nextP = 0;
while(true)
{
if(!que.isEmpty())
{
process curP = que.poll();
waitTime += currentTime - arrivetime[nextP];
if(curP.excuteTime <= q)
{
currentTime += curP.excuteTime;
executiontime[nextP] = executiontime[nextP]- curP.excuteTime;
}
else
{
currentTime+= q;
arrivetime[nextP] = currentTime;
executiontime[nextP] = executiontime[nextP]-q;
//System.out.println(currentTime +"\t"+arrivetime[nextP]+"\t"+executiontime[nextP]);
}
que.peek();
int min = 1000000;
int count = 0;
//找下一个最小
for(int i=0; i < arrivetime.length; i++)
{
if(arrivetime[i] <= currentTime)
{
if(min > executiontime[i]&& executiontime[i]>0)
{
min = executiontime[i];
nextP = i;
}
if(executiontime[i]<1)
{
count++;
// System.out.println("i:\t"+i+" :"+executiontime[i]+"\tnow count:\t"+count);
}
}
}
if(count==arrivetime.length)
{
break;
}
}else
{
que.offer(new process(arrivetime[nextP],executiontime[nextP]));
}
}
return ((double)waitTime/arrivetime.length);
}
代码部分参考了一亩三分地里面的一个人发的代码,但是说真的,我没看懂他的逻辑,所以重新自己写了一遍。不过我觉得自己判断结束这一块儿做的有点复杂,应该有更好的方法,可是一时想不到
顺便附上 dwl1222 的代码(就是我上面说参考的那个人的)
public class process {
int arriveTime;
int excuteTime;
process(int arr, int exc) {
arriveTime = arr;
excuteTime = exc;
}
}
// Assume arrive is sorted.
public double roundRobin(int[] arrive, int[] excute, int q) {
LinkedList<process> queue = new LinkedList<>();
int curTime = 0;
int waitTime = 0;
int nextProIdx = 0;
while (!queue.isEmpty() || nextProIdx < arrive.length) {
if (!queue.isEmpty()) {. 1point3acres.com/bbs
process cur = queue.poll();
waitTime += curTime - cur.arriveTime;
curTime += Math.min(cur.excuteTime, q);
for (int i = nextProIdx; i < arrive.length; i ++) {
if (arrive[i] <= curTime) {
queue.offer(new process(arrive[i], excute[i]));
nextProIdx = i + 1;
} else {
break;
}
}
if (cur.excuteTime > q) {
queue.offer(new process(curTime, cur.excuteTime - q);
}
} else {
queue.offer(new process(arrive[nextProIdx], excute[nextProIdx]));
curTime = arrive[nextProIdx ++];
}
}
return (double)waitTime / arrive.length;
}