【问题标题】:disk scheduler SCAN algorithm bug磁盘调度程序 SCAN 算法错误
【发布时间】:2013-12-29 20:15:30
【问题描述】:

我有一个第一行的文件,我想做扫描算法(电梯)来计算总距离。

队列大小为 32,总数据行数为 35691

左端为0

右端是59999

ex:

queue size is 3

start from 0

left end is 0

right end is 255

all request:30, 150, 30, 10, 70

1.
head:0
quene:30, 150, 30
distance:0
2.
head:30
quene:150, 30, 10
distance:30
3.
head:30
quene:150, 10, 70
distance:30
4.
head:70
quene:150, 10
distance:70
5.
head:150
quene:10
distance:150
6.
head:10
quene:
distance:500(150 to right end 255 and come back to 10 --> 150 + (255 - 150) * 2 + (150 - 10))

我做的是下面的代码,我用multi set来存储它,

the first stage I fill up the queue

the second stage I insert the next element first

if the direction is right now

to see whether there is element next to the current, if not, change the direction, else keep right moving.

if the direction is left now

do the same thing above but go to left 

the third stage I will calculate the remaining element in the queue.

我遇到的问题是我在

中计算的距离
second stage is larger the result

,所以可能有问题。而且我认为我认为是对的,我想不通

哪里出错了。

最终结果应该是 33055962。

还有代码:

#include <iostream>
#include <fstream>
#include <string>
#include <set>
const int dataSize = 35691;
const int queueSize = 32;
const int minNumber = 0;
const int maxNumber = 59999;
using namespace std;

int number = minNumber;
int direction = 1;// right
int distanceSum = 0;
multiset<int> myset;
multiset<int>::iterator it;
multiset<int>::iterator temp;
multiset<int>::iterator next;
void print(void);

int main(int argc, char const *argv[]){
    ifstream myfile("sort");
    if (myfile.is_open()){
// ===============================initialization===============================
        for(int i = 0; i < queueSize; i ++){
            myfile >> number;
            myset.insert(number);           
        }
        it = myset.begin();
        int last = minNumber;
        int current = *it;
// ===============================middle stage===============================
        for(int i = 0; i < dataSize - queueSize; i ++){
            myfile >> number;
            myset.insert(number);
            current = *it;
            if(direction == 1){// right
                next = it;
                next ++;
                if(next == myset.end()){// right most
                    direction = 0;// change direction
                    distanceSum += ((maxNumber - current) * 2 + (current - last));
                    temp = it;
                    it --;
                    myset.erase(temp);
                    last = current;
                }
                else{
                    distanceSum += (current - last);
                    temp = it;
                    it ++;
                    myset.erase(temp);
                    last = current;
                }
            }
            else if(direction == 0){// left
                if(it == myset.begin()){// left most
                    direction = 1;// change direction
                    distanceSum += ((current - minNumber) * 2 + (last - current));
                    temp = it;
                    it ++;
                    myset.erase(temp);
                    last = current;
                }
                else{
                    distanceSum += (last - current);
                    temp = it;
                    it --;
                    myset.erase(temp);
                    last = current;
                }
            }       
        }
// ===============================remaining===============================
        // for(int i = 0; i < queueSize; i ++){
        //  current = *it;
        //  if(direction == 1){// right
        //      next = it;
        //      next ++;
        //      if(next == myset.end()){
        //          direction = 0;
        //          if(myset.size() == 1)distanceSum += (current - last);
        //          else distanceSum += ((maxNumber - current) * 2 + (current - last));
        //          temp = it;
        //          it --;
        //          myset.erase(temp);
        //          last = current;
        //      }
        //      else{
        //          distanceSum += (current - last);
        //          temp = it;
        //          it ++;
        //          myset.erase(temp);
        //          last = current;
        //      }
        //  }
        //  else if(direction == 0){

        //      if(it == myset.begin()){
        //          direction = 1;
        //          if(myset.size() == 1)distanceSum += (last - current);
        //          else distanceSum += ((current - minNumber) * 2 + (last - current));
        //          temp = it;
        //          it ++;
        //          myset.erase(temp);
        //          last = current;
        //      }
        //      else{
        //          distanceSum += (last - current);
        //          temp = it;
        //          it --;
        //          myset.erase(temp);
        //          last = current;
        //      }
        //  }       
        // }
        myfile.close();
    }
    else cout << "Unable to open file";
    print();
    cout << "distanceSum is :" << distanceSum << endl;
    return 0;
}
void print(){
    cout << "value:" << endl;
    for(multiset<int>::iterator it = myset.begin(); it != myset.end(); it ++){
        cout << *it << "\t"; 
    }
    cout << endl;
    cout << "current point to:" << *it << endl;
    cout << "total size is:" << myset.size() << endl;
    cout << "current distance:" << distanceSum << endl;
}

以及测试数据:

https://drive.google.com/file/d/0ByMlz1Uisc9ONWJIdFFXaGdpSXM/edit?usp=sharing

你应该把它保存为文件名'sort'

【问题讨论】:

  • 您是否使用最短寻道时间优先算法?
  • 不,我使用的是 SCAN(电梯)。
  • 好的。在阅读了您的最后一个案例后意识到这一点。编辑:您在问题中也提到了这一点。我想知道我是怎么错过的。
  • 但是我会删除一个元素。我第一个插入是测试左右是否有下一个元素。这样头部就可以走了。
  • 查看答案。它识别代码中的问题。我会继续扩展它。

标签: c++ algorithm scheduling scheduler


【解决方案1】:

我现在已经阅读了您的算法三遍,我能找到的唯一错误是您读取的值相同。考虑一下,

  • 您在位置 300 向左移动。
  • 您将新元素插入队列中,该元素也是位置 '300'。

    Now in the multiset implementation according to this SO answer
    (http://stackoverflow.com/q/2643473) depending on the implementation
    the value can either go right to your present value(C++ 0x) or can go
    anywhere(C++03). 
    
  • 因此,如果您在位置 300 并假设新值被插入到多重集中当前值的右侧。

  • 您检查左侧并移动到较小的元素,或者如果您在最左边的位置,则在下降到位置 0 后开始右扫。而您应该首先访问位置 300 中的值,这是新的队列。

当您在右侧并且在您的当前值的左侧插入相同的值时,会发生相同类型的错误。

这是一个使用队列大小为 3 的示例。
考虑您的多集队列具有值 (300,700,900) 和方向 = 0,即左侧。右边带有星号的数字表示它所在的迭代器。让我们假设此时 totalSweepDistance=0。

  • 您当前的队列(300*、700、900),totalSweepDistance=0,方向=0
  • 你读取300并将其插入队列(300*、300、700、900),totalSweepDistance=0,direction =0
  • 您检查队列的开头并返回真。您将移动的扫掠距离添加为0,将方向更改为向右,然后达到300,使得扫掠距离=600
  • 您当前的队列(300*、700、900),totalSweepDistance=600 方向 =1
  • 您读取了一个低于 300 的新值,理想情况下,如果您不更改方向并执行右扫描,则该值会在左扫描中读取,而无需增加您执行的扫描量。

解决方案

一种可能的解决方案是在队列中插入一个与当前值相同的新值。向左移动时检查当前位置的右侧一位,向右移动时检查当前位置左侧的一位以插入相同的值。

【讨论】:

  • 谢谢,你是对的!非常感谢您的帮助,我已经与它斗争了两天。谢谢!!!!!!
  • 没问题。从您的代码来看,您似乎不需要我的帮助来实施更改,但如果您需要任何帮助。随时问。
猜你喜欢
  • 1970-01-01
  • 2012-11-07
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多