问题描述:给出一定用户的请求(各类虚拟机的数量),装在给定规格的服务器内 ,要求服务器的资源利用率最大。其中,虚拟机和服务器各有两个维度限制,CPU和内存(Mem)。
思路:本题实质是背包问题,考虑过dp,贪心,蚁群以及遗传。若单单解决该问题,则dp是最佳的选择,由于题目后期会有拓展(多维度多约束背包问题),并且有时间上的要求,考虑到这个原因,我就放弃了dp。个人觉得蚁群的复杂度较高,所以也放弃了蚁群。贪心在数据规格较小时,效果明显,一旦数据规格扩大时,则遗传效果明显。经过实验的对比,在一定数量的虚拟机下采用贪心算法,一旦超过了这个数量,怎用遗传来处理。遗传主要的难点是在编码方式上,数据量大时,二进制编码的缺点就暴露出来,思考过来决定用实数编码,然后做数据的映射。
方案:将所有的虚拟机用数组装载起来,数组的下标作为染色体,然后将染色体和虚拟机用数据结构关联在一起,方便后面的输出。
交叉算子采用多点交叉,步骤如下:
1)随机选择两个父染色体,随机生成交叉点,交叉点将染色体分成两部分,如图(a)所示;
2)交换两个染色体的第一部分或者是第二部分,生成新的染色体,如图(b)所示;
3)将新的染色体放入新的种群中。
(a)
(b)
代码如下:
Vector<SA.Flavor> vec_flavors = new Vector<>();
for (String key : map.keySet()) {
int v = map.get(key);
while (v-- != 0) {
vec_flavors.add(re.get(key)); //将所有虚拟机加入容器内
}
}
int[] cpu_data = new int[vec_flavors.size()];
int[] mem_data = new int[vec_flavors.size()];
for (int i = 0; i < vec_flavors.size(); i++) {
cpu_data[i] = vec_flavors.get(i).cpu; //将所有虚拟机的cpu放入一维数组中
mem_data[i] = vec_flavors.get(i).mem; //将所有虚拟机的mem放入一维数组中
}
//------数据映射,将染色体编码和虚拟机关联起来-------//
LinkedHashMap<Integer, Integer> map1 = new LinkedHashMap<>();
int m = 0;
for (int i = 0; i < target_f_num_qu.length; i++) {
for (int j = 0; j < target_f_num_qu[i]; j++) {
map1.put(m, i + 1); m++;
}
}
登录 | 立即注册