// exhaustive search with load-balanced routing bool Tree::BackTracking(Cluster &req, Solution &map) { sort(req.B.begin(),req.B.end(),greater<float>()); // sort B1,...BN in descending order float sum_capacity[nServer][nServer]; float hostBw[nServer]={0}; //total bandwidths of a server assigned to the current VDC vector<int> assignment(req.N,-1); //the server index B1,...BN located in //vector<vector<bool>> tabu(req.N,vector<bool>(nServer,false)); //intiate the map variables: map.Clear(); //quick fail float res_port_B[nServer]={0},sumB=0; if (QuickFail(req,sumB,res_port_B)==false) return false; //end of quick fail !! //i: visit the VMs, j: visit the servers int numVMembedded=0; if (recursivePlacement(req, map,assignment,sumB,res_port_B,hostBw,numVMembedded)) { return true; } else return false; }
bool Tree::BestFit(Cluster& req,Solution& map) { sort(req.B.begin(),req.B.end(),greater<float>()); // sort B1,...BN in descending order float sum_capacity[nServer][nServer]; float hostBw[nServer]={0}; //total bandwidths of a server assigned to the current VDC vector<int> assignment(req.N,-1); //the server index B1,...BN located in //intiate the map variables: map.Clear(); //quick fail float res_port_B[nServer]={0},sumB=0; if (QuickFail(req,sumB,res_port_B)==false) return false; //i: visit the VMs, j: visit the servers int numVMembedded=0; for (int i=0;i<req.N;i++) { int x,bestHost=-1; float min_mlu=1; for (x=0;x<nServer;x++) { // packing VMs( i=1:N )into server x if (Table[x].Slot<=map.Slot[x])// there is no space in server x continue; //open the next server if(res_port_B[x]<min(hostBw[x]+req.B[i],sumB-hostBw[x]-req.B[i])) continue; //less ingress bandwidth!! hostBw[x]+=req.B[i]; CongestDetect(x,req,hostBw,sumB,map); float mlu=0; for (int e=0;e<Ne;e++){ if (mlu<map.Bandwidth[e]/resBandwidth[e]){ mlu=map.Bandwidth[e]/resBandwidth[e]; } } if (mlu<min_mlu) //better host is found! { min_mlu=mlu; bestHost=x; } //undo the placement and try the next server hostBw[x]-=req.B[i]; } //end for server x if (min_mlu>=1) // fail to find a suitable host return false; map.Slot[bestHost]+=1;hostBw[bestHost]+=req.B[i];assignment[i]=bestHost;numVMembedded++; if (numVMembedded==req.N) { // already found the host for the last VM return true; } } // end for VM(Bi) }
// greedy pack a server with any fitable VMs bool Tree::FirstFit(Cluster& req,Solution& map) { sort(req.B.begin(),req.B.end(),greater<float>()); // sort B1,...BN in descending order float hostBw[nServer]={0}; //total bandwidths of a server assigned to the current VDC vector<int> assignment(req.N,-1); //the server index B1,...BN located in //intiate the map variables: map.Clear(); //quick fail float res_port_B[nServer]={0},sumB=0; if (QuickFail(req,sumB,res_port_B)==false) return false; //end of quick fail !! //i: visit the VMs, j: visit the servers int numVMembedded=0,maxLoop=req.N*nServer;; for (int i=0;i<req.N;i++) { int x; for (x=0;x<nServer;x++) { // packing VMs( i=1:N )into server x if (Table[x].Slot<=map.Slot[x])// there is no space in server x continue; //open the next server if(res_port_B[x]<min(hostBw[x]+req.B[i],sumB-hostBw[x]-req.B[i])) continue; //less ingress bandwidth!! map.Slot[x]+=1;hostBw[x]+=req.B[i];assignment[i]=x;numVMembedded++; if (CongestDetect(x,req,hostBw,sumB,map)) { map.Slot[x]-=1; hostBw[x]-=req.B[i]; assignment[i]=-1; numVMembedded--; } else { if (numVMembedded==req.N) { return true; } else break; } //else continue; //to try the next server } //end for server x if (x>=nServer) return false; } // end for VM(Bi) }
bool Tree::NextFit(Cluster& req,Solution& map) { sort(req.B.begin(),req.B.end(),greater<float>()); // sort B1,...BN in descending order float hostBw[nServer]={0}; //total bandwidths of a server assigned to the current VDC vector<int> assignment(req.N,-1); //the server index B1,...BN located in //intiate the map variables: map.Clear(); //quick fail float res_port_B[nServer]={0},sumB=0; if (QuickFail(req,sumB,res_port_B)==false) return false; //i: visit the VMs, j: visit the servers int numVMembedded=0,lastHost=0; for (int i=0;i<req.N;i++) { int x=lastHost,j=0; for (;j<nServer;j++) { // packing VMs( i=1:N )into server x x=(x+j)%nServer; if (Table[x].Slot<=map.Slot[x])// there is no space in server x continue; //open the next server if(res_port_B[x]<min(hostBw[x]+req.B[i],sumB-hostBw[x]-req.B[i])) continue; //less ingress bandwidth!! map.Slot[x]+=1;hostBw[x]+=req.B[i];assignment[i]=x;numVMembedded++; if (CongestDetect(x,req,hostBw,sumB,map)) { //undo the placement and try the next server map.Slot[x]-=1; hostBw[x]-=req.B[i]; assignment[i]=-1; numVMembedded--; } else{ if (numVMembedded==req.N) { // already found the host for the last VM return true; } else // already found the host for the current VM { lastHost=x; break; } } } //end for server x if (j>=nServer) // fail to find a suitable host return false; } // end for VM(Bi) }
bool Tree::GreedyARAllocation(Cluster &req,Solution &map) { sort(req.B.begin(),req.B.end()); // sort B1,...BN in acescending order vector<int> assignment(req.N,-1); //the server index B1,...BN located in //intiate the map variables: map.Clear(); //quick fail float res_port_B[nServer]={0},sumB=0; if (QuickFail(req,sumB,res_port_B)==false) return false; Matrix<bool>Q(Nv,req.N); for(int x=0;x<req.N;x++) for(int y=x;y<req.N;y++) split(x,y)=getSplit(req,sumB,x,y); //from down to root for (int v=0;v<Nv;v++) for(int x=0;x<req.N;x++) for(int y=x;y<req.N;y++){ calculateAR(req,sumB,x,y,v); //cout<<" "<<v<<" "<<x<<" "<<y<<" "; //cout<<" "<<AR[v].split[x][y]; } //from root to down bool accept=subAssign(req,0,req.N-1,root,Q,map); if(accept){ for(int i=0;i<req.N;i++)for(int j=0;j<nServer;j++) if(Q(j,i)){ assignment[i]=j; map.Slot[j]++; } } return accept; }
// pertubation only when a VM can not placed bool Tree::Pertubation(Cluster& req,Solution& map) { sort(req.B.begin(),req.B.end(),greater<float>()); // sort B1,...BN in descending order float hostBw[nServer]={0}; //total bandwidths of a server assigned to the current VDC vector<int> assignment(req.N,-1); //the server index B1,...BN located in vector<vector<bool>> tabu(req.N,vector<bool>(nServer,false)); //intiate the map variables: map.Clear(); //quick fail float res_port_B[nServer]={0},sumB=0; if (QuickFail(req,sumB,res_port_B)==false) return false; //end of quick fail !! int numVMembedded=0,maxLoop=req.N*nServer; float TS[nServer]={0},TD[nServer]={0}; for(int t=0;t<maxLoop+1;t++) { // find VM(Bi) with max B, and try to place to server x int i,x; //i: visit the VMs, x: visit the servers for (i=0;i<req.N;i++) if (assignment[i]==-1) break; //to place VM(Bi)into the servers, {0,1,...tabu[i]} are not considered int n_usefull_server=0; for (x=0;x<nServer;x++) { if (tabu[i][x])// this server x is in the tabu list of VM(Bi) continue; if (Table[x].Slot<=map.Slot[x])// there is no space in server m continue; //try the next server for VM(Bi) if(res_port_B[x]<min(hostBw[x]+req.B[i],sumB-hostBw[x]-req.B[i])) continue; //less ingress bandwidth!! n_usefull_server++; map.Slot[x]+=1;hostBw[x]+=req.B[i];assignment[i]=x;numVMembedded++; if (CongestDetect(x,req,hostBw,sumB,map)){ map.Slot[x]-=1; hostBw[x]-=req.B[i]; assignment[i]=-1; numVMembedded--; updateBottlenecks(hostBw,map,TS,TD); } else break; //else, try server x+1 } //end for server x if (numVMembedded==req.N) return true; if (x>=nServer) { if(n_usefull_server==0||numVMembedded==0) // running out of VM slots! return false; // fail due to conestion,try pertubation // fail due to conestion,try pertubation int the_server=-1,the_vm; the_server=findBottleneck(hostBw,TS,TD); for(the_vm=req.N-1;the_vm>=0;the_vm--) if (assignment[the_vm]==the_server) break; if (the_server<0||the_server>=nServer||the_vm<0||the_vm>req.N) return false; //fail due to bisection traffic, rather than concurrent congestion. //n_bottle[the_server]=0; //unload a VM from the bottleneck server map.Slot[the_server]-=1; hostBw[the_server]-=req.B[the_vm]; assignment[the_vm]=-1; numVMembedded--; tabu[the_vm][the_server]=1; } //else, Let's place the next VM(Bi+1) } return false; }