Created
August 24, 2019 12:40
-
-
Save ryankshah/cedadd9c509ff880f787900a669631cb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import networkx as nx | |
import matplotlib.pyplot as plt | |
from random import randrange,choices,randint | |
from pathlib import Path | |
import random | |
import secrets | |
import uuid | |
import math | |
import json | |
import os | |
# ============================================================================ # | |
# create a technician with id and provider id | |
def create_technician(): | |
return str(uuid.uuid4()) | |
# create a provider with n technicians | |
def create_provider(region_id, level, number, n): | |
id = 'p_'+str(region_id)+'_'+str(level)+'_'+str(number) | |
# Create n technicians | |
technicians = [] | |
for i in range(n): | |
technicians.append(create_technician()) | |
return {id:{'technicians': technicians}} | |
def create_nmi_technicians(n): | |
technicians = [] | |
for i in range(n): | |
technicians.append(create_technician()) | |
return technicians | |
# Create report with parents + technician | |
def create_report(device_id, level, technician, parents): | |
return {'id': device_id, 'level': level, 'technician': technician, 'parents': parents} | |
# n = number of field devices | |
def generate_graph(num_field_devices): | |
max_chain_length = int(2*math.log(num_field_devices, 10)) | |
## Info ## | |
# ====== # | |
# Field level = 0 | |
# NMI = max_chain_length-1 | |
nmi_level = str(max_chain_length-1) | |
regions = { | |
'USA': {'id': '1', 'NMI': {'level': nmi_level, 'acronym': 'NIST', 'technicians': create_nmi_technicians(5)}}, | |
'UK': {'id': '2', 'NMI': {'level': nmi_level, 'acronym': 'NPL', 'technicians': create_nmi_technicians(4)}}, | |
'China': {'id': '3', 'NMI': {'level': nmi_level, 'acronym': 'NIM', 'technicians': create_nmi_technicians(3)}}, | |
'France': {'id': '4', 'NMI': {'level': nmi_level, 'acronym': 'LNE', 'technicians': create_nmi_technicians(3)}} | |
} | |
# For each region, create a set of | |
# 1 to m calibration service | |
# providers for each level up to | |
# the field level | |
for region, data in regions.items(): | |
# Create providers dict | |
providers = {} | |
# For range between field (0) and | |
# max_chain_length-2, create providers | |
for i in range(0, max_chain_length-1): | |
# Choose between 2 and 5 providers | |
m = randint(2, 5) | |
x = 0 | |
for j in range(m): | |
# create provider with 1-3 technicians | |
providers.update(create_provider(data['id'], i, x, randint(1,3))) | |
x = x + 1 | |
# Add providers to region | |
data.update({'providers': providers}) | |
#print(json.dumps(regions, indent=4)) | |
# Cool, now this is done, create the calibration | |
# reports for the chain! | |
devices = {} | |
for level in range(max_chain_length): | |
devices.update({level: []}) | |
# Field level | |
if level == 0: | |
for i in range(num_field_devices): | |
devices[level].append(str(uuid.uuid4())) | |
else: | |
k = int(math.pow((2/3), level) * num_field_devices) | |
for i in range(k): | |
devices[level].append(str(uuid.uuid4())) | |
# Create reports for these devices with parents + technician | |
reports = {} | |
for level,devs in devices.items(): | |
for device in devs: | |
if level == 0: | |
# Choose 2-3 parents from upper level | |
parents = choices(devices[level+1], k=randrange(2,4)) | |
elif level == max_chain_length-1: | |
# NMI level has no parents | |
parents = [] | |
else: | |
# Choose 1-2 parents from upper level | |
parents = choices(devices[level+1], k=randrange(1,3)) | |
# Choose random region | |
region = regions[secrets.choice(list(regions))] | |
# If NMI, use NMI technician, otherwise | |
# choose a provider from the level | |
if level == max_chain_length-1: | |
technician = secrets.choice(region['NMI']['technicians']) | |
else: | |
# Choose random provider at same level | |
providers = region['providers'] | |
provider = providers[secrets.choice(list({k:v for (k,v) in providers.items() if (k.split('_'))[2] == str(level)}))] | |
# Choose technician at the same level | |
technician = secrets.choice(provider['technicians']) | |
# Generate the conflict sets using a G_n,p random graph | |
# in_conflict = 1, no_conflict = 0 | |
g = nx.fast_gnp_random_graph(n, p) # n = number of nodes, p = probability of edge (1 ) | |
reports.update({device: create_report(device, level, technician, parents)}) | |
## Run ## | |
# ===== # | |
generate_graph(100) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment