0

I have a file which have a number one line, and I want to do the scan algorithm(elevator) to calculate the total distance.

the queue size is 32 and total data line is 35691

left end is 0

and right end is 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))

what I do is the following code, I use the multi set to store it,

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.

What I encounter the problem is the distance that I calculate in the

second stage is larger the result

, so it may something wrong. And I think that what I think is right and I cannot figure out

where is the error.

The final result should be 33055962.

And the code:

#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;
}

and the test data:

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

you should save it as filename 'sort'

Jason
  • 1,573
  • 3
  • 18
  • 46

1 Answers1

1

I have read your algorithm three times now and the only fault I can find is when you read the same value. Consider this,

  • you are on position 300 moving left.
  • You insert the new element in queue which is also position '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). 
    
  • So, if you are in position 300 and suppose the new value gets inserted in the right side of your present value in the multiset.

  • You check the left side and move to the smaller element or if you are in the leftmost position start a right sweep after going down to postion 0. Whereas you should have done accessed the value first in position 300 which was new in the queue.

The same kind of error will occur when you are on right side and the same value gets inserted in the left side of your present value.

Here is an illustration of it using a queuesize of 3.
Consider your multiset queue has values (300,700,900) and the direction = 0 which is left. The numebr with the star on it's right indicates where the iterator it is. let us assume totalSweepDistance=0 at this time.

  • Your current queue (300*, 700, 900), totalSweepDistance=0, direction =0
  • You read 300 and insert it in the queue (300*, 300, 700, 900), totalSweepDistance=0, direction =0
  • You check for the beginning of the queue and it returns true. You add the sweep distance of moving to 0, change the direction to right and then reach 300 which makes the sweep distance =600
  • Your current queue (300*, 700, 900), totalSweepDistance=600 direction =1
  • You read a new value which is lower than 300 and ideally which would have been read in the left sweep had you not changed the direction and performed a right sweep which was not needed increasing the amount of sweep you do.

Solution

One possible solution is when you insert a new value into the queue which is same as the present value. Check one place right of the current positon when you are moving to left and check one place left of current position when you are moving to right for the insertion of the same value.

erosenin
  • 1,052
  • 10
  • 22
  • Thank, you are right! I very appreciate your help, I have fight with it two days. Thank you!!!!! – Jason Dec 30 '13 at 05:12
  • No problem. From your code it doesn't look like you will need my help implementing the change but if you need any help. Feel free to ask. – erosenin Dec 30 '13 at 05:15