文章目录
源码如下:
#include "iostream"
#include "vector"
#include "map"
#include "unordered_map"
#include "ctime"
#include "string"
#include "algorithm"
#include "time.h"
#include "stdio.h"
#include "limits.h"
#include "string.h"
using namespace std;
#define min(a, b) ((a) < (b) ? (a) : (b))
class SeversModel { /* 所有服务器信息类 */
public:
//string model; /* 服务器型号 */
int cpu_A; /* 节点A的cpu核数 */
int cpu_B; /* 节点B的cpu核数 */
int momery_A; /* 节点A的内存容量 */
int momery_B; /* 节点B的内存容量 */
int price; /* 服务器价格 */
int energyConsumption; /* 服务器每日能耗 */
int pre_id;
int cur_id; /* 服务器id */
map<int, int> VmId;
};
map<string, SeversModel> Severs; /* 所有服务器 */
multimap<string, SeversModel> localSevers; /* 本地服务器 */
class VirtualMachineModel { /* 所有虚拟机信息类 */
public:
string model; /* 虚拟机型号 */
int cpu; /* cpu核数 */
int momery; /* 内存容量 */
int node; /* 节点方式0:单节点、1:双节点 */
int id; /* 虚拟机id */
int mountedSeverId; /* 虚拟机挂载的服务器id */
char mountedSeverNode; /* 虚拟机挂载的服务器节点:A、B、N(表示虚拟机为双节点部署) */
string mountedSeverModel;
};
map<string, VirtualMachineModel> VirtualMachines; /* 所有虚拟机 */
multimap<int, VirtualMachineModel> localVirtualMachines; /* 本地虚拟机 */
class curDayPurchasedSeversMessage { /* 当天购买的服务器信息、按照型号排序 */
public:
string model;
int nums;
};
class curDayPurchasedSeversMessageById { /* 当天购买的服务器信息、按照型号、id进行排序 */
public:
//string model;
int pre_id;
int cur_id;
};
class curDayAddedVirtualMachinesMessage { /* 当天添加的虚拟机信息 */
public:
int mountedSeverId;
char mountedSeverNode;
string vmModel;
string severModel;
int flag;
};
class operation {
public:
string model;
int id;
};
class migrationVM {
public:
int flag;
int destSeverId;
char destSeverNode;
};
/* 按照本地虚拟机挂载的服务器id进行升序排序 */
typedef pair<int, curDayAddedVirtualMachinesMessage> PAIR2;
bool cmp_by_added_seq(const PAIR2& lhs, const PAIR2& rhs) {
return lhs.second.flag < rhs.second.flag;
}
/* 按照本地服务器的价格进行升序排序 */
typedef pair<string, SeversModel> PAIR3;
bool cmp_by_sever_cap(const PAIR3& lhs, const PAIR3& rhs) {
if ((lhs.second.cpu_A + lhs.second.cpu_B) == (rhs.second.cpu_A + rhs.second.cpu_B)) {
return (lhs.second.momery_A + lhs.second.momery_B) < (rhs.second.momery_A + rhs.second.momery_B);
} else {
return (lhs.second.cpu_A + lhs.second.cpu_B) < (rhs.second.cpu_A + rhs.second.cpu_B);
}
}
/* 按照迁移虚拟机顺序升序排序 */
typedef pair<int, migrationVM> PAIR4;
bool cmp_by_migration_seq(const PAIR4& lhs, const PAIR4& rhs) {
return lhs.second.flag < rhs.second.flag;
}
int severNums = 0; /* 服务器数量 */
int virtualMachineNums = 0; /* 虚拟机数量 */
int requestDays = 0; /* 请求的天数 */
int size = 1024; /* 字符串缓冲区大小 */
int severId = 0; /* 本地服务器id */
//long long totalCost = 0;
// /* 本地服务器挂载的所有虚拟机 */
// multimap<int, int> localSeverId_VmId;
/* 添加虚拟机到本地服务器 */
void addVirtualMachine(int &flag, string model, int id,
multimap<string, curDayPurchasedSeversMessage>&curDayPurchasedSevers,
multimap<string, SeversModel>&curDayPurchasedSeversByModel,
unordered_map<int, curDayAddedVirtualMachinesMessage>&curDayAddedVirtualMachines,
multimap<int, curDayAddedVirtualMachinesMessage>&curDayAddedVirtualMachinesBySeverId,
multimap<int, int>&SeverId_VmId) {
//1、找到这台虚拟机信息记录下来
int curVirtualMachineCpu = 0; /* 当前要添加的虚拟机的cpu核数 */
int curVirtualMachineMomery = 0; /* 当前要添加的虚拟机的momery大小 */
int curVirtualMachineNode = -1; /* 当前要添加的虚拟机的节点方式 */
map<string, VirtualMachineModel>::iterator pos = VirtualMachines.find(model);
if (pos != VirtualMachines.end()) {
curVirtualMachineCpu = pos->second.cpu;
curVirtualMachineMomery = pos->second.momery;
curVirtualMachineNode = pos->second.node;
}
//2.1、判断本地服务器中是否有可以容纳此台虚拟机得服务器
string matchedSeverModel = "**"; /* 新增虚拟机匹配服务器的型号 */
int matchedSeverId = -1; /* 新增虚拟机匹配的服务器的id */
int matchedSeverPrice = INT_MAX; /* 新增虚拟机匹配的服务器成本价格 */
int matchedSeverEnergyConsumption = INT_MAX; /* 新增虚拟机匹配的服务器能耗价格 */
char matchedMountedSeverNode = 'N'; /* 新增虚拟机的节点方式 */
string matchedMountedSeverModel = "**";
int matchedSeverCpu = INT_MAX;
int matchedSeverCpu_A = INT_MAX;
int matchedSeverCpu_B = INT_MAX;
int matchedSeverMomery = INT_MAX;
int matchedSeverMomery_A = INT_MAX;
int matchedSeverMomery_B = INT_MAX;
for (auto pos = localSevers.begin(); pos != localSevers.end(); pos++) {
int smallCpu = min(pos->second.cpu_A, pos->second.cpu_B);
int smallMomery = min(pos->second.momery_A, pos->second.momery_B);
if (curVirtualMachineNode == 0 ) { /* 单节点 */
if (pos->second.cpu_A > pos->second.cpu_B
&& pos->second.momery_A > pos->second.momery_B
&& pos->second.cpu_A >= curVirtualMachineCpu
&& pos->second.momery_A >= curVirtualMachineMomery) { /* 节点A剩余空间多 */
//存储此节点所在服务器得能耗、id
if (pos->second.cpu_A < matchedSeverCpu_A
&& pos->second.momery_A < matchedSeverMomery_A
&& pos->second.price < matchedSeverPrice) { /* 先考虑成本价格,成本价格低就选 */
matchedSeverModel = pos->first;
matchedSeverId = pos->second.cur_id;
matchedSeverPrice = pos->second.price;
matchedSeverCpu_A = pos->second.cpu_A;
matchedSeverMomery_A = pos->second.momery_A;
matchedSeverEnergyConsumption = pos->second.energyConsumption;
matchedMountedSeverNode = 'A';
matchedMountedSeverModel = pos->first;
//break;
}
} else if (pos->second.cpu_A <= pos->second.cpu_B
&& pos->second.momery_A <= pos->second.momery_B
&& pos->second.cpu_B >= curVirtualMachineCpu
&& pos->second.momery_B >= curVirtualMachineMomery) { /* 节点B剩余空间多 */
//存储此节点所在服务器得能耗、id
if (pos->second.cpu_B < matchedSeverCpu_B
&& pos->second.momery_B < matchedSeverMomery_B
&& pos->second.price < matchedSeverPrice) { /* 先考虑成本价格,成本价格低就选 */
matchedSeverModel = pos->first;
matchedSeverId = pos->second.cur_id;
matchedSeverPrice = pos->second.price;
matchedSeverCpu_B = pos->second.cpu_B;
matchedSeverMomery_B = pos->second.momery_B;
matchedSeverEnergyConsumption = pos->second.energyConsumption;
matchedMountedSeverNode = 'B';
matchedMountedSeverModel = pos->first;
//break;
}
}
} else { /* 双节点 */
if (smallCpu >= curVirtualMachineCpu / 2
&& smallMomery >= curVirtualMachineMomery / 2
&& smallCpu <= matchedSeverCpu
&& smallMomery <= matchedSeverMomery
&& pos->second.price < matchedSeverPrice) { /* 先考虑成本价格,成本价格低就选 */
//存储此节点所在服务器得能耗、id
matchedSeverModel = pos->first;
matchedSeverId = pos->second.cur_id;
matchedSeverPrice = pos->second.price;
matchedSeverCpu = smallCpu;
matchedSeverMomery = smallMomery;
matchedSeverEnergyConsumption = pos->second.energyConsumption;
matchedMountedSeverNode = 'N';
matchedMountedSeverModel = pos->first;
//break;
}
}
}
//2.2、本地服务器中有满足条件的服务器,进行处理即可
if (matchedSeverId != -1) {
//将本地虚拟机链表更新
VirtualMachineModel vm;
vm.model = model;
vm.cpu = curVirtualMachineCpu;
vm.momery = curVirtualMachineMomery;
vm.node = curVirtualMachineNode;
vm.id = id;
vm.mountedSeverId = matchedSeverId;
vm.mountedSeverNode = matchedMountedSeverNode;
vm.mountedSeverModel = matchedMountedSeverModel;
localVirtualMachines.insert(make_pair(id, vm));
SeverId_VmId.insert(make_pair(matchedSeverId, id));
//localSeverId_VmId.insert(make_pair(matchedSeverId, id));
/* 记录这一次添加的虚拟机信息 */
curDayAddedVirtualMachinesMessage tmpVirtualMachines;
tmpVirtualMachines.mountedSeverId = matchedSeverId;
tmpVirtualMachines.mountedSeverNode = matchedMountedSeverNode;
tmpVirtualMachines.flag = flag++;
tmpVirtualMachines.vmModel = model;
tmpVirtualMachines.severModel = matchedMountedSeverModel;
curDayAddedVirtualMachines.insert(make_pair(id, tmpVirtualMachines));
/* 记录这一次添加的虚拟机信息,通过对应服务器id排序 */
curDayAddedVirtualMachinesBySeverId.insert(make_pair(matchedSeverId, tmpVirtualMachines));
//将本地服务器链表更新
/* 先找到本地服务器列表中这台服务器型号排列第一个位置,在我那个下面开始查找 */
multimap<string, SeversModel>::iterator pos = localSevers.find(matchedSeverModel);
for (; pos != localSevers.end(); pos++) {
if ((matchedSeverId % 100) != (pos->second.cur_id % 100)) {
continue;
}
if (pos->second.cur_id == matchedSeverId) {
pos->second.VmId.insert(make_pair(id, -1));
if (matchedMountedSeverNode == 'A') {
pos->second.cpu_A -= curVirtualMachineCpu;
pos->second.momery_A -= curVirtualMachineMomery;
} else if (matchedMountedSeverNode == 'B') {
pos->second.cpu_B -= curVirtualMachineCpu;
pos->second.momery_B -= curVirtualMachineMomery;
} else {
pos->second.cpu_A -= curVirtualMachineCpu / 2;
pos->second.cpu_B -= curVirtualMachineCpu / 2;
pos->second.momery_A -= curVirtualMachineMomery / 2;
pos->second.momery_B -= curVirtualMachineMomery / 2;
}
/* 更新完服务器容量就退出 */
return;
}
}
}
//3.1、本地服务器中没有匹配的服务器,需要购买,查找合适的服务器
matchedSeverCpu = 0;
matchedSeverMomery = 0;
/* 本地买过的服务器中没有满足条件的,需要重新购买 */
for (auto pos = Severs.begin(); pos != Severs.end(); pos++) {
if (curVirtualMachineNode == 0) { /* 单节点 */
if (pos->second.cpu_A >= curVirtualMachineCpu
&& pos->second.momery_A >= curVirtualMachineMomery
&& pos->second.price < matchedSeverPrice) { /* 先考虑成本价格,成本价格低就选 */
//存储此节点所在服务器得能耗、id
matchedSeverCpu = pos->second.cpu_A * 2;
matchedSeverMomery = pos->second.momery_A * 2;
matchedSeverModel = pos->first;
matchedSeverId = pos->second.cur_id;
matchedSeverPrice = pos->second.price;
matchedSeverEnergyConsumption = pos->second.energyConsumption;
matchedMountedSeverNode = 'A';
matchedMountedSeverModel = pos->first;
//break;
}
} else { /* 双节点 */
if (pos->second.cpu_A >= curVirtualMachineCpu / 2
&& pos->second.momery_A >= curVirtualMachineMomery / 2
&& pos->second.price < matchedSeverPrice) { /* 先考虑成本价格,成本价格低就选 */
//存储此节点所在服务器得能耗、id
matchedSeverCpu = pos->second.cpu_A * 2;
matchedSeverMomery = pos->second.momery_A * 2;
matchedSeverModel = pos->first;
matchedSeverId = pos->second.cur_id;
matchedSeverPrice = pos->second.price;
matchedSeverEnergyConsumption = pos->second.energyConsumption;
matchedMountedSeverNode = 'N';
matchedMountedSeverModel = pos->first;
//break;
}
}
}
//将本地服务器链表更新
SeversModel s;
s.cpu_A = matchedSeverCpu / 2;
s.cpu_B = matchedSeverCpu / 2;
s.momery_A = matchedSeverMomery / 2;
s.momery_B = matchedSeverMomery / 2;
s.price = matchedSeverPrice;
s.energyConsumption = matchedSeverEnergyConsumption;
s.pre_id = -2;
s.cur_id = severId++;
s.VmId.insert(make_pair(id, -1));
matchedSeverId = s.cur_id; /* 这里需要将当前添加虚拟机匹配的服务器id更新,后面更新当天添加的虚拟机时会用到 */
//totalCost += matchedSeverPrice;
/* 更新服务器的容量 */
if (matchedMountedSeverNode == 'A') {
s.cpu_A -= curVirtualMachineCpu;
s.momery_A -= curVirtualMachineMomery;
} else if (matchedMountedSeverNode == 'B') {
s.cpu_B -= curVirtualMachineCpu;
s.momery_B -= curVirtualMachineMomery;
} else {
s.cpu_A -= curVirtualMachineCpu / 2;
s.cpu_B -= curVirtualMachineCpu / 2;
s.momery_A -= curVirtualMachineMomery / 2;
s.momery_B -= curVirtualMachineMomery / 2;
}
localSevers.insert(make_pair(matchedSeverModel, s));
curDayPurchasedSeversByModel.insert(make_pair(matchedSeverModel, s));
/* 记录这一次购买的服务器信息,记录此型号服务器当天购买的数量 */
auto pos1 = curDayPurchasedSevers.find(matchedSeverModel);
if (pos1 != curDayPurchasedSevers.end()) { /* 此台服务器当天已经买过了 */
pos1->second.nums++;
} else {
curDayPurchasedSeversMessage tmpSevers;
tmpSevers.model = matchedSeverModel;
tmpSevers.nums = 1;
curDayPurchasedSevers.insert(make_pair(matchedSeverModel, tmpSevers));
}
//将本地虚拟机链表更新
VirtualMachineModel vm1;
vm1.model = model;
vm1.cpu = curVirtualMachineCpu;
vm1.momery = curVirtualMachineMomery;
vm1.node = curVirtualMachineNode;
vm1.id = id;
vm1.mountedSeverId = matchedSeverId;
vm1.mountedSeverNode = matchedMountedSeverNode;
vm1.mountedSeverModel = matchedMountedSeverModel;
localVirtualMachines.insert(make_pair(id, vm1));
SeverId_VmId.insert(make_pair(matchedSeverId, id));
//localSeverId_VmId.insert(make_pair(matchedSeverId, id));
/* 记录这一次添加的虚拟机信息,按照虚拟机id排序的 */
curDayAddedVirtualMachinesMessage tmp1VirtualMachines;
tmp1VirtualMachines.mountedSeverId = matchedSeverId;
tmp1VirtualMachines.mountedSeverNode = matchedMountedSeverNode;
tmp1VirtualMachines.vmModel = model;
tmp1VirtualMachines.flag = flag++;
tmp1VirtualMachines.severModel = matchedMountedSeverModel;
curDayAddedVirtualMachines.insert(make_pair(id, tmp1VirtualMachines));
/* 记录这一次添加的虚拟机信息,按照对应服务器id排序 */
curDayAddedVirtualMachinesBySeverId.insert(make_pair(matchedSeverId, tmp1VirtualMachines));
}
/* 删除本地服务器中的的当前虚拟机 */
void delVirtualMachine(int id) {
int curVirtualMachineCpu = 0; /* 当前要删除的虚拟机的cpu核数 */
int curVirtualMachineMomery = 0; /* 当前要删除的虚拟机的momery大小 */
int curVirtualMachineMountedSeverId = -1; /* 当前要删除的虚拟机挂载的服务器id */
char curVirtualMachineMountedSeverNode = 'N'; /* 当前要删除的虚拟机挂载的服务器节点:A、B、N(表示虚拟机为双节点部署) */
string curVirtualMachineMountedSeverModel = "**";
//1、根据虚拟机id找到其位置,删除本地虚拟机链表中的虚拟机节点
multimap<int, VirtualMachineModel>::iterator posvm = localVirtualMachines.find(id);
if (posvm != localVirtualMachines.end()) {
curVirtualMachineCpu = posvm->second.cpu;
curVirtualMachineMomery = posvm->second.momery;
curVirtualMachineMountedSeverId = posvm->second.mountedSeverId;
curVirtualMachineMountedSeverNode = posvm->second.mountedSeverNode;
curVirtualMachineMountedSeverModel = posvm->second.mountedSeverModel;
localVirtualMachines.erase(id);
}
// /* 删除服务器、虚拟机哈希表中的对应元素 */
// auto it = localSeverId_VmId.find(curVirtualMachineMountedSeverId);
// for (; it != localSeverId_VmId.end(); it++) {
// if (it->second == id) {
// localSeverId_VmId.erase(it);
// break;
// }
// }
//2、恢复虚拟机对应服务器的cpu、momery
auto pos = localSevers.find(curVirtualMachineMountedSeverModel);
for (; pos != localSevers.end(); pos++) {
if ((curVirtualMachineMountedSeverId % 100) != (pos->second.cur_id % 100)) {
continue;
}
if (pos->second.cur_id == curVirtualMachineMountedSeverId) {
pos->second.VmId.erase(id);
if (curVirtualMachineMountedSeverNode == 'A') { /* 要删除虚拟机部署在当前服务器的A节点 */
pos->second.cpu_A += curVirtualMachineCpu;
pos->second.momery_A += curVirtualMachineMomery;
} else if (curVirtualMachineMountedSeverNode == 'B') { /* 要删除虚拟机部署在当前服务器的B节点 */
pos->second.cpu_B += curVirtualMachineCpu;
pos->second.momery_B += curVirtualMachineMomery;
} else { /* 要删除虚拟机部署在当前服务器双节点上 */
pos->second.cpu_A += curVirtualMachineCpu / 2;
pos->second.cpu_B += curVirtualMachineCpu / 2;
pos->second.momery_A += curVirtualMachineMomery / 2;
pos->second.momery_B += curVirtualMachineMomery / 2;
}
break;
}
}
}
void readSever(map<string, SeversModel>&msevers) {
for (int sum = 0; sum < severNums; sum++) {
SeversModel severs;
string model;
char* model1 = (char *)malloc(size);
/* 1、读取服务器型号 */
char *buff = (char *)malloc(size);
if (scanf("%s", buff));
bool b = false;
int i = 0;
char *name0 = (char *)malloc(size);
for (int addr = 0; buff[addr] != '\0'; addr++) { //遍历字符串,赋给结构体
if (buff[addr] == ',' && b) {
b = false;
name0[i] = '\0';
//severs[sum].model = name0;
model1 = name0;
i = 0;
break;
} else if (addr == '\0') {
b = true;
continue;
}
if (b) {
name0[i++] = buff[addr];
}
}
free(buff);
/* 2、读取服务器cpu、内存、价格、能耗 */
int a, b1, c, d;
if (scanf("%d, %d, %d, %d", &a, &b1, &c, &d));
severs.cpu_A = a / 2;
severs.cpu_B = a / 2;
severs.momery_A = b1 / 2;
severs.momery_B = b1 / 2;
severs.price = c;
severs.energyConsumption = d;
severs.pre_id = -2;
severs.cur_id = -1;
model = model1;
msevers.insert(make_pair(model, severs));
free(model1);
/*3、读取剩余字符:) */
char *buffer = (char *)malloc(size);
if (scanf("%s", buffer));
free(buffer);
}
}
void readVirtualMachine(map<string, VirtualMachineModel>&mvirtualmachines) {
for (int sum = 0; sum < virtualMachineNums; sum++) {
VirtualMachineModel virtualmachines;
string model;
char* model1 = (char *)malloc(size);
/* 1、读取虚拟机型号 */
char *buff = (char *)malloc(size);
if (scanf("%s", buff));
bool b = false;
int i = 0;
char *name0 = (char *)malloc(size);
for (int addr = 0; buff[addr] != '\0'; addr++) { //遍历字符串,赋给结构体
if (buff[addr] == ',' && b) {
b = false;
name0[i] = '\0';
model1 = name0;
i = 0;
break;
} else if (addr == 0) {
b = true;
continue;
}
if (b) {
name0[i++] = buff[addr];
}
}
free(buff);
/* 2、读取虚拟机cpu、内存、节点方式 */
int a, b1, c;
if (scanf("%d, %d, %d", &a, &b1, &c));
virtualmachines.cpu = a;
virtualmachines.momery = b1;
virtualmachines.node = c;
virtualmachines.id = -1;
virtualmachines.mountedSeverId = -1;
virtualmachines.mountedSeverNode = 'N';
model = model1;
mvirtualmachines.insert(make_pair(model, virtualmachines));
free(model1);
/* 3、读取剩余字符:) */
char *buffer = (char *)malloc(size);
if (scanf("%s", buffer));
free(buffer);
}
}
/* 迁移虚拟机 */
void migrationVirtualMachines(int &flag1, int day, int* migrationVmNums, unordered_map<int, migrationVM>&MigrationResults) {
/* 每天可以迁移的虚拟机数量不超过当前虚拟机存量的千分之五,既:5n/1000 向下取整 */
//cout << "day[" << day << "]: migrationVmNums = " << *migrationVmNums << endl;
if (*migrationVmNums == 0) { /* 可迁移次数为0,直接返回 */
return;
}
//cout << "migrationVirtualMachines 1" << endl;
//把本地服务器按cpu、momery剩余容量降序排序
vector<PAIR3> cmp_severCap(localSevers.begin(), localSevers.end());
sort(cmp_severCap.begin(),cmp_severCap.end(), cmp_by_sever_cap);
int sortFlag_L = 0, sortFlag_R = cmp_severCap.size();
for (int index1 = sortFlag_R - 1; index1 >= sortFlag_L; index1--) {
//cout << "migrationVirtualMachines 2" << endl;
//找到当前剩余容量最大的一台服务器
string curSeverModel = cmp_severCap[index1].first;
int curSeverId = cmp_severCap[index1].second.cur_id;
// //找到这台服务器中的挂载的所有虚拟机
// auto itL = localSeverId_VmId.find(curSeverId);
// int vmnums = localSeverId_VmId.count(curSeverId);
//依次迁移每一台虚拟机
auto itFindVmId = cmp_severCap[index1].second.VmId.begin();
for (; itFindVmId !=cmp_severCap[index1].second.VmId.end(); itFindVmId++) {
//for (auto it = localVirtualMachines.begin(); it != localVirtualMachines.end(); it++) {
//if (it->second.mountedSeverId == curSeverId) {
//for (int i = 0; (itL != localSeverId_VmId.end()) && (i < vmnums); itL++, i++) {
//cout << "migrationVirtualMachines 3" << endl;
//找到当前虚拟机,记录其信息
auto curVm = localVirtualMachines.find(itFindVmId->first);
int curVmId = curVm->second.id;
int curVmCpu = curVm->second.cpu;
int curVmMomery = curVm->second.momery;
string curVmMountedSeverModel = curVm->second.mountedSeverModel;
char curVmMountedSeverNode = curVm->second.mountedSeverNode;
int curVmNode = curVm->second.node;
//依次查找剩余容量较小的服务器,将此台虚拟机迁移过去
for (int index2 = sortFlag_L; index2 < index1; index2++) {
//cout << "migrationVirtualMachines 4" << endl;
string destSeverModel = cmp_severCap[index2].first;
int destSeverId = cmp_severCap[index2].second.cur_id;
if (curVmNode == 0) { //当前虚拟机为单节点部署
//cout << "migrationVirtualMachines 5" << endl;
if (cmp_severCap[index2].second.cpu_A >= curVmCpu
&& cmp_severCap[index2].second.momery_A >= curVmMomery) {
//cout << "migrationVirtualMachines 6" << endl;
//更新源服务器信息
auto srcSeverL = localSevers.find(curSeverModel);
int count1 = localSevers.count(curSeverModel);
for (int i = 0; (i < count1) && (srcSeverL != localSevers.end()); srcSeverL++, i++) {
if ((srcSeverL->second.cur_id % 100) != (curSeverId % 100)) {
i++;
continue;
}
if (srcSeverL->second.cur_id == curSeverId) {
if (curVmMountedSeverNode == 'A') {
srcSeverL->second.cpu_A += curVmCpu;
srcSeverL->second.momery_A += curVmMomery;
//更新当前排序后cmp_severCap中源服务器的容量
cmp_severCap[index1].second.cpu_A += curVmCpu;
cmp_severCap[index1].second.momery_A += curVmMomery;
break;
} else if (curVmMountedSeverNode == 'B') {
srcSeverL->second.cpu_B += curVmCpu;
srcSeverL->second.momery_B += curVmMomery;
//更新当前排序后cmp_severCap中源服务器的容量
cmp_severCap[index1].second.cpu_B += curVmCpu;
cmp_severCap[index1].second.momery_B += curVmMomery;
break;
}
}
}
//更新目的服务器
auto destSeverL = localSevers.find(destSeverModel);
int count2 = localSevers.count(destSeverModel);
for (int i = 0; (i < count2) && (destSeverL != localSevers.end()); destSeverL++, i++) {
if ((destSeverL->second.cur_id % 100) != (destSeverId % 100)) {
i++;
continue;
}
if (destSeverL->second.cur_id == destSeverId) {
destSeverL->second.cpu_A -= curVmCpu;
destSeverL->second.momery_A -= curVmMomery;
//更新当前排序后cmp_severCap中目的服务器的容量
cmp_severCap[index2].second.cpu_A -= curVmCpu;
cmp_severCap[index2].second.momery_A -= curVmMomery;
break;
}
}
//更新本地虚拟机信息
auto posVm = localVirtualMachines.find(curVmId);
if (posVm != localVirtualMachines.end()) {
posVm->second.mountedSeverId = destSeverId;
posVm->second.mountedSeverModel = destSeverModel;
posVm->second.mountedSeverNode = 'A';
}
//更新服务器挂载虚拟机信息
// auto posSeverVm = localSeverId_VmId.find(curSeverId);
// for (; posSeverVm != localSeverId_VmId.end(); posSeverVm++) {
// if ((posSeverVm->second % 100) != (curVmId % 100)) {
// continue;
// }
// if (posSeverVm->second == curVmId) {
// localSeverId_VmId.erase(posSeverVm);
// break;
// }
// }
// localSeverId_VmId.insert(make_pair(destSeverId, curVmId));
//更新返回信息,迁移的虚拟机id,目的服务器id、目的服务器节点(0:A、1:B、2:N)
migrationVM destSeverInfo;
destSeverInfo.destSeverId = destSeverId;
destSeverInfo.flag = flag1++;
destSeverInfo.destSeverNode = 'A';
MigrationResults.insert(make_pair(curVmId, destSeverInfo));
(*migrationVmNums)--;
if (*migrationVmNums == 0) { //迁移虚拟机数量到达限制,直接返回
return;
}
break;
} else if (cmp_severCap[index2].second.cpu_B >= curVm->second.cpu
&& cmp_severCap[index2].second.momery_B >= curVm->second.momery) {
// cout << "migrationVirtualMachines 7" << endl;
//更新源服务器信息
auto srcSeverL = localSevers.find(curSeverModel);
int count3 = localSevers.count(curSeverModel);
for (int i = 0; (i < count3) && (srcSeverL != localSevers.end()); srcSeverL++, i++) {
if (srcSeverL->second.cur_id == curSeverId) {
if ((srcSeverL->second.cur_id % 100) != (curSeverId % 100)) {
i++;
continue;
}
if (curVmMountedSeverNode == 'A') {
srcSeverL->second.cpu_A += curVmCpu;
srcSeverL->second.momery_A += curVmMomery;
//更新当前排序后cmp_severCap中源服务器的容量
cmp_severCap[index1].second.cpu_A += curVmCpu;
cmp_severCap[index1].second.momery_A += curVmMomery;
break;
} else if (curVmMountedSeverNode == 'B') {
srcSeverL->second.cpu_B += curVmCpu;
srcSeverL->second.momery_B += curVmMomery;
//更新当前排序后cmp_severCap中源服务器的容量
cmp_severCap[index1].second.cpu_B += curVmCpu;
cmp_severCap[index1].second.momery_B += curVmMomery;
break;
}
}
}
//更新目的服务器
auto destSeverL = localSevers.find(destSeverModel);
int count4 = localSevers.count(destSeverModel);
for (int i = 0; (i < count4) && (destSeverL != localSevers.end()); destSeverL++, i++) {
if ((destSeverL->second.cur_id % 100) != (destSeverId % 100)) {
i++;
continue;
}
if (destSeverL->second.cur_id == destSeverId) {
destSeverL->second.cpu_B -= curVmCpu;
destSeverL->second.momery_B -= curVmMomery;
//更新当前排序后cmp_severCap中目的服务器的容量
cmp_severCap[index2].second.cpu_B -= curVmCpu;
cmp_severCap[index2].second.momery_B -= curVmMomery;
break;
}
}
//更新本地虚拟机信息
auto posVm = localVirtualMachines.find(curVmId);
if (posVm != localVirtualMachines.end()) {
posVm->second.mountedSeverId = destSeverId;
posVm->second.mountedSeverModel = destSeverModel;
posVm->second.mountedSeverNode = 'B';
}
// //更新服务器挂载虚拟机信息
// auto posSeverVm = localSeverId_VmId.find(curSeverId);
// for (; posSeverVm != localSeverId_VmId.end(); posSeverVm++) {
// if ((posSeverVm->second % 100) != (curVmId % 100)) {
// i++;
// continue;
// }
// if (posSeverVm->second == curVmId) {
// localSeverId_VmId.erase(posSeverVm);
// break;
// }
// }
// localSeverId_VmId.insert(make_pair(destSeverId, curVmId));
migrationVM destSeverInfo;
destSeverInfo.destSeverId = destSeverId;
destSeverInfo.flag = flag1++;
destSeverInfo.destSeverNode = 'B';
MigrationResults.insert(make_pair(curVmId, destSeverInfo));
(*migrationVmNums)--;
if (*migrationVmNums == 0) { //迁移虚拟机数量到达限制,直接返回
return;
}
break;
}
} else { //当前虚拟机为双节点部署
//cout << "migrationVirtualMachines 8" << endl;
int smallDestSeverCpu = min(cmp_severCap[index2].second.cpu_A, cmp_severCap[index2].second.cpu_B);
int smallDestSeverMomery = min(cmp_severCap[index2].second.momery_A, cmp_severCap[index2].second.momery_B);
if (smallDestSeverCpu >= curVmCpu / 2
&& smallDestSeverMomery >= curVmMomery / 2) {
//cout << "migrationVirtualMachines 9" << endl;
//更新源服务器信息
auto srcSeverL = localSevers.find(curSeverModel);
int count5 = localSevers.count(curSeverModel);
for (int i = 0; (i < count5) && (srcSeverL != localSevers.end()); srcSeverL++, i++) {
if ((srcSeverL->second.cur_id % 100) != (curSeverId % 100)) {
i++;
continue;
}
if (srcSeverL->second.cur_id == curSeverId) {
srcSeverL->second.cpu_A += curVmCpu / 2;
srcSeverL->second.cpu_B += curVmCpu / 2;
srcSeverL->second.momery_A += curVmMomery / 2;
srcSeverL->second.momery_B += curVmMomery / 2;
//更新当前排序后cmp_severCap中源服务器的容量
cmp_severCap[index1].second.cpu_A += curVmCpu / 2;
cmp_severCap[index1].second.cpu_B += curVmCpu / 2;
cmp_severCap[index1].second.momery_A += curVmMomery / 2;
cmp_severCap[index1].second.momery_B += curVmMomery / 2;
break;
}
}
//更新目的服务器
auto destSeverL = localSevers.find(destSeverModel);
int count6 = localSevers.count(destSeverModel);
for (int i = 0; (i < count6) && (destSeverL != localSevers.end()); destSeverL++, i++) {
if ((destSeverL->second.cur_id % 100) != (destSeverId % 100)) {
i++;
continue;
}
if (destSeverL->second.cur_id == destSeverId) {
destSeverL->second.cpu_A -= curVmCpu / 2;
destSeverL->second.cpu_B -= curVmCpu / 2;
destSeverL->second.momery_A -= curVmMomery / 2;
destSeverL->second.momery_B -= curVmMomery / 2;
//更新当前排序后cmp_severCap中目的服务器的容量
cmp_severCap[index2].second.cpu_A -= curVmCpu / 2;
cmp_severCap[index2].second.cpu_B -= curVmCpu / 2;
cmp_severCap[index2].second.momery_A -= curVmMomery / 2;
cmp_severCap[index2].second.momery_B -= curVmMomery / 2;
break;
}
}
//更新本地虚拟机信息
auto posVm = localVirtualMachines.find(curVmId);
if (posVm != localVirtualMachines.end()) {
posVm->second.mountedSeverId = destSeverId;
posVm->second.mountedSeverModel = destSeverModel;
posVm->second.mountedSeverNode = 'N';
}
// //更新服务器挂载虚拟机信息
// auto posSeverVm = localSeverId_VmId.find(curSeverId);
// for (; posSeverVm != localSeverId_VmId.end(); posSeverVm++) {
// if ((posSeverVm->second % 100) != (curVmId % 100)) {
// i++;
// continue;
// }
// if (posSeverVm->second == curVmId) {
// localSeverId_VmId.erase(posSeverVm);
// break;
// }
// }
// localSeverId_VmId.insert(make_pair(destSeverId, curVmId));
migrationVM destSeverInfo;
destSeverInfo.flag = flag1++;
destSeverInfo.destSeverId = destSeverId;
destSeverInfo.destSeverNode = 'N';
MigrationResults.insert(make_pair(curVmId, destSeverInfo));
(*migrationVmNums)--;
if (*migrationVmNums == 0) { //迁移虚拟机数量到达限制,直接返回
return;
}
break;
}
}
}
//}
}
}
//cout << "migrationVirtualMachines 10" << endl;
}
/* 处理这一天的所有请求 */
void readRequestListForOneDay(int day, int requestListNums, int* preDayPurchasedSeversId) {
int flag = 1, flag1 = 1;
multimap<string, curDayPurchasedSeversMessage> curDayPurchasedSevers;
multimap<string, SeversModel> curDayPurchasedSeversByModel;
unordered_map<int, curDayAddedVirtualMachinesMessage> curDayAddedVirtualMachines;
multimap<int, curDayAddedVirtualMachinesMessage> curDayAddedVirtualMachinesBySeverId;
multimap<int, int> SeverId_VmId;
/* 用来存储当天所有的操作 */
multimap<string, operation> curDayOperations;
/* 迁移的虚拟机id,目的服务器id、目的服务器节点(0:A、1:B、2:N) */
unordered_map<int, migrationVM> migrationResults;
/* 每天迁移虚拟机上限 */
int migrationVmNums = (5 * localVirtualMachines.size()) / 1000;
// for (auto it = localSevers.begin(); it != localSevers.end(); it++) {
// printf("day[%d]: localSever_1[%d]: %s, %d, %d, %d, %d\n", day, it->second.cur_id,
// it->first.c_str(),
// it->second.cpu_A,
// it->second.cpu_B,
// it->second.momery_A,
// it->second.momery_B);
// }
for (int sum = 0; sum < requestListNums; sum++) {
string vmOp; /* 当前操作add还是del */
string vmModel; /* 虚拟机型号 */
int vmId; /* 虚拟机id */
/* 1、读取这一次请求的目的add还是del */
char *buff = (char *)malloc(size);
if (scanf("%s", buff));
bool b = false;
int i = 0;
char *name0 = (char *)malloc(size);
for (int addr = 0; buff[addr] != '\0'; addr++) {
if (buff[addr] == ',' && b) {
b = false;
name0[i] = '\0';
if (name0) {
vmOp = name0;
}
i = 0;
} else if (addr == 0) {
b = true;
continue;
}
if (b) {
name0[i++] = buff[addr];
}
}
free(buff);
/* 2、判断这一次操作是不是add;
* 若是,则读取虚拟机型号
* 若不是,则虚拟机型号赋值为"**"
*/
if (vmOp == "add") {
//printf("21 readRequestListForOneDay\n");
char *buff1 = (char *)malloc(size);
if (scanf("%s", buff1));
bool bb = false;
int ii = 0;
char *name00 = (char *)malloc(size);
for (int addr1 = 0; buff1[addr1] != '\0'; addr1++){
if (buff1[addr1] == ',' && bb) {
bb = false;
name00[ii] = '\0';
if (name00) {
vmModel = name00;
}
ii = 0;
} else if (addr1 == 0) {
bb = true;
name00[ii++] = buff1[addr1];
continue;
}
if (bb) {
name00[ii++] = buff1[addr1];
}
}
free(buff1);
/* 3.1、读取要操作的虚拟机ID */
int a;
if (scanf("%d", &a));
vmId = a;
//printf("22 readRequestListForOneDay\n");
} else {
/* 3.2、读取要操作的虚拟机ID */
int a1;
if (scanf("%d", &a1));
vmModel = (char*)"**";
vmId = a1;
}
/* 4、读取剩余字符串:) */
char *buffer = (char *)malloc(size);
if (scanf("%s", buffer));
free(buffer);
operation curOperation;
curOperation.model = vmModel;
curOperation.id = vmId;
curDayOperations.insert(make_pair(vmOp, curOperation));
}
/* 迁移本地的虚拟机 */
try {
//migrationVirtualMachines(flag1, day, &migrationVmNums, migrationResults);
} catch (...) {
//printf("error happen!!\n");
//exit(-1);
}
/* 5、资源规划与调度 */
/* 添加操作 */
auto it1 = curDayOperations.find("add");
for (; it1 != curDayOperations.end(); it1++) {
if (it1->first == "add") {
addVirtualMachine(flag, it1->second.model, it1->second.id, curDayPurchasedSevers, curDayPurchasedSeversByModel,
curDayAddedVirtualMachines, curDayAddedVirtualMachinesBySeverId, SeverId_VmId);
it1->second.id = -3;
}
}
/* 删除操作 */
auto it2 = curDayOperations.find("del");
for (; it2 != curDayOperations.end(); it2++) {
if (it2->first == "del") {
multimap<int, VirtualMachineModel>::iterator tmp2 = localVirtualMachines.find(it2->second.id);
if (tmp2 != localVirtualMachines.end()) {
delVirtualMachine(it2->second.id);
it2->second.id = -3;
}
}
}
//multimap<int, int> tmp_localSeverId_VmId;
/* 0、将本地服务器id从上一天之后开始编号 */
int newSeverId = *preDayPurchasedSeversId;
for (auto pos = curDayPurchasedSeversByModel.begin(); pos != curDayPurchasedSeversByModel.end(); pos++) {
pos->second.pre_id = pos->second.cur_id;
pos->second.cur_id = newSeverId++;
/* 0.1、更新本地服务器id */
for (auto pos1 = localSevers.rbegin(); pos1 != localSevers.rend(); pos1++) {
if (pos1->second.cur_id == pos->second.pre_id) {
pos1->second.pre_id = pos1->second.cur_id;
pos1->second.cur_id = pos->second.cur_id;
break;
}
}
/* 0.2、更新本地虚拟机对应服务器的id */
multimap<int, int>::iterator findvm = SeverId_VmId.find(pos->second.pre_id);
int mountedVm = SeverId_VmId.count(pos->second.pre_id);
for (int count = 0; findvm != SeverId_VmId.end() && count < mountedVm; findvm++, count++) {
/* 0.2.1、当天添加的虚拟机对应的服务器id */
unordered_map<int, curDayAddedVirtualMachinesMessage>::iterator tmp1 = curDayAddedVirtualMachines.find(findvm->second);
if (tmp1 != curDayAddedVirtualMachines.end()) {
(*tmp1).second.mountedSeverId = (*pos).second.cur_id;
}
/* 0.2.2、本地虚拟机对应的服务器id */
multimap<int, VirtualMachineModel>::iterator tmp2 = localVirtualMachines.find(findvm->second);
if (tmp2 != localVirtualMachines.end()) {
(*tmp2).second.mountedSeverId = (*pos).second.cur_id;
}
}
// /* 0.3、修改本地服务器与其挂载的所有虚拟机哈希表中服务器的id */
// /* 先添加 */
// int nums = localSeverId_VmId.count(pos->second.pre_id);
// int vmIds[nums];
// auto it22 = localSeverId_VmId.find(pos->second.pre_id);
// for (int i = 0; (it22 != localSeverId_VmId.end()) && (i < nums); it22++, i++) {
// if (it22->first == pos->second.pre_id) {
// vmIds[i] = it22->second;
// }
// }
// for (int i = 0; i < nums; i++) {
// tmp_localSeverId_VmId.insert(make_pair(pos->second.cur_id, vmIds[i]));
// }
// /* 再删除 */
// auto it11 = localSeverId_VmId.find(pos->second.pre_id);
// for (int i = 0; (i < nums) && (it11 != localSeverId_VmId.end()); i++) {
// if (it11->first == pos->second.pre_id) {
// it11 = localSeverId_VmId.erase(it11);
// continue;
// } else {
// it11++;
// }
// }
}
// for (auto it = tmp_localSeverId_VmId.begin(); it!= tmp_localSeverId_VmId.end(); it++) {
// localSeverId_VmId.insert(make_pair(it->first, it->second));
// }
/* P1: 输出当天购买的服务器总数量 */
int n = curDayPurchasedSevers.size();
cout << "(purchase, " << n << ")" << endl;
/* P2: 输出购买的各个服务器的型号和数量 */
for (auto pos1 = curDayPurchasedSevers.begin(); pos1 != curDayPurchasedSevers.end(); pos1++) {
cout << "(" << pos1->first << ", " << pos1->second.nums << ")" << endl;
}
/* P3: 输出当天迁移的服务器数量 */
cout << "(migration, " << migrationResults.size() << ")" << endl;
/* 迁移的虚拟机id,目的服务器id、目的服务器节点(0:A、1:B、2:N) */
vector<PAIR4> cmp_migr_seq(migrationResults.begin(), migrationResults.end());
sort(cmp_migr_seq.begin(),cmp_migr_seq.end(), cmp_by_migration_seq);
for (auto itForMigr = cmp_migr_seq.begin(); itForMigr != cmp_migr_seq.end(); itForMigr++) {
if (itForMigr->second.destSeverNode != 'N') { //虚拟机迁移到目的服务器节点A、B
cout << "(" << itForMigr->first << ", " << itForMigr->second.destSeverId << ", " << itForMigr->second.destSeverNode << ")" << endl;
} else { //虚拟机为双节点部署
cout << "(" << itForMigr->first << ", " << itForMigr->second.destSeverId << ")" << endl;
}
}
/* P4: 输出当天添加的虚拟机对应的服务器id和节点
* 输出要按照每一条虚拟机请求的顺序输出,现在是按照虚拟机的id顺序来输出的p
*/
vector<PAIR2> cmp_added_seq(curDayAddedVirtualMachines.begin(), curDayAddedVirtualMachines.end());
sort(cmp_added_seq.begin(),cmp_added_seq.end(), cmp_by_added_seq);
for (auto pos3 = cmp_added_seq.begin(); pos3 != cmp_added_seq.end(); pos3++) {
if (pos3->second.mountedSeverNode != 'N') {
cout << "(" << pos3->second.mountedSeverId << ", " << pos3->second.mountedSeverNode << ")" << endl;
} else {
cout << "(" << pos3->second.mountedSeverId << ")" << endl;
}
}
// for (auto it = localSevers.begin(); it != localSevers.end(); it++) {
// auto pos = Severs.find(it->first);
// if (it->second.cpu_A < pos->second.cpu_A
// || it->second.cpu_B < pos->second.cpu_B ) {
// totalCost += pos->second.energyConsumption;
// }
// }
// for (auto it = localSevers.begin(); it != localSevers.end(); it++) {
// printf("day[%d]: localSever_2[%d]: %s, %d, %d, %d, %d\n", day, it->second.cur_id,
// it->first.c_str(),
// it->second.cpu_A,
// it->second.cpu_B,
// it->second.momery_A,
// it->second.momery_B);
// }
}
int main() {
//clock_t start_time = clock();
/* 1、读取全部服务器的信息 */
if(scanf("%d", &severNums));
readSever(Severs);
/* 2、读取全部虚拟机的信息 */
if (scanf("%d", &virtualMachineNums));
readVirtualMachine(VirtualMachines);
/* 3、读取请求的天数 */
if (scanf("%d", &requestDays));
/* 4、读取每一天得请求序列并进行资源规划与调度 */
int EveryDayRequestListNums[requestDays];
for (int i = 0; i < requestDays; i++) {
/* 1、读取这一天的请求序列数目 */
if (scanf("%d", &EveryDayRequestListNums[i]));
/* 2、读取这一天所有请求的信息并进行处理 */
int preDayId = severId;
// for (auto it = localSevers.begin(); it != localSevers.end(); it++) {
// printf("day[%d]: localSever_1[%d]: %s, %d, %d, %d, %d\n", i, it->second.cur_id,
// it->first.c_str(),
// it->second.cpu_A,
// it->second.cpu_B,
// it->second.momery_A,
// it->second.momery_B);
// }
readRequestListForOneDay(i, EveryDayRequestListNums[i], &preDayId);
// for (auto it = localSevers.begin(); it != localSevers.end(); it++) {
// printf("day[%d]: localSever_2[%d]: %s, %d, %d, %d, %d\n", i, it->second.cur_id,
// it->first.c_str(),
// it->second.cpu_A,
// it->second.cpu_B,
// it->second.momery_A,
// it->second.momery_B);
// }
}
//printf("\ntotalCost = %lld\n", totalCost);
//clock_t end_time = clock();
//cout << "The run time is: " <<(double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << endl;
//cout << "totalCost = " << totalCost << endl;
return 0;
}