我choco
用来解决虚拟机分配问题,这就是我想要做的:
假设我们有 3 个用于物理机属性的数组(PMcpu
、PMram
、PMbw
)和 3 个用于虚拟机的数组(VMcpu
、VMram
、VMbw
)。现在我们定义一个具有这些维度的矩阵:PM*VM
这样 choco 将设置值(0 或 1 表示特定 VM 是否分配给 PM)。根据常识,我们知道 PM 资源应该大于或等于所有分配的 VM 资源的总量,因此我们将分配矩阵中的每个元素与相应的资源相乘,例如假设:
PMcpu = {8000, 7000, 3000};
PMram = {7000, 4000, 5000};
PMbw = {2000, 500, 7000};
VMcpu = {2000, 3000, 1000};
VMram = {1000, 2000, 3000};
VMbw = {100, 2000, 500};
分配矩阵:
0 1 0
1 0 0
0 0 1
行代表 PM,列代表 VM,所以这里:
VM2 -> PM1
VM1 -> PM2
VM3 -> PM3
所以我写了这段代码:
Model model = new Model("Resource Allocation Problem");
int[] VMcpu = new int[number_of_vms];
int[] VMram = new int[number_of_vms];
int[] VMbw = new int[number_of_vms];
// some initialization here
int[] PMcpu = new int[number_of_pms];
int[] PMram = new int[number_of_pms];
int[] PMbw = new int[number_of_pms];
// some initialization here
IntVar[][] alloc_matrix = model.intVarMatrix("alloc_matrix", number_of_pms, number_of_vms, new int[] {0,1});
// ensuring all columns have only one 1 in them
ArrayList<IntVar> sum_of_col = new ArrayList<>();
for(int j=0; j<number_of_vms; j++) {
int count = 0;
for(int i=0; i<number_of_pms; i++) {
count += alloc_matrix[i][j].getValue();
}
IntVar tempInt = model.intVar(count);
sum_of_col.add(tempInt);
}
for(int i=0; i<sum_of_col.size(); i++) {
model.arithm(sum_of_col.get(i), "=", 1).post();
}
// ensuring that PMs can host that much VM (based on their resources)
for (int i=0; i<number_of_pms; i++) {
ArrayList<IntVar> pm_total_cpu = new ArrayList<>();
ArrayList<IntVar> pm_total_ram = new ArrayList<>();
ArrayList<IntVar> pm_total_bw = new ArrayList<>();
for (int j=0; j<number_of_vms; j++) {
IntVar temp_cpu = model.intVar(alloc_matrix[i][j].getValue() * VMcpu[j]);
IntVar temp_ram = model.intVar(alloc_matrix[i][j].getValue() * VMram[j]);
IntVar temp_bw = model.intVar(alloc_matrix[i][j].getValue() * VMbw[j]);
pm_total_cpu.add(temp_cpu);
pm_total_ram.add(temp_ram);
pm_total_bw.add(temp_bw);
}
model.sum(ArrayUtils.toArray(pm_total_cpu), "<", PMcpu[i]).post();
model.sum(ArrayUtils.toArray(pm_total_ram), "<", PMram[i]).post();
model.sum(ArrayUtils.toArray(pm_total_bw), "<", PMbw[i]).post();
}
// getting the number of active PMs (those that have at least one 1 in their row)
ArrayList<IntVar> pm_hostings = new ArrayList<>();
for (int i=0; i<number_of_pms; i++) {
ArrayList<IntVar> row = new ArrayList<>();
for (int j=0; j<number_of_vms; j++) {
IntVar temp_int_var = model.intVar(alloc_matrix[i][j].getValue());
row.add(temp_int_var);
}
int has_one = 0;
for(int iterator=0; iterator<row.size(); iterator++) {
if (row.get(iterator).getValue() == 1) {
has_one = 1;
break;
}
}
IntVar temp = model.intVar(has_one);
pm_hostings.add(temp);
}
// sum will be the number of active PMs
int sum = 0;
for (int i=0; i<pm_hostings.size(); i++) {
sum += pm_hostings.get(i).getValue();
}
// setting objective to minimize that number of active PMs
IntVar answer = model.intVar(sum);
model.setObjective(Model.MINIMIZE, answer);
while(model.getSolver().solve()) {
System.out.println("answer: " + answer.getValue());
for(int i=0;i<sum_of_col.size();i++) {
System.out.println("=== " + sum_of_col.get(i).getValue());
}
for(int i=0;i<number_of_pms;i++) {
for(int j=0;j<number_of_vms;j++) {
System.out.print(alloc_matrix[i][j].getValue() + " ");
}
System.out.println();
}
}
我试图通过检查要在行中填充的矩阵的每一列来确保分配所有 VM model.arithm(sum_of_col.get(i), "=", 1).post();
。如果我评论约束和目标,矩阵将被随机分配,但在应用约束时,choco 不会解决任何问题(没有输出,因为while(model.getSolver().solve()
永远不会正确,所以 choco 似乎没有解决它)。我不知道我在哪里做错了。任何帮助表示赞赏:)
提前致谢
编辑:我意识到问题是 choco 只在第一次检查这些约束,所以当一切都为 0 时它会检查它,这就是它不会继续的原因,但是在 solve() 循环中添加约束后,我仍然得到相同的结果,也许我应该以choco理解它们的另一种方式应用这些约束,我现在真的很沮丧:(