ошибка алгоритма SCAN

0

У меня есть файл, который имеет номер один, и я хочу выполнить алгоритм сканирования (лифт), чтобы вычислить общее расстояние.

размер очереди равен 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

вы должны сохранить его как filename 'sort'

  • 0
    Используете ли вы алгоритм поиска с кратчайшим временем поиска?
  • 0
    Нет, я использую SCAN (лифт).
Показать ещё 4 комментария
Теги:
algorithm
scheduling
scheduler

1 ответ

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, который был новым в очереди.

Такая же ошибка возникает, когда вы находитесь на правой стороне, и то же значение вставлено в левой части вашего текущего значения.

Вот иллюстрация этого, используя queuesize of 3.
Рассмотрим, что ваша очередь мультисети имеет значения (300,700,900) и оставшееся направление = 0. Numebr со звездой справа указывает, где итератор. предположим totalSweepDistance = 0 в это время.

  • Текущая очередь (300 *, 700, 900), totalSweepDistance = 0, direction = 0
  • Вы читаете 300 и вставляете их в очередь (300 *, 300, 700, 900), totalSweepDistance = 0, direction = 0
  • Вы проверяете начало очереди и возвращает true. Вы добавляете расстояние развертки перемещения до 0, меняете направление вправо, а затем достигаете 300, что делает расстояние развертки = 600
  • Текущая очередь (300 *, 700, 900), totalSweepDistance = 600 direction = 1
  • Вы читаете новое значение, которое меньше 300 и идеально, которое было бы прочитано в левом разметке, если бы вы не изменили направление и не выполнили правильную развертку, которая не требовалась, увеличивая количество развертки, которое вы делаете.

Решение

Одним из возможных решений является добавление нового значения в очередь, которое совпадает с текущим значением. Проверяйте одно место справа от текущего положения, когда вы двигаетесь влево, и проверяйте одно место слева от текущей позиции, когда вы двигаетесь вправо для вставки того же значения.

  • 0
    Спасибо, вы правы! Я очень ценю вашу помощь, я борюсь с ней два дня. Спасибо!!!!!
  • 0
    Нет проблем. Из вашего кода не похоже, что вам понадобится моя помощь в реализации изменений, но если вам нужна помощь. Не стейсняйся спросить.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню