多机调度问题 scheduling problem of multicomputer

该问题作为一个NP hard 问题,属实引起了我的一点兴趣。

不过个人并不是数学强手,只能首先整理和收集大量的NP hard问题,以及寻求目前来说能够值得做的解法。

问题描述

​ 设有n个独立的作业{1, 2, …, n},由m台相同的机器{M1, M2, …, Mm}进行加工处理,作业i所需的处理时间为ti(1≤i≤n),每个作业均可在任何一台机器上加工处理,但不可间断、拆分。多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
​ 设7个独立作业{1, 2, 3, 4, 5, 6, 7}由3台机器{M1, M2, M3}加工处理,各作业所需的处理时间分别为{2, 14, 4, 16, 6, 5, 3}。

解法思路

目的是为了将三台机器的处理时间平均分配,理想情况则需要让每台机器的处理时间都大致接近单台机器处理所有任务的总时间的1/3,然而由于任务的随机性,并不能完美保证任务的分配能使每台机器都接近1/3。

那么则需要通过权重值判定每个任务应该交由哪一台处理器处理。

重点来了:一旦我们每台机器都有任务需要处理时,那么我们就应该优先将新的任务交给最先完成任务的处理机。

​ 那么任务有序的情况下,优先分配的工作一定是工时长的,后续分配的工作工时更短,则在处理机有任务时,分配更短的任务更容易保证:原本最先处理完任务的处理机被分配任务后不会突然遇到这样一个情况 “接到一个非常漫长的任务,而如果将先前的任务分配给其他处理机反而会更好”

​ 而通过将任务按照工时降序排列,并将处理机用优先队列存放,则是实现的最优方式。

解法步骤

  1. 通过降序排序先将任务排序好。
  2. 通过优先队列将多机分别存储,并以被占用时间升序为优先队列权重排序方式,被占用最少的优先出队,相同则先入队者出队。
  3. 依次从优先队列取出处理机,依次从有序任务列表中取出尚未处理的任务,并根据出队出列表的顺序依次将任务布置给处理机。

实现代码

待实现

Get Mode and Multiplicy in Collection

project3-2

具体实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int getMode(int nums[], int n, int* maxCount){
int i = 0;
*maxCount = 1;
int index = 0;
while(i < n - 1){
int tempCount = 1;
int j;
for(j = i; j < n - 1; j++){
if(nums[j] == nums[j+1]){
tempCount++;
}else{
break;
}
}
if(*maxCount < tempCount){
*maxCount = tempCount;
index = j;
}
i = ++j;
}
return index;
}

测试数据生成函数如下:

1
2
3
4
5
6
7
8
9
int* randomCollection(int n, int max){
srand(time(0));
int* coins = new int[n];
for(int i = 0; i < n; i++){
coins[i] = rand() % max;
}
return coins;
}

测试样例展示函数如下:

1
2
3
4
5
6
7
void printCollection(int coins[], int n){
cout << "[";
for(int i = 0; i < n - 1; i++){
cout << coins[i] << ",";
}
cout << coins[n-1] << "]" << endl;
}

测试主函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;

int main()
{
int count = 300, max = 500, maxCount = 0;
int* list = randomCollection(count, max);
printCollection(list, count);
sort(list, list + count);
printCollection(list, count);
cout << "the Mode is:" << list[getMode(list, count, &maxCount)] << ", the Multiplicity is:" << maxCount << endl;
return 0;
}

生成测试结果展示

1
2
3
4
5
$g++ -o main *.cpp
$main
[120,138,326,318,484,329,431,476,26,11,442,158,184,142,332,381,321,205,278,40,492,415,292,205,68,96,188,209,260,4,355,232,142,33,50,126,363,333,454,241,345,248,251,29,390,84,263,64,289,41,104,133,456,396,339,376,493,379,85,105,383,293,189,25,326,91,4,41,425,310,282,122,59,34,151,301,470,414,365,259,308,322,244,116,70,435,493,415,314,430,372,197,223,61,75,402,5,79,295,430,389,78,404,300,464,55,454,434,322,319,45,482,493,141,98,64,77,443,331,391,374,204,441,449,117,16,203,122,447,499,404,188,429,308,341,393,216,295,179,38,466,76,20,460,69,470,376,146,414,59,390,140,263,331,89,233,199,145,207,498,144,464,38,73,272,379,318,340,174,349,230,493,277,102,305,346,73,33,493,339,92,383,479,208,66,420,441,117,65,0,115,61,464,153,134,89,385,304,429,59,153,160,404,430,114,209,129,39,242,122,378,187,357,209,395,275,482,188,392,399,188,359,461,153,12,447,94,249,252,23,161,405,35,65,188,2,127,317,41,221,291,420,408,148,481,155,423,463,343,167,363,384,26,176,389,390,123,483,140,375,358,301,133,246,366,321,248,345,490,289,67,281,61,475,281,43,483,56,6,326,223,221,62,249,397,303,139,21,286,131,248,497,432,381,243,151,54,491,496,396]
[0,2,4,4,5,6,11,12,16,20,21,23,25,26,26,29,33,33,34,35,38,38,39,40,41,41,41,43,45,50,54,55,56,59,59,59,61,61,61,62,64,64,65,65,66,67,68,69,70,73,73,75,76,77,78,79,84,85,89,89,91,92,94,96,98,102,104,105,114,115,116,117,117,120,122,122,122,123,126,127,129,131,133,133,134,138,139,140,140,141,142,142,144,145,146,148,151,151,153,153,153,155,158,160,161,167,174,176,179,184,187,188,188,188,188,188,189,197,199,203,204,205,205,207,208,209,209,209,216,221,221,223,223,230,232,233,241,242,243,244,246,248,248,248,249,249,251,252,259,260,263,263,272,275,277,278,281,281,282,286,289,289,291,292,293,295,295,300,301,301,303,304,305,308,308,310,314,317,318,318,319,321,321,322,322,326,326,326,329,331,331,332,333,339,339,340,341,343,345,345,346,349,355,357,358,359,363,363,365,366,372,374,375,376,376,378,379,379,381,381,383,383,384,385,389,389,390,390,390,391,392,393,395,396,396,397,399,402,404,404,404,405,408,414,414,415,415,420,420,423,425,429,429,430,430,430,431,432,434,435,441,441,442,443,447,447,449,454,454,456,460,461,463,464,464,464,466,470,470,475,476,479,481,482,482,483,483,484,490,491,492,493,493,493,493,493,496,497,498,499]
the Crowd is:188, the Multiplicity is:5

comparison of BiTree

递归对比二叉链结构的二叉树

数据结构如下:

1
2
3
4
5
template<class T>
struct Node {
T data;
Node* lchild, * rchild;
};

实际方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
using namespace std;

bool isEqual(Node<int>* bt1, Node<int>* bt2) {
if (bt1 == NULL && bt2 == NULL)//正确的出口
return true;
else if (bt1 == NULL || bt2 == NULL)
return false;
else {
cout << bt1->data << "," << bt2->data << endl;
if (bt1->data != bt2->data)
return false;
return isEqual(bt1->lchild, bt2->lchild) && isEqual(bt1->rchild, bt2->rchild);
}
}

生成测试二叉树函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//创建二叉树
//根据平衡二叉树规则生成
Node<int>* CreateBTtree(int a[], int n)
{
Node<int>* root, * c, * pa = NULL, * p;
int i;
root = new Node<int>;
root->data = a[0];
root->lchild = root->rchild = NULL;
for (i = 1; i < n; i++)
{
p = new Node<int>;
p->lchild = p->rchild = NULL;
p->data = a[i];
c = root;
while (c)
{
pa = c;
if (c->data < p->data) //根节点小于待插入节点
c = c->rchild; //往右遍历
else //根节点大于待插入节点
c = c->lchild; //往左遍历
}
if (pa->data < p->data)
pa->rchild = p; //右放
else
pa->lchild = p; //左放
}
return root; //返回根节点
}

测试函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void test() {
int a[8] = { 5, 3, 7, 2, 4, 6, 8, 9 };
int b[8] = { 5, 3, 7, 2, 4, 6, 8, 15 };
int c[7] = { 5, 3, 7, 2, 4, 6, 8 };
int d[8] = { 5, 3, 7, 2, 4, 6, 8, 1 };
Node<int>* bt1 = CreateBTtree(a, 8);
Node<int>* bt2 = CreateBTtree(a, 8);
Node<int>* bt3 = CreateBTtree(b, 8);
Node<int>* bt4 = CreateBTtree(c, 7);
Node<int>* bt5 = CreateBTtree(d, 8);
cout << "A and B Equal or Not : " << (isEqual(bt1, bt2) ? "Equal" : "Not Equal") << endl;
cout << "A and C Equal or Not : " << (isEqual(bt1, bt3) ? "Equal" : "Not Equal") << endl;
cout << "A and D Equal or Not : " << (isEqual(bt1, bt4) ? "Equal" : "Not Equal") << endl;
cout << "A and E Equal or Not : " << (isEqual(bt1, bt5) ? "Equal" : "Not Equal") << endl;
}

输出测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//output
5,5
3,3
2,2
4,4
7,7
6,6
8,8
9,15
A and C Equal or Not : Not Equal
5,5
3,3
2,2
4,4
7,7
6,6
8,8
9,empty
the nodes count not equal
A and D Equal or Not : Not Equal
5,5
3,3
2,2
empty,1
the nodes count not equal
A and E Equal or Not : Not Equal

G:\GithubProjects\C++\TrashCodes\Debug\TrashCodes.exe (进程 17836)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .