Initial model changes and api changes for pci-opt
[optf/osdf.git] / osdf / optimizers / pciopt / solver / optimizer.py
1 # -------------------------------------------------------------------------
2 #   Copyright (c) 2018 AT&T Intellectual Property
3 #
4 #   Licensed under the Apache License, Version 2.0 (the "License");
5 #   you may not use this file except in compliance with the License.
6 #   You may obtain a copy of the License at
7 #
8 #       http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #   Unless required by applicable law or agreed to in writing, software
11 #   distributed under the License is distributed on an "AS IS" BASIS,
12 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 #   See the License for the specific language governing permissions and
14 #   limitations under the License.
15 #
16 # -------------------------------------------------------------------------
17 #
18
19 import itertools
20 import os
21
22 import pymzn
23
24 from .pci_utils import get_id
25
26 BASE_DIR = os.path.dirname(__file__)
27 MZN_FILE_NAME = os.path.join(BASE_DIR, 'no_conflicts_no_confusion.mzn')
28
29
30 def pci_optimize(network_cell_info, cell_info_list):
31     neighbor_edges = get_neighbor_list(network_cell_info)
32     second_level_edges = get_second_level_neighbor(network_cell_info)
33     dzn_data = {
34         'NUM_NODES': len(cell_info_list),
35         'NUM_PCIS': len(cell_info_list),
36         'NUM_NEIGHBORS': len(neighbor_edges),
37         'NEIGHBORS': get_list(neighbor_edges),
38         'NUM_SECOND_LEVEL_NEIGHBORS': len(second_level_edges),
39         'SECOND_LEVEL_NEIGHBORS': get_list(second_level_edges)
40     }
41
42     return solve(dzn_data)
43
44
45 def get_list(edge_list):
46     array_list = []
47     for s in edge_list:
48         array_list.append([s[0], s[1]])
49     return sorted(array_list)
50
51
52 def solve(dzn_data):
53     return pymzn.minizinc(MZN_FILE_NAME, data=dzn_data)
54
55
56 def get_neighbor_list(network_cell_info):
57     neighbor_list = set()
58     for cell in network_cell_info['cell_list']:
59         add_to_neighbor_list(network_cell_info, cell, neighbor_list)
60     return neighbor_list
61
62
63 def add_to_neighbor_list(network_cell_info, cell, neighbor_list):
64     for nbr in cell.get('nbr_list', []):
65         host_id = cell['id']
66         nbr_id = get_id(network_cell_info, nbr['cellId'])
67         if nbr_id and host_id != nbr_id:
68             neighbor_list.add((host_id, nbr_id))
69
70
71 def get_second_level_neighbor(network_cell_info):
72     second_neighbor_list = set()
73     for cell in network_cell_info['cell_list']:
74         comb_list = build_second_level_list(network_cell_info, cell)
75         for comb in comb_list:
76             if comb[0] and comb[1]:
77                 second_neighbor_list.add((comb[0], comb[1]))
78     return sorted(second_neighbor_list)
79
80
81 def build_second_level_list(network_cell_info, cell):
82     second_nbr_list = []
83     for nbr in cell.get('nbr_list', []):
84         second_nbr_list.append(get_id(network_cell_info, nbr['cellId']))
85     return [list(elem) for elem in list(itertools.combinations(second_nbr_list, 2))]