Reputation: 5038
I have a QMap<int, MyData>
where the key is the address of Modbus register, and MyData
is my own struct that contains some information not important for this question.
The keys set might be quite large (say 2000 values) with some of them close each other. For example:
1, 2, 3, 4, 7, 23, 24, 25, 40, 41, 43, ...
My goal is to end up with a QList<QPair<int,int>>
where the items of the QPair
class are the lower and upper bounds of each Modbus request I will send.
This list should be optimized to join together consequential values or values "very close" each other. This is to reduce the number of Modbus requests with a trade-off with the amount of data requested.
In the example above I would like:
[1, 7], [23, 25], [40, 43]
I'm going to set a couple of constraints to give a weight for each request. Requesting data from address 1 to 7 is worth than 1 to 4 and then only 7, but it isn't if the 7 was 16... Another constraint is the maximum length of a single request: even if there are a lot of consequential addresses they must be splitted in segments of length N.
I'm asking some guidelines how to approach such a problem.
What I thought until now. Create a second array with the difference between element x and x-1:
1, 2, 3, 4, 7, 23, 24, 25, 40, 41, 43, ...
1, 1, 1, 3, 16, 1, 1, 15, 1, 2, ...
Then scan this array and find any number below the "weight threshold" (let's say is 4) and create the first QPair
list including those addresses:
[1, 7], [23, 25], [40, 43]
Finally, check the length of each couples and if greater than the maximum allowable split it.
Do you think is a reasonable approach? Is there some well-known algorithm that might fit here? Does a QMap
is a good choice? I used this because I'm going to emit a signal when I receive each value from the Modbus like this:
void dataReceived(int address, quint16 value);
hence would be very easy to retrieve the related MyData
.
Upvotes: 1
Views: 224
Reputation: 306
The solution you thought is great. It solves the problem in O(n)
complexity. In terms of complexity can not be better than this. Since to build the list is needed to traverse all the elements. But... you can do it a little faster (assuming that the array is sorted)
To build the list QList<QPair<int,int>>
you are doing three iterations of size n.:
1 - Build the array with the differences.
2 - Create the list traversing the array built in the previous step
3 - Check the length of each couples and if greater than the maximum allowable split it.
You can do it in only one iteration (one step); Keeping track of variables start, end of the pair and the size. When you find a value that has a difference greater than the "weight threshold" from the previos value or the size is greater than the "maximun allowable" then -> Add the pair to the list and reset the variables start, end and size with the next value.
Anyway since the list is only 2000 values max it is not a big diference.
About your other question. Yes QMap
is an excellent choice since provide O(1)
time complexity to retrive your data.
Upvotes: 3