├── Arnes.gml ├── Qlearning_SDN-Copy1.py └── data2.csv /Arnes.gml: -------------------------------------------------------------------------------- 1 | graph [ 2 | DateObtained "19/10/10" 3 | GeoLocation "Slovenia" 4 | GeoExtent "Country" 5 | Network "ARNES" 6 | Provenance "Primary" 7 | Access 0 8 | Source "http://www.arnes.si/infrastruktura.html" 9 | Version "1.0" 10 | DateType "Dynamic" 11 | Type "REN" 12 | Backbone 1 13 | Commercial 0 14 | label "Arnes" 15 | ToolsetVersion "0.3.34dev-20120328" 16 | Customer 1 17 | IX 0 18 | SourceGitVersion "e278b1b" 19 | DateModifier "=" 20 | DateMonth "10" 21 | LastAccess "19/10/10" 22 | Layer "IP" 23 | Creator "Topology Zoo Toolset" 24 | Developed 1 25 | Transit 0 26 | NetworkDate "2010_10" 27 | DateYear "2010" 28 | LastProcessed "2011_09_01" 29 | Testbed 0 30 | node [ 31 | id 0 32 | label "Trbovlje" 33 | Country "Slovenia" 34 | Longitude 15.05333 35 | Internal 1 36 | Latitude 46.155 37 | type "Small Node" 38 | ] 39 | node [ 40 | id 1 41 | label "Krsko" 42 | Country "Slovenia" 43 | Longitude 15.49167 44 | Internal 1 45 | Latitude 45.95915 46 | type "Small Node" 47 | ] 48 | node [ 49 | id 2 50 | label "Celje" 51 | Country "Slovenia" 52 | Longitude 15.26044 53 | Internal 1 54 | Latitude 46.23092 55 | type "Small Node" 56 | ] 57 | node [ 58 | id 3 59 | label "Lasko" 60 | Country "Slovenia" 61 | Longitude 15.23555 62 | Internal 1 63 | Latitude 46.15463 64 | type "Small Node" 65 | ] 66 | node [ 67 | id 4 68 | label "Kranj" 69 | Country "Slovenia" 70 | Longitude 14.35561 71 | Internal 1 72 | Latitude 46.23887 73 | type "Small Node" 74 | ] 75 | node [ 76 | id 5 77 | label "Bled" 78 | Country "Slovenia" 79 | Longitude 14.11361 80 | Internal 1 81 | Latitude 46.36917 82 | type "Small Node" 83 | ] 84 | node [ 85 | id 6 86 | label "Novo Mesto" 87 | Country "Slovenia" 88 | Longitude 15.16886 89 | Internal 1 90 | Latitude 45.80397 91 | type "Small Node" 92 | ] 93 | node [ 94 | id 7 95 | label "Ljubljana" 96 | Country "Slovenia" 97 | Longitude 14.50513 98 | Internal 1 99 | Latitude 46.05108 100 | type "Large Node" 101 | ] 102 | node [ 103 | id 8 104 | label "Tolmin" 105 | Country "Slovenia" 106 | Longitude 13.73321 107 | Internal 1 108 | Latitude 46.18304 109 | type "Small Node" 110 | ] 111 | node [ 112 | id 9 113 | label "Nova Gorica" 114 | Country "Slovenia" 115 | Longitude 13.64837 116 | Internal 1 117 | Latitude 45.95604 118 | type "Small Node" 119 | ] 120 | node [ 121 | id 10 122 | label "Portoroz" 123 | Country "Slovenia" 124 | Longitude 13.59206 125 | Internal 1 126 | Latitude 45.51429 127 | type "Small Node" 128 | ] 129 | node [ 130 | id 11 131 | label "Gornja Radgona" 132 | Country "Slovenia" 133 | Longitude 15.99222 134 | Internal 1 135 | Latitude 46.67333 136 | type "Small Node" 137 | ] 138 | node [ 139 | id 12 140 | label "Radenci" 141 | Country "Slovenia" 142 | Longitude 16.03781 143 | Internal 1 144 | Latitude 46.64201 145 | type "Small Node" 146 | ] 147 | node [ 148 | id 13 149 | label "Rogasja Slatina" 150 | Country "Slovenia" 151 | Longitude 15.63972 152 | Internal 1 153 | Latitude 46.2375 154 | type "Small Node" 155 | ] 156 | node [ 157 | id 14 158 | label "Senozece" 159 | Country "Slovenia" 160 | Longitude 14.04111 161 | Internal 1 162 | Latitude 45.72111 163 | type "Small Node" 164 | ] 165 | node [ 166 | id 15 167 | label "Jesenice" 168 | Country "Slovenia" 169 | Longitude 14.06694 170 | Internal 1 171 | Latitude 46.43056 172 | type "Small Node" 173 | ] 174 | node [ 175 | id 16 176 | label "Sezana" 177 | Country "Slovenia" 178 | Longitude 13.87333 179 | Internal 1 180 | Latitude 45.70924 181 | type "Small Node" 182 | ] 183 | node [ 184 | id 17 185 | label "Divaca" 186 | Country "Slovenia" 187 | Longitude 13.97028 188 | Internal 1 189 | Latitude 45.68472 190 | type "Small Node" 191 | ] 192 | node [ 193 | id 18 194 | label "Postojna" 195 | Country "Slovenia" 196 | Longitude 14.21667 197 | Internal 1 198 | Latitude 45.77694 199 | type "Small Node" 200 | ] 201 | node [ 202 | id 19 203 | label "Ajdovscina" 204 | Country "Slovenia" 205 | Longitude 13.90946 206 | Internal 1 207 | Latitude 45.88601 208 | type "Small Node" 209 | ] 210 | node [ 211 | id 20 212 | label "Kovevje" 213 | Country "Slovenia" 214 | Longitude 14.86333 215 | Internal 1 216 | Latitude 45.64333 217 | type "Small Node" 218 | ] 219 | node [ 220 | id 21 221 | label "Kamnik" 222 | Country "Slovenia" 223 | Longitude 14.61207 224 | Internal 1 225 | Latitude 46.22587 226 | type "Small Node" 227 | ] 228 | node [ 229 | id 22 230 | label "Izola" 231 | Country "Slovenia" 232 | Longitude 13.66194 233 | Internal 1 234 | Latitude 45.53694 235 | type "Small Node" 236 | ] 237 | node [ 238 | id 23 239 | label "Koper" 240 | Country "Slovenia" 241 | Longitude 13.72944 242 | Internal 1 243 | Latitude 45.54694 244 | type "Small Node" 245 | ] 246 | node [ 247 | id 24 248 | label "Slovenj Gradec" 249 | Country "Slovenia" 250 | Longitude 15.08056 251 | Internal 1 252 | Latitude 46.51028 253 | type "Small Node" 254 | ] 255 | node [ 256 | id 25 257 | label "Velenje" 258 | Country "Slovenia" 259 | Longitude 15.11028 260 | Internal 1 261 | Latitude 46.35917 262 | type "Small Node" 263 | ] 264 | node [ 265 | id 26 266 | label "Murska Sobota" 267 | Country "Slovenia" 268 | Longitude 16.16639 269 | Internal 1 270 | Latitude 46.6625 271 | type "Small Node" 272 | ] 273 | node [ 274 | id 27 275 | label "Ljutomer" 276 | Country "Slovenia" 277 | Longitude 16.1975 278 | Internal 1 279 | Latitude 46.52083 280 | type "Small Node" 281 | ] 282 | node [ 283 | id 28 284 | label "Ormoz" 285 | Country "Slovenia" 286 | Longitude 16.15444 287 | Internal 1 288 | Latitude 46.41139 289 | type "Small Node" 290 | ] 291 | node [ 292 | id 29 293 | label "Ptuj" 294 | Country "Slovenia" 295 | Longitude 15.87018 296 | Internal 1 297 | Latitude 46.42005 298 | type "Small Node" 299 | ] 300 | node [ 301 | id 30 302 | label "Maribor" 303 | Country "Slovenia" 304 | Longitude 15.64667 305 | Internal 1 306 | Latitude 46.55472 307 | type "Large Node" 308 | ] 309 | node [ 310 | id 31 311 | label "Slovenska Bistrica" 312 | Country "Slovenia" 313 | Longitude 15.57444 314 | Internal 1 315 | Latitude 46.39278 316 | type "Small Node" 317 | ] 318 | node [ 319 | id 32 320 | label "Dravograd" 321 | Country "Slovenia" 322 | Longitude 15.01917 323 | Internal 1 324 | Latitude 46.58806 325 | type "Small Node" 326 | ] 327 | node [ 328 | id 33 329 | label "Ravne na Koroskem" 330 | Country "Slovenia" 331 | Longitude 14.96917 332 | Internal 1 333 | Latitude 46.54306 334 | type "Small Node" 335 | ] 336 | edge [ 337 | source 0 338 | target 3 339 | LinkSpeed "1" 340 | LinkLabel "1 GB/s" 341 | LinkSpeedUnits "G" 342 | LinkSpeedRaw 1000000000.0 343 | ] 344 | edge [ 345 | source 0 346 | target 7 347 | LinkSpeed "1" 348 | LinkLabel "1 GB/s" 349 | LinkSpeedUnits "G" 350 | LinkSpeedRaw 1000000000.0 351 | ] 352 | edge [ 353 | source 1 354 | target 13 355 | LinkSpeed "1" 356 | LinkLabel "1 GB/s" 357 | LinkSpeedUnits "G" 358 | LinkSpeedRaw 1000000000.0 359 | ] 360 | edge [ 361 | source 1 362 | target 6 363 | LinkSpeed "1" 364 | LinkLabel "1 GB/s" 365 | LinkSpeedUnits "G" 366 | LinkSpeedRaw 1000000000.0 367 | ] 368 | edge [ 369 | source 2 370 | target 25 371 | LinkSpeed "1" 372 | LinkLabel "1 GB/s" 373 | LinkSpeedUnits "G" 374 | LinkSpeedRaw 1000000000.0 375 | ] 376 | edge [ 377 | source 2 378 | target 3 379 | LinkSpeed "1" 380 | LinkLabel "1 GB/s" 381 | LinkSpeedUnits "G" 382 | LinkSpeedRaw 1000000000.0 383 | ] 384 | edge [ 385 | source 2 386 | target 21 387 | LinkSpeed "1" 388 | LinkLabel "1 GB/s" 389 | LinkSpeedUnits "G" 390 | LinkSpeedRaw 1000000000.0 391 | ] 392 | edge [ 393 | source 2 394 | target 31 395 | LinkSpeed "1" 396 | LinkLabel "1 GB/s" 397 | LinkSpeedUnits "G" 398 | LinkSpeedRaw 1000000000.0 399 | ] 400 | edge [ 401 | source 3 402 | target 30 403 | LinkSpeed "3" 404 | LinkLabel "3 GB/s" 405 | LinkSpeedUnits "G" 406 | LinkSpeedRaw 3000000000.0 407 | ] 408 | edge [ 409 | source 3 410 | target 7 411 | LinkSpeed "3" 412 | LinkLabel "3 GB/s" 413 | LinkSpeedUnits "G" 414 | LinkSpeedRaw 3000000000.0 415 | ] 416 | edge [ 417 | source 4 418 | target 7 419 | LinkSpeed "1" 420 | LinkLabel "1 GB/s" 421 | LinkSpeedUnits "G" 422 | LinkSpeedRaw 1000000000.0 423 | ] 424 | 425 | edge [ 426 | source 4 427 | target 23 428 | LinkSpeed "10" 429 | LinkLabel "10 GB/s" 430 | LinkSpeedUnits "G" 431 | LinkSpeedRaw 10000000000.0 432 | ] 433 | edge [ 434 | source 4 435 | target 5 436 | LinkSpeed "1" 437 | LinkLabel "1 GB/s" 438 | LinkSpeedUnits "G" 439 | LinkSpeedRaw 1000000000.0 440 | ] 441 | edge [ 442 | source 4 443 | target 15 444 | LinkSpeed "1" 445 | LinkLabel "1 GB/s" 446 | LinkSpeedUnits "G" 447 | LinkSpeedRaw 1000000000.0 448 | ] 449 | edge [ 450 | source 5 451 | target 8 452 | LinkSpeed "1" 453 | LinkLabel "1 GB/s" 454 | LinkSpeedUnits "G" 455 | LinkSpeedRaw 1000000000.0 456 | ] 457 | edge [ 458 | source 6 459 | target 20 460 | LinkSpeed "1" 461 | LinkLabel "1 GB/s" 462 | LinkSpeedUnits "G" 463 | LinkSpeedRaw 1000000000.0 464 | ] 465 | edge [ 466 | source 7 467 | target 9 468 | LinkLabel "10 GB/s - redundantno" 469 | ] 470 | edge [ 471 | source 7 472 | target 18 473 | LinkSpeed "1" 474 | LinkLabel "1 GB/s" 475 | LinkSpeedUnits "G" 476 | LinkSpeedRaw 1000000000.0 477 | ] 478 | edge [ 479 | source 7 480 | target 20 481 | LinkSpeed "1" 482 | LinkLabel "1 GB/s" 483 | LinkSpeedUnits "G" 484 | LinkSpeedRaw 1000000000.0 485 | ] 486 | edge [ 487 | source 7 488 | target 21 489 | LinkSpeed "1" 490 | LinkLabel "1 GB/s" 491 | LinkSpeedUnits "G" 492 | LinkSpeedRaw 1000000000.0 493 | ] 494 | edge [ 495 | source 7 496 | target 23 497 | LinkLabel "10 GB/s - redundantno" 498 | ] 499 | edge [ 500 | source 7 501 | target 30 502 | LinkLabel "10 GB/s - redundantno" 503 | ] 504 | edge [ 505 | source 8 506 | target 9 507 | LinkSpeed "1" 508 | LinkLabel "1 GB/s" 509 | LinkSpeedUnits "G" 510 | LinkSpeedRaw 1000000000.0 511 | ] 512 | edge [ 513 | source 9 514 | target 19 515 | LinkSpeed "1" 516 | LinkLabel "1 GB/s" 517 | LinkSpeedUnits "G" 518 | LinkSpeedRaw 1000000000.0 519 | ] 520 | edge [ 521 | source 10 522 | target 17 523 | LinkSpeed "1" 524 | LinkLabel "1 GB/s" 525 | LinkSpeedUnits "G" 526 | LinkSpeedRaw 1000000000.0 527 | ] 528 | edge [ 529 | source 10 530 | target 22 531 | LinkSpeed "10" 532 | LinkLabel "10 GB/s" 533 | LinkSpeedUnits "G" 534 | LinkSpeedRaw 10000000000.0 535 | ] 536 | edge [ 537 | source 11 538 | target 12 539 | LinkSpeed "1" 540 | LinkLabel "1 GB/s" 541 | LinkSpeedUnits "G" 542 | LinkSpeedRaw 1000000000.0 543 | ] 544 | edge [ 545 | source 11 546 | target 30 547 | LinkSpeed "1" 548 | LinkLabel "1 GB/s" 549 | LinkSpeedUnits "G" 550 | LinkSpeedRaw 1000000000.0 551 | ] 552 | edge [ 553 | source 12 554 | target 26 555 | LinkSpeed "1" 556 | LinkLabel "1 GB/s" 557 | LinkSpeedUnits "G" 558 | LinkSpeedRaw 1000000000.0 559 | ] 560 | edge [ 561 | source 13 562 | target 29 563 | LinkSpeed "1" 564 | LinkLabel "1 GB/s" 565 | LinkSpeedUnits "G" 566 | LinkSpeedRaw 1000000000.0 567 | ] 568 | edge [ 569 | source 14 570 | target 16 571 | LinkSpeed "1" 572 | LinkLabel "1 GB/s" 573 | LinkSpeedUnits "G" 574 | LinkSpeedRaw 1000000000.0 575 | ] 576 | edge [ 577 | source 14 578 | target 17 579 | LinkSpeed "1" 580 | LinkLabel "1 GB/s" 581 | LinkSpeedUnits "G" 582 | LinkSpeedRaw 1000000000.0 583 | ] 584 | edge [ 585 | source 14 586 | target 18 587 | LinkSpeed "1" 588 | LinkLabel "1 GB/s" 589 | LinkSpeedUnits "G" 590 | LinkSpeedRaw 1000000000.0 591 | ] 592 | edge [ 593 | source 17 594 | target 19 595 | LinkSpeed "1" 596 | LinkLabel "1 GB/s" 597 | LinkSpeedUnits "G" 598 | LinkSpeedRaw 1000000000.0 599 | ] 600 | edge [ 601 | source 17 602 | target 23 603 | LinkSpeed "1" 604 | LinkLabel "1 GB/s" 605 | LinkSpeedUnits "G" 606 | LinkSpeedRaw 1000000000.0 607 | ] 608 | edge [ 609 | source 22 610 | target 23 611 | LinkSpeed "10" 612 | LinkLabel "10 GB/s" 613 | LinkSpeedUnits "G" 614 | LinkSpeedRaw 10000000000.0 615 | ] 616 | edge [ 617 | source 24 618 | target 32 619 | LinkSpeed "1" 620 | LinkLabel "1 GB/s" 621 | LinkSpeedUnits "G" 622 | LinkSpeedRaw 1000000000.0 623 | ] 624 | edge [ 625 | source 24 626 | target 25 627 | LinkSpeed "1" 628 | LinkLabel "1 GB/s" 629 | LinkSpeedUnits "G" 630 | LinkSpeedRaw 1000000000.0 631 | ] 632 | edge [ 633 | source 25 634 | target 32 635 | LinkSpeed "1" 636 | LinkLabel "1 GB/s" 637 | LinkSpeedUnits "G" 638 | LinkSpeedRaw 1000000000.0 639 | ] 640 | edge [ 641 | source 26 642 | target 27 643 | LinkSpeed "1" 644 | LinkLabel "1 GB/s" 645 | LinkSpeedUnits "G" 646 | LinkSpeedRaw 1000000000.0 647 | ] 648 | edge [ 649 | source 27 650 | target 28 651 | LinkSpeed "1" 652 | LinkLabel "1 GB/s" 653 | LinkSpeedUnits "G" 654 | LinkSpeedRaw 1000000000.0 655 | ] 656 | edge [ 657 | source 28 658 | target 29 659 | LinkSpeed "1" 660 | LinkLabel "1 GB/s" 661 | LinkSpeedUnits "G" 662 | LinkSpeedRaw 1000000000.0 663 | ] 664 | edge [ 665 | source 29 666 | target 30 667 | LinkSpeed "1" 668 | LinkLabel "1 GB/s" 669 | LinkSpeedUnits "G" 670 | LinkSpeedRaw 1000000000.0 671 | ] 672 | edge [ 673 | source 30 674 | target 32 675 | LinkSpeed "1" 676 | LinkLabel "1 GB/s" 677 | LinkSpeedUnits "G" 678 | LinkSpeedRaw 1000000000.0 679 | ] 680 | edge [ 681 | source 30 682 | target 31 683 | LinkSpeed "1" 684 | LinkLabel "1 GB/s" 685 | LinkSpeedUnits "G" 686 | LinkSpeedRaw 1000000000.0 687 | ] 688 | edge [ 689 | source 32 690 | target 33 691 | LinkSpeed "1" 692 | LinkLabel "1 GB/s" 693 | LinkSpeedUnits "G" 694 | LinkSpeedRaw 1000000000.0 695 | ] 696 | ] 697 | -------------------------------------------------------------------------------- /Qlearning_SDN-Copy1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | # In[20]: 5 | 6 | 7 | #--------Graph Building Begins-------------------------- 8 | from __future__ import division 9 | import numpy as np 10 | import time 11 | import networkx as nx 12 | import random 13 | from random import shuffle 14 | from math import radians, cos, sin, asin, sqrt 15 | from random import randrange 16 | from collections import defaultdict 17 | import matplotlib.pylab as plt 18 | import pandas as pd 19 | import csv 20 | import math 21 | import copy 22 | 23 | k=int(input("enter no of controllers: ")) 24 | start=time.time() 25 | graph=nx.read_gml('Arnes.gml',label='id') 26 | 27 | Lat=nx.get_node_attributes(graph,"Latitude") 28 | Long=nx.get_node_attributes(graph,"Longitude") 29 | for v in list(graph.nodes): 30 | if Lat.get(v) == None or Long.get(v) == None: 31 | graph.remove_node(v) 32 | 33 | # Removing the vertices of degree 0 34 | nodes = list(graph.nodes) 35 | for node in nodes: 36 | if nx.is_isolate(graph,node): 37 | graph.remove_node(node) 38 | 39 | def distance_calculate_using_lat_long(node_0, node_1): 40 | 41 | lon_x = Long.get(node_0) 42 | lon_y = Long.get(node_1) 43 | lat_x = Lat.get(node_0) 44 | lat_y = Lat.get(node_1) 45 | # # The math module contains a function named 46 | # radians which converts from degrees to radians. 47 | lon1 = float(radians(lon_x) ) 48 | lon2 = float(radians(lon_y) ) 49 | lat1 = float(radians(lat_x) ) 50 | lat2 = float(radians(lat_y) ) 51 | 52 | # Haversine formula 53 | dlon = lon2 - lon1 54 | dlat = lat2 - lat1 55 | a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 56 | 57 | c = 2 * asin(sqrt(a)) 58 | #print 'value of c', c 59 | 60 | # Radius of earth in kilometers. Use 3956 for miles 61 | r = 6371 62 | 63 | # # calculate the result 64 | distance= c * r 65 | return distance 66 | 67 | 68 | 69 | 70 | for node in list(graph.nodes): 71 | for neighbor in list(graph.neighbors(node)): 72 | graph[node][neighbor]['weight'] = distance_calculate_using_lat_long( 73 | node,neighbor) 74 | 75 | edges = list(graph.edges) 76 | for edge in edges: 77 | try: 78 | graph.edges[edge]['weight'] 79 | except KeyError: 80 | graph.remove_edge(edge[0],edge[1]) 81 | 82 | 83 | 84 | print(nx.info(graph)) 85 | n=nx.number_of_nodes(graph) 86 | 87 | 88 | adj_list = [] 89 | for i in range(0, n): 90 | l = [] 91 | adj_list.append(l) 92 | 93 | for x in graph.edges: 94 | i,j = x 95 | adj_list[i].append(j) 96 | adj_list[j].append(i) 97 | 98 | 99 | #random sampling for controller index selection. 100 | controller=random.sample(range(0, n), k) 101 | #controller=[1,14,9,26] 102 | 103 | #cONTROLLERS SET 104 | controller_max = copy.deepcopy(controller) 105 | 106 | print("controllers : ",controller,"\n") 107 | lol = [] 108 | for i in range(0,k): 109 | lol.append([]) 110 | 111 | def BFS(queue,adj_list,listx): 112 | while queue: 113 | p = queue.pop(0) 114 | u , w = p 115 | for v in adj_list[u]: 116 | if listx[v] == 100000007: 117 | listx[v] = w + 1 118 | queue.append((v, w + 1)) 119 | return listx 120 | 121 | index=0 122 | for j in range(0,k): 123 | listx = (n)*[100000007] 124 | listx[controller[index]] = 0 125 | queue = [] 126 | queue.append((controller[index], 0)) 127 | listx = BFS(queue,adj_list,listx) 128 | lol[j]=listx 129 | index+=1 130 | 131 | 132 | 133 | def transpose(lol, transpose_list): 134 | transpose_list =[[row[i] for row in lol] for i in range(len(lol[0]))] 135 | return transpose_list 136 | 137 | transpose_list = [] 138 | transpose_list = transpose(lol, transpose_list) 139 | 140 | 141 | minumum_pos=[] 142 | 143 | for x in transpose_list: 144 | min_ele= n+5 145 | for i in range(0,len(x)): 146 | if x[i] d[(node2,node1)] + d[(node1,node3)]: 195 | d[(node2,node3)] = d[(node2,node1)] + d[(node1,node3)] 196 | d[(node3,node2)] = d[(node2,node3)] 197 | 198 | return d 199 | 200 | dist=floyd_warshall(graph) 201 | 202 | 203 | #print("After initialization \n") 204 | #print(final) 205 | 206 | frame = pd.read_csv('data2.csv') 207 | #print(frame) 208 | 209 | nodes = list(graph.nodes) 210 | #print('Original nodes') 211 | #print(nodes) 212 | 213 | #Shuffled nodes 214 | #print('Shuffled nodes') 215 | shuffle(nodes) 216 | #print(nodes) 217 | 218 | #x=dict(zip(frame.columns,nodes)) 219 | #print(x) 220 | 221 | frame = frame.rename(columns = dict(zip(frame.columns,nodes))) 222 | #print(frame) 223 | 224 | load_array = [] 225 | for i in frame.index: 226 | Load = dict(frame.loc[i]) 227 | load_array.append(Load) 228 | 229 | # I have redone this because some keys are strings and repeated 230 | # Load = {int(k):v for k,v in Load.items()} 231 | 232 | #------------------------------------------------------------------# 233 | 234 | 235 | # In[21]: 236 | 237 | 238 | #Classify the domain based on load as Overloaded, Underloaded 239 | def classify_domain(cluster_load,no_of_controller): 240 | #Mean load 241 | mean_load = sum([y for x,y in cluster_load.items()]) 242 | mean_load = mean_load/no_of_controller 243 | O_domain = [] 244 | I_domain = [] 245 | for controller1,controller_load in cluster_load.items(): 246 | if(controller_load > mean_load): 247 | O_domain.append(controller1) 248 | else: 249 | I_domain.append(controller1) 250 | return [O_domain,I_domain,mean_load] 251 | 252 | 253 | #To update the load 254 | def update_load(cluster_load,i,current_state,cnt,current_switch): 255 | cluster_load[current_state] = cluster_load[current_state]-load_array[i][current_switch]; 256 | cluster_load[cnt] = cluster_load[cnt]+load_array[i][current_switch]; 257 | return 258 | 259 | # The function which returns all available actions in state given as an argument 260 | def available_actions(k): 261 | return [item for item in range(0, k)] 262 | 263 | #calculating the mean load 264 | def load_rate(cluster_load,mean_load,no_of_controller): 265 | s=0 266 | for controller1,controller_load in cluster_load.items(): 267 | s = s + abs(controller_load - mean_load) 268 | s = s/no_of_controller 269 | return s 270 | 271 | #load ratio calculate 272 | def load_ratio_calculate(controller1,cluster_load): 273 | return cluster_load[controller1] 274 | 275 | 276 | # In[22]: 277 | 278 | 279 | #populating cluster load array 280 | #{c1:36363663,c2:3234325,c3,32523525,c4:3523535,c5:3542646} of this form 281 | 282 | def calculate_load(time_step): 283 | cluster_load = defaultdict(lambda:0) 284 | for center in controller: 285 | #print(center) 286 | for node in controller_set: 287 | #print(node) 288 | if center in node: 289 | for switch in node: 290 | #print(switch) 291 | cluster_load [center] += load_array[time_step][switch] 292 | return cluster_load 293 | 294 | #For switch selection randomly 295 | def switch_select(ind,current_cont): 296 | if(len(controller_set[ind]) == 1): 297 | return -1 298 | x = random.choice(controller_set[ind]) 299 | #To avoid controller to be selected itself 300 | while(x == current_cont): 301 | x = random.choice(controller_set[ind]) 302 | return x 303 | 304 | #Random controller selection 305 | def random_action(available_act,control): 306 | next_action = int(np.random.choice(available_act,1)) 307 | while(next_action == control): 308 | next_action = int(np.random.choice(available_act,1)) 309 | return next_action 310 | 311 | #Migration of switch from source to target 312 | def migrate_switch(ind_of_controller,target_controller,current_switch): 313 | controller_set[ind_of_controller].remove(current_switch) 314 | controller_set[target_controller].append(current_switch) 315 | return 316 | 317 | #Selection of switch 318 | def switch_select_mx(ind,current_cont): 319 | if(len(controller_set[ind]) == 1): 320 | return -1 321 | x = random.choice(controller_set[ind]) 322 | while(x == current_cont): 323 | x = random.choice(controller_set[ind]) 324 | return x 325 | 326 | 327 | # In[23]: 328 | 329 | 330 | #Random Approch 331 | #For making graph 332 | x1 = [] #For storing time steps 333 | y1 = [] #For load balance rate 334 | z1 = [] #For number of switches 335 | 336 | load_rate_array = [] #(load balance rate, number of switches) 337 | migration_cost_random = 0 338 | migration_array_random = [] 339 | normalize = 10**9 340 | #Training over 5,000 iterations(time steps). 341 | for i in range(0,1000): 342 | print('At time steps =',i) 343 | 344 | #default dictionary to store load of each controller{k:load(k) for each k} 345 | cluster_load = defaultdict(lambda:0) 346 | cluster_load = calculate_load(i) 347 | switch_array = [] 348 | 349 | #To classify the controllers on the basis of load taking mean_load as ideal 350 | #O_domain = Set of overloded domain 351 | #I_domain = Set of undeloaded domain 352 | O_domain,I_domain,mean_load = classify_domain(cluster_load,k) 353 | print('Overloaded domains are = ',O_domain) 354 | 355 | migration_cost_random = 0 356 | #loop until all O_domain are balanced 357 | while(len(O_domain) >=1 ): 358 | 359 | #Picking a random overloaded domain 360 | current_state = random.choice(O_domain) 361 | O_domain.remove(current_state) 362 | 363 | #do until the choosen controller becomes balanced i.e. its load becomes less than or equal to mean_load 364 | while(cluster_load[current_state] > mean_load): 365 | 366 | #state = current_state 367 | print('Balancing controller',current_state) 368 | 369 | print('Controller\tController_Load') 370 | for C,C_load in cluster_load.items(): 371 | print(C,' :\t',C_load) 372 | 373 | #for switch selection 374 | ind_of_controller = controller.index(current_state) 375 | current_switch = switch_select(ind_of_controller,current_state) 376 | print('Source controller set ',current_state,' : ',controller_set[ind_of_controller]) 377 | 378 | if(current_switch == -1): 379 | break; 380 | 381 | print('switch selected is',current_switch) 382 | switch_array.append(current_switch) 383 | 384 | #available action and choosing random from it 385 | available_act = available_actions(k) 386 | target_controller = random_action(available_act,ind_of_controller) 387 | print('Target controller set ',controller[target_controller],' : ',controller_set[target_controller]) 388 | 389 | migrate_switch(ind_of_controller,target_controller,current_switch) 390 | update_load(cluster_load,i,current_state,controller[target_controller],current_switch) 391 | 392 | if(dist[current_state,current_switch] - dist[controller[target_controller],current_switch] > 0): 393 | migration_cost_random = migration_cost_random + 6*(2*dist[controller[target_controller],current_state] + load_array[i][current_switch]*(abs(dist[current_state,current_switch] - dist[controller[target_controller],current_switch]))) 394 | else: 395 | migration_cost_random = migration_cost_random + 6*(2*dist[controller[target_controller],current_state]) 396 | 397 | 398 | print('\n') 399 | 400 | migration_array_random.append(migration_cost_random/normalize) 401 | #load balancing rate 402 | l_rate = load_rate(cluster_load,mean_load,k) 403 | 404 | y1.append(l_rate) 405 | x1.append(i) 406 | load_rate_array.append([l_rate,len(switch_array)]) 407 | z1.append(len(switch_array)) 408 | print('At Time step ',i,' number of switch migrated are : ',len(switch_array)) 409 | print('Migrated Switches are ',switch_array) 410 | 411 | print('---------------------------------------------------------------------------------------------------------------------------') 412 | 413 | 414 | # In[11]: 415 | 416 | 417 | #For Q-learning 418 | def calculate_load_max(time_step): 419 | cluster_load = defaultdict(lambda:0) 420 | for center in controller_max: 421 | #print(center) 422 | for node in controller_set_max: 423 | #print(node) 424 | if center in node: 425 | for switch in node: 426 | #print(switch) 427 | cluster_load [center] += load_array[time_step][switch] 428 | return cluster_load 429 | 430 | #max_load switch select 431 | 432 | def switch_max_select(ind,current_cont,time_st): 433 | if(len(controller_set_max[ind]) == 1): 434 | return -1 435 | x = controller_set_max[ind] 436 | load_x = [] 437 | for i in x: 438 | load_x.append((load_array[time_st][i],i)) 439 | load_x.sort(reverse=True) 440 | print(load_x) 441 | if(load_x[0][1] == current_cont): 442 | return load_x[1][1] 443 | return load_x[0][1] 444 | 445 | #return I domain 446 | def find_underloaded(cluster_load,mean_load): 447 | I_domain = [] 448 | for controller1,controller_load in cluster_load.items(): 449 | if(controller_load < mean_load): 450 | I_domain.append(controller1) 451 | return I_domain 452 | 453 | 454 | 455 | def sample_next_action(available_act,control,epsilon,Q_greedy): 456 | 457 | ran = np.random.random() 458 | next_action = -1 459 | 460 | if(ran < epsilon): 461 | next_action = int(np.random.choice(available_act,1)) 462 | while(next_action == control): 463 | next_action = int(np.random.choice(available_act,1)) 464 | else: 465 | ls = [] 466 | for i in available_act: 467 | ind = controller_max.index(i) 468 | if(ind != control): 469 | ls.append(ind) 470 | 471 | max_ele = Q_greedy[control][ls[0]] 472 | next_action = controller_max[ls[0]] 473 | if(len(ls)>1): 474 | for i in range(1,len(ls)): 475 | if(max_ele < Q_greedy[control][ls[i]]): 476 | max_ele = Q_greedy[control][ls[i]] 477 | next_action = controller_max[ls[i]] 478 | return next_action 479 | 480 | 481 | def deviation_calculate(R_ini,R_tar): 482 | mean = (R_ini + R_tar)/2; 483 | x = math.sqrt(((R_ini - mean)**2 + (R_tar - mean)**2)/2) 484 | x = x/mean 485 | return x 486 | 487 | def migrate_switch_max(ind_of_controller,target_controller,current_switch): 488 | controller_set_max[ind_of_controller].remove(current_switch) 489 | controller_set_max[target_controller].append(current_switch) 490 | return 491 | 492 | 493 | # In[24]: 494 | 495 | 496 | #Q-matrix 497 | 498 | #size equals to number of states. 499 | Q_greedy = np.ones([k,k]) 500 | 501 | #Q(state,action) = Q[current_state,action] + alpha*(R[current_state,action] + gamma*max_value - Q[current_state,action]) 502 | 503 | #learning parameters 504 | #Learning rate 505 | alpha = 0.6; 506 | #Gamma 507 | #between 0 and 1 508 | gamma = 0.7 509 | 510 | 511 | def update_greedyQL(current_state,action,gamma,reward): 512 | #selecting maximum in target controller considering as new state 513 | 514 | l = [] 515 | maximum_ele = Q_greedy[action,0] 516 | t = range(1,len(Q_greedy[action,])) 517 | for i in t: 518 | if(Q_greedy[action,i] >= maximum_ele): 519 | maximum_ele = Q_greedy[action,i] 520 | 521 | for i in range(0,len(Q_greedy[action,])): 522 | if(Q_greedy[action,i] == maximum_ele): 523 | l.append(i) 524 | 525 | #if more than one maximum 526 | max_index = np.random.choice(l) 527 | 528 | #for max term 529 | max_value=Q_greedy[action, max_index] 530 | 531 | Q_greedy[current_state,action] = Q_greedy[current_state,action] + alpha*(reward + gamma*max_value - Q_greedy[current_state,action]) 532 | print('Q value = ',Q_greedy[current_state,action]) 533 | return 534 | 535 | #For making graph 536 | x2 = [] #For storing time steps 537 | y2 = [] #For load balance rate 538 | z2 = [] #For number of switches 539 | 540 | reward_array = [] 541 | load_rate_array_QL = [] 542 | 543 | migration_cost=0 544 | migration_array_greedy = [] 545 | 546 | epsilon = 0.001 547 | epsilon_dec = 0.0025 548 | epsilon_min = 0.05 549 | 550 | load_controller = [] 551 | 552 | #Training over 5,000 iterations(time steps). 553 | for i in range(0,1000): 554 | print('At time steps =',i) 555 | 556 | #default dictionary to store load of each controller{k:load(k) for each k} 557 | cluster_load = defaultdict(lambda:0) 558 | 559 | cluster_load = calculate_load_max(i) 560 | switch_array = [] 561 | 562 | #To classify the controllers on the basis of load taking mean_load as ideal 563 | #O_domain = Set of overloded domain 564 | #I_domain = Set of undeloaded domain 565 | O_domain,I_domain,mean_load = classify_domain(cluster_load,k) 566 | print('Overloaded domains are = ',O_domain) 567 | 568 | #migration_cost = 0 569 | 570 | #loop until all O_domain are balanced 571 | while(len(O_domain) >=1 ): 572 | 573 | #Picking a random overloaded domain 574 | current_state = random.choice(O_domain) 575 | O_domain.remove(current_state) 576 | 577 | #do until the choosen controller becomes balanced i.e. its load becomes less than or equal to mean_load 578 | while(cluster_load[current_state] > mean_load): 579 | 580 | print('Balancing controller',current_state) 581 | 582 | print('Controller\tController_Load') 583 | for C,C_load in cluster_load.items(): 584 | print(C,' :\t',C_load) 585 | 586 | #for switch selection 587 | ind_of_controller = controller_max.index(current_state) 588 | 589 | current_switch = switch_max_select(ind_of_controller,current_state,i) 590 | print('Source controller set ',current_state,' : ',controller_set_max[ind_of_controller]) 591 | 592 | if(current_switch == -1): 593 | break; 594 | print('switch selected is',current_switch) 595 | switch_array.append(current_switch) 596 | 597 | ###### 598 | Underloaded_domain = find_underloaded(cluster_load,mean_load) 599 | print('Underloaded domain are = ',Underloaded_domain) 600 | 601 | #available action and choosing in epsilon greedy approch 602 | target = sample_next_action(Underloaded_domain,ind_of_controller,epsilon,Q_greedy) 603 | target_controller = controller_max.index(target) 604 | 605 | print('Target controller set ',controller_max[target_controller],' : ',controller_set_max[target_controller]) 606 | print('Mean Load = ',mean_load) 607 | 608 | #Reward calculation 609 | R_initial = load_ratio_calculate(current_state,cluster_load) 610 | R_target = load_ratio_calculate(controller_max[target_controller],cluster_load) 611 | D_t = deviation_calculate(R_initial, R_target) 612 | 613 | migrate_switch_max(ind_of_controller,target_controller,current_switch) 614 | update_load(cluster_load,i,current_state,controller_max[target_controller],current_switch) 615 | 616 | R_initial = load_ratio_calculate(current_state,cluster_load) 617 | R_target = load_ratio_calculate(controller_max[target_controller],cluster_load) 618 | D_tt = deviation_calculate(R_initial, R_target) 619 | 620 | 621 | 622 | #(D_tt - D_t) 623 | reward = (-D_tt + D_t) 624 | print('Reward = ',reward) 625 | 626 | 627 | 628 | 629 | update_greedyQL(ind_of_controller,target_controller,gamma,reward) 630 | print('\n') 631 | 632 | if(epsilon > epsilon_min): 633 | epsilon = epsilon*epsilon_dec 634 | else: 635 | epsilon = epsilon_min 636 | 637 | # migration_array_greedy.append(migration_cost) 638 | #load balancing rate 639 | l_rate = load_rate(cluster_load,mean_load,k) 640 | 641 | reward_array.append(reward) 642 | 643 | y2.append(l_rate) 644 | x2.append(i) 645 | z2.append(len(switch_array)) 646 | 647 | load_controller.append(cluster_load) 648 | 649 | load_rate_array_QL.append([l_rate,len(switch_array)]) 650 | 651 | print('At Time step ',i,' number of switch migrated are : ',len(switch_array)) 652 | print('Migrated Switches are ',switch_array) 653 | 654 | print('---------------------------------------------------------------------------------------------------------------------------') 655 | print(Q_greedy) 656 | 657 | 658 | # In[25]: 659 | 660 | 661 | x = [] 662 | 663 | yrandom = [] 664 | yQl = [] 665 | 666 | zrandom = [] 667 | zQl = [] 668 | 669 | wrandom = [] 670 | wQl = [] 671 | 672 | for i in range(500,1000,20): 673 | x.append(x1[i]) 674 | 675 | yrandom.append(y1[i]) 676 | yQl.append(y2[i]) 677 | 678 | zrandom.append(z1[i]) 679 | zQl.append(z2[i]) 680 | 681 | #wrandom.append(migration_array_random[i]) 682 | #wQl.append(migration_array_greedy[i]) 683 | 684 | 685 | # In[26]: 686 | 687 | 688 | import matplotlib.pyplot as plt 689 | 690 | plt.plot(x,yrandom,label='Random Selection') 691 | #plt.plot(x,ygreedy,label='Greedy_QL') 692 | plt.plot(x,yQl,label='Q-Learning') 693 | plt.xlabel('Time steps') 694 | plt.ylabel('Load balancing rate') 695 | plt.legend() 696 | plt.show() 697 | 698 | 699 | # In[27]: 700 | 701 | 702 | import matplotlib.pyplot as plt 703 | 704 | plt.plot(x,zrandom,label='Random Selection') 705 | #plt.plot(x,zgreedy,label='Greedy_QL') 706 | plt.plot(x,zQl,label='Q-Learning') 707 | plt.xlabel('Time steps') 708 | plt.ylabel('Number of switches migrated') 709 | plt.legend() 710 | plt.show() 711 | 712 | 713 | # In[18]: 714 | 715 | 716 | c1 = [[],[],[],[],[]] 717 | sc = [] 718 | for i in range(0,10,2): 719 | sc.append(i) 720 | e = load_controller[i] 721 | j=0 722 | for ctrl,ctrl_load in e.items(): 723 | c1[j].append(ctrl_load) 724 | j = j+1 725 | 726 | plt.plot(sc,c1[0],label='C1') 727 | plt.plot(sc,c1[1],label='C2') 728 | plt.plot(sc,c1[2],label='C3') 729 | plt.plot(sc,c1[3],label='C4') 730 | plt.plot(sc,c1[4],label='C5') 731 | plt.xlabel('Time steps') 732 | plt.ylabel('Controller load') 733 | plt.legend() 734 | plt.show() 735 | 736 | 737 | # In[54]: 738 | 739 | 740 | import csv 741 | 742 | # field names 743 | fields = ['load_rate','Number of switches'] 744 | 745 | # name of csv file 746 | filename = "Dataset_Load_random.csv" 747 | 748 | # writing to csv file 749 | with open(filename, 'w') as csvfile: 750 | # creating a csv writer object 751 | csvwriter = csv.writer(csvfile) 752 | 753 | # writing the fields 754 | csvwriter.writerow(fields) 755 | 756 | # writing the data rows 757 | csvwriter.writerows(load_rate_array) 758 | 759 | 760 | # In[55]: 761 | 762 | 763 | # name of csv file 764 | filename = "Dataset_Load_greedy.csv" 765 | 766 | # writing to csv file 767 | with open(filename, 'w') as csvfile: 768 | # creating a csv writer object 769 | csvwriter = csv.writer(csvfile) 770 | 771 | # writing the fields 772 | csvwriter.writerow(fields) 773 | 774 | # writing the data rows 775 | csvwriter.writerows(load_rate_array_max) 776 | 777 | 778 | # In[56]: 779 | 780 | 781 | # name of csv file 782 | filename = "Dataset_Load_greedyQl.csv" 783 | 784 | # writing to csv file 785 | with open(filename, 'w') as csvfile: 786 | # creating a csv writer object 787 | csvwriter = csv.writer(csvfile) 788 | 789 | # writing the fields 790 | csvwriter.writerow(fields) 791 | 792 | # writing the data rows 793 | csvwriter.writerows(load_rate_arrayQ) 794 | 795 | --------------------------------------------------------------------------------