您的问题是典型的计划问题。这些问题在计算机科学中得到了很好的研究,因此有大量文献可供参考。
该代码有点像Deficit round
robin,但有一些简化。首先,我们通过添加
data_to_process变量来自己填充队列。其次,队列只是循环访问值列表。
一个区别是,除数学误差外,该解决方案将获得所需的最佳值。
粗略的草图:尚未编译(c ++ 11) 基于unix的规范代码
#include <iostream>#include <vector>#include <numeric>#include <unistd.h>//#include <cmath> //for ceil#define TIME_SCALE ((double)60.0) //1 for realtime speed//Assuming you are not refreshing ints in the real casetemplate<typename T>struct queue{ const std::vector<T> data; //this will be filled with numbers int position; double refresh_rate; //must be refreshed ever ~ hours double data_rate; //this many refreshes per hour double credit; //amount of refreshes owed queue(std::initializer_list<T> v, int r ) : data(v), position(0), refresh_rate(r), credit(0) { data_rate = data.size() / (double) refresh_rate; } int getNext() { return data[position++ % data.size()]; }};double time_passed(){static double total;//if(total < 20){ //stop early usleep(60000000 / TIME_SCALE); //sleep for a minute total += 1.0 / 60.0; //add a minute std::cout << "Time: " << total << std::endl; return 1.0; //change to 1.0 / 60.0 for real time speed//} else return 0;}int main(){ //keep a list of the queues std::vector<queue<int> > queues{ {{1, 2, 3}, 2}, {{1, 2, 3, 4}, 3}}; double total_data_rate = 0; for(auto q : queues) total_data_rate += q.data_rate; double data_to_process = 0; //how many refreshes we have to do int queue_number = 0; //which queue we are processing auto current_queue = &queues[0]; while(1) { data_to_process += time_passed() * total_data_rate; //data_to_process = ceil(data_to_process) //optional while(data_to_process >= 1){ //data_to_process >= 0 will make the the scheduler more //eager in the first time period (ie. everything will updated correctly //in the first period and and following periods if(current_queue->credit >= 1){ //don't change here though, since credit determines the weighting only, //not how many refreshes are made //refresh(current_queue.getNext(); std::cout << "From queue " << queue_number << " refreshed " << current_queue->getNext() << std::endl; current_queue->credit -= 1; data_to_process -= 1; } else { queue_number = (queue_number + 1) % queues.size(); current_queue = &queues[queue_number]; current_queue->credit += current_queue->data_rate; } } } return 0;}该示例现在应使用–std = c ++ 11在gcc上进行编译,并为您提供所需的内容。
这是测试用例的输出:(用于非时间缩放的早期代码)
Time: 0From queue 1 refreshed 1From queue 0 refreshed 1From queue 1 refreshed 2Time: 1From queue 0 refreshed 2From queue 0 refreshed 3From queue 1 refreshed 3Time: 2From queue 0 refreshed 1From queue 1 refreshed 4From queue 1 refreshed 1Time: 3From queue 0 refreshed 2From queue 0 refreshed 3From queue 1 refreshed 2Time: 4From queue 0 refreshed 1From queue 1 refreshed 3From queue 0 refreshed 2Time: 5From queue 0 refreshed 3From queue 1 refreshed 4From queue 1 refreshed 1
作为扩展,通过允许此调度程序仅完成前一个lcm(update_rate * lcm(… refresh rate
…),ceil(update_rate))步骤来回答重复模式问题,然后重复该模式。
还:实际上,有时由于小时限制的要求,这将无法解决。当我使用您无法解决的示例并修改time_passed以返回0.1时,将通过每1.1小时更新一次(而不是在小时界限内)来解决时间表。



