I have unsorted pairs of integers, which represent some time intervals (first number is always less than the second one). The problem is to assign an integer, so called channel number(0..x) to each time interval, so that the intervals which do not collide will share the same channel. The least possible number of channels should be used.
For example those intervals will use 2 channels:
50 100 //1
10 70 //0
80 200 //0
I've implemented it using counting sort, to sort the input by the first column, and then used linear search to find chains of pairs, which follow one another. I also first of all copy the input *const*array to the new one, and at the end, assign values to the correct positions in the input array.
Yes, it is an assignment I've got from the University, and its implemented already, but can anybody please tell me how to make the code faster ? Which algorithm to use, so that sorting, chaining of pairs will be as fast as possible ? The length of the input array is up to 10 millions elements.
Here is the code:
#include <cstdlib>
#include <cstdio>
#include <iostream>
using namespace std;
struct TPhone
{
unsigned int m_TimeFrom;
unsigned int m_TimeTo;
unsigned int m_Channel;
};
class TElement
{
public:
TPhone m_data;
int index;
TElement(TPhone * const data, int index_)
{
m_data.m_TimeFrom=data->m_TimeFrom;
m_data.m_TimeTo=data->m_TimeTo;
m_data.m_Channel=-1;
index=index_;
}
TElement()
{
}
};
int FindNext(TElement** sorted_general_array, int general_array_size, int index_from)
{
for (int i=index_from+1; i<general_array_size; i++ )
{
if (sorted_general_array[i]->m_data.m_TimeFrom > sorted_general_array[index_from]->m_data.m_TimeTo)
{
if (sorted_general_array[i]->m_data.m_Channel==(unsigned int)-1)
{
return i;
}
}
}
return -1;
}
int AssignChannels(TElement **sorted_general_array, int general_array_size)
{
int current_channel=-1;
for (int i=0; i<general_array_size; i++)
{
if (sorted_general_array[i]->m_data.m_Channel==(unsigned int)-1)
{
current_channel++;
sorted_general_array[i]->m_data.m_Channel=current_channel;
//cout << sorted_general_array[i]->m_data.m_TimeFrom << " " << sorted_general_array[i]->m_data.m_TimeTo << " " << sorted_general_array[i]->m_data.m_Channel << endl;
int next_greater=i;
while (1)
{
next_greater=FindNext(sorted_general_array,general_array_size,next_greater);
if (next_greater!=-1)
{
sorted_general_array[next_greater]->m_data.m_Channel=current_channel;
//cout << sorted_general_array[next_greater]->m_data.m_TimeFrom << " " << sorted_general_array[next_greater]->m_data.m_TimeTo << " " << sorted_general_array[next_greater]->m_data.m_Channel << endl;
}
else
{
break;
}
}
}
}
return current_channel;
}
int AllocChannels ( TPhone * const * req, int reqNr )
{
//initialize
int count_array_size=1700000;
int * count_array;
count_array=new int [count_array_size];
for (int i=0; i<count_array_size; i++)
{
count_array[i]=0;
}
//
int general_array_size=reqNr;
TElement ** general_array;
general_array=new TElement *[general_array_size];
for (int i=0; i<general_array_size; i++)
{
general_array[i]= new TElement(req[i],i);
}
//--------------------------------------------------
//counting sort
//count number of each element
for (int i=0; i<general_array_size; i++)
{
count_array[general_array[i]->m_data.m_TimeFrom]++;
}
//modify array to find postiions
for (int i=0; i<count_array_size-1; i++)
{
count_array[i+1]=count_array[i+1]+count_array[i];
}
//make output array, and fill in the sorted data
TElement ** sorted_general_array;
sorted_general_array=new TElement *[general_array_size];
for (int i=0; i <general_array_size; i++)
{
int insert_position=count_array[general_array[i]->m_data.m_TimeFrom]-1;
sorted_general_array[insert_position]=new TElement;
//cout << "inserting " << general_array[i]->m_data.m_TimeFrom << " to " << insert_position << endl;
sorted_general_array[insert_position]->m_data.m_TimeFrom=general_array[i]->m_data.m_TimeFrom;
sorted_general_array[insert_position]->m_data.m_TimeTo=general_array[i]->m_data.m_TimeTo;
sorted_general_array[insert_position]->m_data.m_Channel=general_array[i]->m_data.m_Channel;
sorted_general_array[insert_position]->index=general_array[i]->index;
count_array[general_array[i]->m_data.m_TimeFrom]--;
delete general_array[i];
}
//free memory which is no longer needed
delete [] general_array;
delete [] count_array;
//--------------------------------------------------
int channels_number=AssignChannels(sorted_general_array,general_array_size);
if (channels_number==-1)
{
channels_number=0;
}
else
{
channels_number++;
}
//output
for (int i=0; i<general_array_size; i++)
{
req[sorted_general_array[i]->index]->m_Channel=sorted_general_array[i]->m_data.m_Channel;
}
//free memory and return
for (int i=0; i<general_array_size; i++)
{
delete sorted_general_array[i];
}
delete [] sorted_general_array;
return channels_number;
}
int main ( int argc, char * argv [] )
{
TPhone ** ptr;
int cnt, chnl;
if ( ! (cin >> cnt) ) return 1;
ptr = new TPhone * [ cnt ];
for ( int i = 0; i < cnt; i ++ )
{
TPhone * n = new TPhone;
if ( ! (cin >> n -> m_TimeFrom >> n -> m_TimeTo) ) return 1;
ptr[i] = n;
}
chnl = AllocChannels ( ptr, cnt );
cout << chnl << endl;
for ( int i = 0; i < cnt; i ++ )
{
cout << ptr[i] -> m_Channel << endl;
delete ptr[i];
}
delete [] ptr;
return 0;
}