边缘计算卸载调度算法--PSO粒子群
日期: 2020-12-13 分类: 跨站数据测试 421次阅读
PSO粒子群卸载调度算法
1.伪代码
2.分析
- 粒子群初始化:
- 粒子群更新:
注:其中pi当作目前适应度最小的粒子的位置。 - 任务调度:
① 例子:
② 调度伪代码:
- 计算适应度:
① 例子:
② 计算公式:
3.我的java代码实现
package com.clj.demo;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
/**
* PSO算法主函数
*/
public class PSO_main {
public static void main(String[] args) {
// 1 初始化
// 1.1 初始化粒子串【此部分指定了,可修改】
int instNum = 6; // 最大实例数
int instTypeNum = 3; // 实例类型数
int instBuyOptionNum = 2; // 实例选择数
int strNum = 1000; // 初始化粒子串数
final int MAX_ITERATION = 800;// 迭代次数
SAXReader reader = new SAXReader();// 创建SAXReader对象用于读取xml文件
try {
Document doc = reader.read(new File("D:\\homework\\边缘计算\\PSO实现\\xmltest\\Epigenomics_100.xml"));// 读取xml文件,获得Document对象
Element root = doc.getRootElement(); // 获取根元素
List<Element> jobElements = root.elements("job");// 获取根元素下的所有job标签的子元素
final int taskNum = jobElements.size(); // 任务数
final int dimension = 2 * instNum + taskNum + 1; // 每个粒子串的维数
double[][] locats = new double[strNum][dimension]; // 初始化位置粒子串
int[] tasks =new int[taskNum]; // 任务节点名称数组
double[] task_exec = new double[taskNum]; // 每个任务执行时间(在Small类型实例上)数组
int[][] task_depen = new int[taskNum][taskNum]; // 初始化DAG图
for (int i = 0; i < jobElements.size(); i++) { // 初始化顶点表task及任务执行时间表task_exec
tasks[i] = i;
task_exec[i] = Double.parseDouble(jobElements.get(i).attributeValue("runtime"));
}
for (int i = 0; i < taskNum; i++) { // 初始化邻接矩阵
for (int j = 0; j < taskNum; j++) {
task_depen[i][j] = 0;
}
}
List<Element> childElements = root.elements("child");// 获取根元素下的所有child标签的子元素
for (int i = 0; i < childElements.size(); i++) {
String vex_str = childElements.get(i).attributeValue("ref");
int vex_int = Integer.parseInt(vex_str.substring(2));
List<Element> parents = childElements.get(i).elements("parent");// 获取child元素下的所有parent标签元素
for (int j = 0; j < parents.size(); j++) {
String vex_parent_str = parents.get(j).attributeValue("ref");
int vex_parent_int = Integer.parseInt(vex_parent_str.substring(2));
task_depen[vex_parent_int][vex_int] = 1;
}
}
double[] task_exec_real = new double[taskNum]; // 每个任务的实际执行时间
double[][] task_time = new double[taskNum][2]; // 每个任务的EST、EFT矩阵
int[][] locat_int = new int[strNum][dimension]; // locat_int存决策串
for (int i = 0; i < strNum; i++) {
for (int j = 0; j < dimension; j++) {
locats[i][j] = Math.random();
}
}
double[][] velocity = new double[strNum][dimension];// 初始化速度粒子串
for (int i = 0; i < strNum; i++) {
for (int j = 0; j < dimension; j++) {
velocity[i][j] = -0.5 + Math.random();
}
}
// 1.2 处理位置粒子串(将粒子串数值转为整形)
for (int i = 0; i < strNum; ++i) {
for (int j = 0; j < dimension; ++j) {
if (j == 0) {
locat_int[i][j] = (int) Math.round(locats[i][j] * instNum);
if (locat_int[i][j] == 0) {
locat_int[i][j] = 1;
}
} else if (j > 0 && j <= instNum) {
locat_int[i][j] = (int) Math.round(locats[i][j] * instTypeNum);
if (locat_int[i][j] == 0) {
locat_int[i][j] = 1;
}
} else if (j > instNum && j <= instNum * 2) {
locat_int[i][j] = (int) Math.round(locats[i][j] * instBuyOptionNum);
if (locat_int[i][j] == 0) {
locat_int[i][j] = 1;
}
} else {
if (locat_int[i][0] == 1) {
locat_int[i][j] = 1;
} else {
locat_int[i][j] = (int) Math.round(locats[i][j] * instNum);
if (locat_int[i][j] == 0) {
locat_int[i][j] = 1;
}
}
}
}
}
// 1.3 初始化task_idle、instBuyOption、inst_type
double[] str_fitness = new double[strNum]; // 每个粒子串的适应值
int[][] task_idle = new int[strNum][taskNum]; // 任务在哪个实例(虚拟机)上分布
int[][] instBuyOption = new int[strNum][instNum]; // 每个实例的购买类型(按需、预约)
int[][] inst_type = new int[strNum][instNum]; // 每个实例的类型(Small、Large、Extra Large)
// 1.4 计算每个粒子初始适应度、最小适应度、每个任务的EST、EFT
int min_str = 0; // 适应度最小的粒子下标
double min_fitness = 102410241; // 最小的适应度值
for (int i = 0; i < strNum; ++i) {
for (int j = 0; j < instNum; ++j) { // 计算当前粒子的实例购买类型(Demand、Reserved)
int x = 1 + instNum + j;
instBuyOption[i][j] = locat_int[i][x];
}
for (int k = 0; k < taskNum; ++k) { // 计算当前粒子的每个任务分布在那个实例上
int x = 1 + 2 * instNum + k;
task_idle[i][k] = locat_int[i][x];
}
for (int j = 0; j < instNum; ++j) { // 计算当前粒子实例的类型(Small、Large、Extra Large)
int x = 1 + j;
inst_type[i][j] = locat_int[i][x];
}
// 计算每个任务实际执行时间,此处默认Small: Large: Extra Large = 5:4:3
for(int k = 0; k < taskNum; ++k) {
int index = task_idle[i][k] - 1;//
int type = inst_type[i][index];
if(type == 1) { // 1 表示小型实例
task_exec_real[k] = task_exec[k];
} else if (type == 2) { // 2 表示大型实例
task_exec_real[k] = task_exec[k] * 4.0 / 5;
} else if (type == 3) { // 3 表示超大型实例
task_exec_real[k] = task_exec[k] * 3.0 / 5;
}
}
int count = 0;// 辅助变量
for (int k = 0; k < taskNum; ++k) {
for (int j = 0; j < taskNum; j++) {// 初始化开始节点的EST、EFT
if (task_depen[j][k] == 0) {
++count;
}
}
if (count == taskNum) {
task_time[k][0] = 0;
task_time[k][1] = task_exec_real[k];
for (int j = 0; j < taskNum; j++) {// 初始化开始节点直接后继节点的EST、EFT
if (task_depen[k][j] == 1) {
if (task_time[j][0] < task_time[k][1]) {
task_time[j][0] = task_time[k][1];
task_time[j][1] = task_time[j][0] + task_exec_real[j];
}
}
}
}
count = 0;
}
for (int k = 0; k < taskNum; ++k) {// 初始化剩下的所有节点的EST、EFT
for (int j = 0; j < taskNum; j++) {
if (task_depen[k][j] == 1) {
if (task_time[j][0] < task_time[k][1]) {
task_time[j][0] = task_time[k][1];
task_time[j][1] = task_time[j][0] + task_exec_real[j];
}
}
}
}
str_fitness[i] = Util.scheduleAndFitness(task_time,instNum,task_idle[i],taskNum,task_exec_real,task_depen,instBuyOption[i],inst_type[i]);// 计算适应值
}
for (int k = 1; k < strNum; ++k) {
if (str_fitness[k] < min_fitness) {
min_str = k;
min_fitness = str_fitness[k];
}
}
// 2 不断迭代求最小适应度
for(int i = 0;i < MAX_ITERATION;++i) {
for (int j = 0; j < strNum; j++) {
double[] v0 = new double[dimension];// 粒子初始速度
double[] x0 = new double[dimension];// 粒子初始位置
double[] p = new double[dimension]; // 最小适应度位置
for (int k = 0; k < dimension; k++) {
v0[k] = velocity[j][k];
p[k] = locats[min_str][k];
}
double[][] new_result = Util.updateStr(x0,v0,p);
double[] x_new = new double[dimension];// 粒子更新位置
double[] v_new = new double[dimension];// 粒子更新速度
for (int k = 0; k < dimension; k++) {
if(new_result[0][k] < 0){
x_new[k] = 0;
}else{
x_new[k] = new_result[0][k];
}
v_new[k] = new_result[1][k];
}
int[] x_new_int = new int[dimension]; // 整形决策信息
for (int k = 0; k < dimension; k++) { // 更新的整形决策信息
if (k == 0) {
x_new_int[k] = (int) Math.round(x_new[k] * instNum);
if (x_new_int[k] == 0) {
x_new_int[k] = 1;
}
} else if (k > 0 && k <= instNum) {
x_new_int[k] = (int) Math.round(x_new[k] * instTypeNum);
if (x_new_int[k] == 0) {
x_new_int[k] = 1;
}
} else if (k > instNum && k <= instNum * 2) {
x_new_int[k] = (int) Math.round(x_new[k] * instBuyOptionNum);
if (x_new_int[k] == 0) {
x_new_int[k] = 1;
}
} else {
if (x_new_int[k] == 1) {
x_new_int[k] = 1;
} else {
x_new_int[k] = (int) Math.round(x_new[k] * instNum);
if (x_new_int[k] == 0) {
x_new_int[k] = 1;
}
}
}
}
for (int k = 0; k < taskNum; k++) {// 更新task_idle
task_idle[i][k] = x_new_int[1 + 2 * instNum + k];
}
for (int k = 0; k < instNum; k++) {// 更新inst_type
inst_type[i][k] = x_new_int[1 + k];
}
for (int k = 0; k < instNum; ++k) { // 更新instBuyOption
instBuyOption[i][k] = x_new_int[1 + instNum + k];
}
double new_fitness = Util.scheduleAndFitness(task_time,instNum,task_idle[i],taskNum,task_exec_real,task_depen,instBuyOption[i],inst_type[i]);// 计算适应值
if(new_fitness < str_fitness[j]){
str_fitness[j] = new_fitness;
for (int k = 0; k < dimension; k++) {
locats[j][k] = x_new[k];
velocity[j][k] = v_new[k];
locat_int[j][k] = x_new_int[k];
}
}
}
for (int k = 1; k < strNum; ++k) {
if (str_fitness[k] < min_fitness) {
min_str = k;
min_fitness = str_fitness[k];
}
}
}
// 3 输出结果
for (int i = 0; i < dimension; i++) {
System.out.print(locat_int[min_str][i] + " ");
}
System.out.println();
for (int i = 0; i < locat_int[min_str][0]; i++) {
if(inst_type[min_str][i] == 1 && instBuyOption[min_str][i] == 1){
System.out.println("第" + (i+1) + "个实例选择Small、预约");
}else if(inst_type[min_str][i] == 1 && instBuyOption[min_str][i] == 2){
System.out.println("第" + (i+1) + "个实例选择Small、按需");
}else if(inst_type[min_str][i] == 2 && instBuyOption[min_str][i] == 1){
System.out.println("第" + (i+1) + "个实例选择Large、预约");
}else if(inst_type[min_str][i] == 2 && instBuyOption[min_str][i] == 2){
System.out.println("第" + (i+1) + "个实例选择Large、按需");
}else if(inst_type[min_str][i] == 3 && instBuyOption[min_str][i] == 1){
System.out.println("第" + (i+1) + "个实例选择Extra Large、预约");
}else if(inst_type[min_str][i] == 3 && instBuyOption[min_str][i] == 2){
System.out.println("第" + (i+1) + "个实例选择Extra Large、按需");
}
}
System.out.println("它的总cost为" + min_fitness);
System.out.println("---------------------------------");
for (int i = 0; i < taskNum; i++) { // 初始化邻接矩阵
for (int j = 0; j < taskNum; j++) {
System.out.print(task_depen[i][j] + " ");
}
System.out.println();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:边缘计算 边缘计算
精华推荐