def set_optimal_res(self, params): """ Parameters ---------- params : TYPE DESCRIPTION. Returns ------- None. """ results_folder = params['OUTPUT_DIR'].replace( params['OUTPUT_DIR'].split('/')[-1], "") out_dir_suffix_res = indp.get_resource_suffix(params) action_file = results_folder + 'indp_results' + '_L' + str(len(params["L"])) + '_m' + \ str(params["MAGNITUDE"]) + "_v" + out_dir_suffix_res + '/actions_' + str( params["SIM_NUMBER"]) + '_.csv' if os.path.isfile(action_file): with open(action_file) as f: lines = f.readlines()[1:] for line in lines: data = line.strip().split(',') t = int(data[0]) action = str.strip(data[1]) act_split = action.split('.') l = int(act_split[-1]) for rc in params['V'].keys(): if rc not in self.v_r[t][l].keys(): self.v_r[t][l][rc] = 0 if '/' in action: act_split2 = act_split[1].split('/') arc_obj = params['N'].G[(int( act_split[0]), int(act_split2[0]))][(int( act_split2[1]), int(act_split[2]))] addition = 0.5 * arc_obj['data'][ 'inf_data'].resource_usage['h_' + rc] else: node_obj = params['N'].G.nodes[(int(act_split[0]), int(act_split[1]))] addition = 1.0 * node_obj['data'][ 'inf_data'].resource_usage['p_' + rc] self.v_r[t][l][rc] += addition for t, val in self.v_r.items( ): # Make sure that resource values are integer for l, val_l in val.items(): for rc in params['V'].keys(): try: self.v_r[t][l][rc] = int(val_l[rc]) except KeyError: self.v_r[t][l][rc] = 0 else: sys.exit('No optimal action file for the resource allocation type OPTIMAL.' + \ ' Mag ' + str(params["MAGNITUDE"]) + ' Sample ' + str(params["SIM_NUMBER"]) + \ ' Rc ' + str(params["V"]))
def set_out_dir(self, root, mag): """ Parameters ---------- root : TYPE DESCRIPTION. mag : TYPE DESCRIPTION. Returns ------- output_dir : TYPE DESCRIPTION. """ out_dir_suffix_res = indp.get_resource_suffix( {'V': self.resource.sum_resource}) output_dir = root + '_L' + str(len(self.layers)) + '_m' + str(mag) + "_v" + \ out_dir_suffix_res + '_' + self.judge_type + '_' + self.res_alloc_type if self.res_alloc_type == 'AUCTION': a_model = next(iter(self.resource.auction_model.values())) output_dir += '_' + a_model.auction_type + '_' + a_model.valuation_type return output_dir
def run_game(params, save_results=True, print_cmd=True, save_model=False, plot2D=False): """ Finds interdependent restoration strategies using a decentralized heuristic, Judgment Call :cite:`Talebiyan2019c,Talebiyan2019`. Parameters ---------- params : dict Global parameters, including number of iterations, game type, etc. save_results : bool, optional Should the results be written to file. The default is True. print_cmd : bool, optional If true, the results are printed to console. The default is True. plot2D : bool, optional Should the payoff matrix be plotted (only for 2-players games). The default is False. save_model : bool, optional Should the games and indp models to compute payoffs be written to file. The default is False. Returns ------- : None """ if "NUM_ITERATIONS" not in params: params["NUM_ITERATIONS"] = 1 num_iterations = params["NUM_ITERATIONS"] # Creating game objects c = 0 objs = {} params_copy = copy.deepcopy(params) # !!! deepcopy for jc in params["JUDGMENT_TYPE"]: params_copy['JUDGMENT_TYPE'] = jc for rst in params["RES_ALLOC_TYPE"]: params_copy['RES_ALLOC_TYPE'] = rst out_dir_suffix_res = indp.get_resource_suffix(params_copy) if rst not in ["MDA", "MAA", "MCA"]: output_dir_full = params["OUTPUT_DIR"] + '_L' + str(len(params["L"])) + '_m' + \ str(params["MAGNITUDE"]) + "_v" + out_dir_suffix_res + '_' + jc + \ '_' + rst + '/actions_' + str(params["SIM_NUMBER"]) + '_.csv' if os.path.exists(output_dir_full): print('Game:', rst, 'results are already there\n') else: objs[c] = gameclasses.InfrastructureGame(params_copy) c += 1 else: for vt in params["VALUATION_TYPE"]: params_copy['VALUATION_TYPE'] = vt output_dir_full = params["OUTPUT_DIR"] + '_L' + str(len(params["L"])) + '_m' + \ str(params["MAGNITUDE"]) + "_v" + out_dir_suffix_res + '_' + jc + \ '_AUCTION_' + rst + '_' + vt + '/actions_' + \ str(params["SIM_NUMBER"]) + '_.csv' if os.path.exists(output_dir_full): print('Game:', rst, vt, 'results are already there\n') else: objs[c] = gameclasses.InfrastructureGame(params_copy) c += 1 # Run games if not objs: return 0 # t=0 costs and performance. v_0 = {x: 0 for x in params["V"].keys()} indp_results_initial = indp.indp(objs[0].net, v_0, 1, objs[0].layers, controlled_layers=objs[0].layers) for _, obj in objs.items(): print('--Running Game: ' + obj.game_type + ', resource allocation: ' + obj.res_alloc_type) if obj.resource.type == 'AUCTION': print('auction type: ' + obj.resource.auction_model.auction_type + \ ', valuation: ' + obj.resource.auction_model.valuation_type) if print_cmd: print("Num iters=", params["NUM_ITERATIONS"]) # t=0 results. obj.results = copy.deepcopy(indp_results_initial[1]) # !!! deepcopy # Run game obj.run_game(compute_optimal=True, plot=plot2D, save_results=save_results, print_cmd=print_cmd, save_model=save_model)
def generate_combinations(database, mags, sample, layers, no_resources, decision_type, judgment_type=[''], res_alloc_type=[''], valuation_type=[''], list_high_dam_add=None, synthetic_dir=None): """ This function returns all combinations of magnitude, sample, judgment type, resource allocation type, and valuation type (if applicable) involved in decentralized and centralized analyses. The returned dictionary are used by other functions to read results and calculate comparison measures. Parameters ---------- database : str Name of the initial damage database. \n options: For shelby county network: 'shelby', 'random', 'ANDRES', 'WU' \n For synthetic networks: 'synthetic' mags : range Range of magnitude parameter of the current simulation. sample : range Range of sample parameter of the current simulation. layers : list List of layers. no_resources : list List of number of available resources, :math:`R_c`. decision_type : list List of methods. judgment_type : list List of judgment types. res_alloc_type : list List of resource allocation methods. valuation_type : list List of valuation types. list_high_dam_add : str, optional Address of the file containing the list of damage scenarios that should be read from file. It is used to read a selected subset of results. The default is None. synthetic_dir : str, optional Address of the synthetic database files. The default is None. Returns ------- combinations : dict All combinations of magnitude, sample, judgment type, resource allocation type involved in the JC (or any other decentralized results). optimal_combinations : dict All combinations of magnitude, sample, judgment type, resource allocation type involved in the INDP (or any other optimal results). """ combinations = [] optimal_combinations = [] optimal_method = ['tdindp', 'indp', 'sample_indp_12Node', 'dp_indp'] print('\nCombination Generation\n', end='') idx = 0 no_total = len(mags) * len(sample) if database in ['shelby', 'from_csv', 'ANDRES', 'WU']: if list_high_dam_add: list_high_dam = pd.read_csv(list_high_dam_add) L = len(layers) for m, s in itertools.product(mags, sample): if list_high_dam_add is None or len(list_high_dam.loc[(list_high_dam.set == s) & \ (list_high_dam.sce == m)].index): for rc in no_resources: out_dir_suffix_res = indp.get_resource_suffix({'V': rc}) for dt, jt, at, vt in itertools.product( decision_type, judgment_type, res_alloc_type, valuation_type): if dt == 'jc': sf = 'real' else: sf = '' if (dt in optimal_method) and \ [m, s, L, out_dir_suffix_res, dt, 'nan', 'nan', 'nan', '', layers, rc] not in optimal_combinations: optimal_combinations.append([ m, s, L, out_dir_suffix_res, dt, 'nan', 'nan', 'nan', sf, layers, rc ]) elif (dt not in optimal_method) and (at not in [ 'UNIFORM', 'OPTIMAL' ]): combinations.append([ m, s, L, out_dir_suffix_res, dt, jt, at, vt, sf, layers, rc ]) elif (dt not in optimal_method) and (at in [ 'UNIFORM', 'OPTIMAL' ]): if [ m, s, L, out_dir_suffix_res, dt, jt, at, 'nan', sf, layers, rc ] not in combinations: combinations.append([ m, s, L, out_dir_suffix_res, dt, jt, at, 'nan', sf, layers, rc ]) idx += 1 update_progress(idx, no_total) elif database == 'synthetic': # Read net configurations if synthetic_dir is None: sys.exit('Error: Provide the address of the synthetic databse') with open(synthetic_dir + 'List_of_Configurations.txt') as f: config_data = pd.read_csv(f, delimiter='\t') config_data = config_data.rename(columns=lambda x: x.strip()) for m, s in itertools.product(mags, sample): config_param = config_data.iloc[m] L = int(config_param.loc['No. Layers']) no_resources = int(config_param.loc['Resource Cap']) for rc in [no_resources]: out_dir_suffix_res = '' for res, val in rc.items(): if isinstance(val, (int)): out_dir_suffix_res += res[0] + str(val) else: out_dir_suffix_res += res[0] + str( sum([lval for _, lval in val.items() ])) + '_fixed_layer_Cap' for dt, jt, at, vt in itertools.product( decision_type, judgment_type, res_alloc_type, valuation_type): if dt == 'JC': sf = 'real' else: sf = '' if (dt in optimal_method) and \ [m, s, L, out_dir_suffix_res, dt, 'nan', 'nan', 'nan', '', layers, rc] not in optimal_combinations: optimal_combinations.append([ m, s, L, out_dir_suffix_res, dt, 'nan', 'nan', 'nan', sf, layers, rc ]) elif (dt not in optimal_method) and (at not in [ 'UNIFORM', 'OPTIMAL' ]): combinations.append([ m, s, L, out_dir_suffix_res, dt, jt, at, vt, sf, layers, rc ]) elif (dt not in optimal_method) and (at in [ 'UNIFORM', 'OPTIMAL' ]): if [ m, s, L, out_dir_suffix_res, dt, jt, at, 'nan', sf, layers, rc ] not in combinations: combinations.append([ m, s, L, out_dir_suffix_res, dt, jt, at, 'nan', sf, layers, rc ]) idx += 1 update_progress(idx, no_total) else: sys.exit('Error: Wrong database type') return combinations, optimal_combinations
def read_resource_allocation(result_df, combinations, optimal_combinations, objs, ref_method='indp', root_result_dir='../results/'): """ This functions reads the resource allocation vectors by INDP and JC. Also, it computes the allocation gap between the resource allocation by JC and and the optimal allocation by INDP :cite:`Talebiyan2020a`. Parameters ---------- result_df : dict Dictionary that contains complete results by JC and INDP collected by :func:`read_results`. combinations : dict All combinations of magnitude, sample, judgment type, resource allocation type involved in the JC (or any other decentralized results) collected by :func:`generate_combinations`. optimal_combinations : dict All combinations of magnitude, sample, judgment type, resource allocation type involved in the INDP (or any other optimal results) collected by :func:`generate_combinations`. ref_method : str, optional Reference method to compute relative measure in comparison to. The default is 'indp'. root_result_dir : str, optional Directory that contains the results. The default is '../results/'. Returns ------- df_res : dict Dictionary that contain the resource allocation vectors. df_alloc_gap : dict Dictionary that contain the allocation gap values. """ cols = ['t', 'decision_type', 'judgment_type', 'auction_type', 'valuation_type', 'sample', 'Magnitude', 'layer', 'no_resources', 'poa'] + ['resource_' + k for k in combinations[0][10].keys()] + \ ['normalized_resource_' + k for k in combinations[0][10].keys()] T = max(result_df.t.unique().tolist()) df_res = pd.DataFrame(columns=cols, dtype=int) print('\nResource allocation') for idx, x in enumerate(optimal_combinations): net_obj = objs[str(combinations[0])].net out_dir_suffix_res = indp.get_resource_suffix({'V': x[10]}) ref_dir = root_result_dir + x[4] + '_results_L' + str( x[2]) + '_m' + str(x[0]) + '_v' + out_dir_suffix_res for t in range(T): for l in range(1, x[2] + 1): temp_dict = { 't': t + 1, 'decision_type': x[4], 'judgment_type': 'nan', 'auction_type': 'nan', 'valuation_type': 'nan', 'sample': x[1], 'Magnitude': x[0], 'layer': l, 'no_resources': x[3], 'poa': 1 } for rc in x[10].keys(): temp_dict['resource_' + rc] = 0 temp_dict['normalized_resource_' + rc] = 0 df_res = df_res.append(temp_dict, ignore_index=True) # Read optimal resource allocation based on the actions action_file = ref_dir + "/actions_" + str(x[1]) + "_" + x[8] + ".csv" if os.path.isfile(action_file): with open(action_file) as f: lines = f.readlines()[1:] for line in lines: data = line.strip().split(',') t = int(data[0]) action = str.strip(data[1]) act_split = action.split('.') l = int(act_split[-1]) row = (df_res['t'] == t) & (df_res['decision_type'] == x[4]) & \ (df_res['sample'] == x[1]) & (df_res['Magnitude'] == x[0]) & \ (df_res['layer'] == l) & (df_res['no_resources'] == x[3]) for rc in x[10].keys(): if '/' in action: act_split2 = act_split[1].split('/') arc_obj = net_obj.G[(int( act_split[0]), int(act_split2[0]))][(int( act_split2[1]), int(act_split[2]))] addition = 0.5 * arc_obj['data'][ 'inf_data'].resource_usage['h_' + rc] else: node_obj = net_obj.G.nodes[(int(act_split[0]), int(act_split[1]))] addition = 1.0 * node_obj['data'][ 'inf_data'].resource_usage['p_' + rc] df_res.loc[row, 'resource_' + rc] += addition df_res.loc[row, 'normalized_resource_' + rc] += addition / float(x[10][rc]) if idx % (len(combinations + optimal_combinations) / 10 + 1) == 0: update_progress(idx + 1, len(optimal_combinations) + len(combinations)) # Read resource allocation based on resource allocation results for idx, x in enumerate(combinations): obj = objs[str(x)] for t, tval in obj.v_r.items(): if x[6] in ["MDA", "MAA", "MCA"]: poa = obj.resource.auction_model.poa[t] else: poa = 'nan' for l, lval in tval.items(): temp_dict = { 't': t, 'decision_type': x[4], 'judgment_type': x[5], 'auction_type': x[6], 'valuation_type': x[7], 'sample': x[1], 'Magnitude': x[0], 'layer': l, 'no_resources': x[3], 'poa': poa } for rc, rval in lval.items(): temp_dict['resource_' + rc] = rval temp_dict['normalized_resource_' + rc] = rval / float(x[10][rc]) df_res = df_res.append(temp_dict, ignore_index=True) if idx % (len(combinations + optimal_combinations) / 10 + 1) == 0: update_progress( len(optimal_combinations) + idx + 1, len(optimal_combinations) + len(combinations)) update_progress( len(optimal_combinations) + idx + 1, len(optimal_combinations) + len(combinations)) #: populate allocation gap dictionary cols = ['decision_type', 'judgment_type', 'auction_type', 'valuation_type', 'sample', 'Magnitude', 'layer', 'no_resources'] + ['gap_' + k for k in combinations[0][10].keys()] + \ ['norm_gap_' + k for k in combinations[0][10].keys()] T = max(result_df.t.unique().tolist()) df_alloc_gap = pd.DataFrame(columns=cols, dtype=int) print('\nAllocation Gap') for idx, x in enumerate(combinations + optimal_combinations): # Construct vector of resource allocation of reference method if x[4] != ref_method: for rc in x[10].keys(): vec_ref = {l: np.zeros(T) for l in range(1, x[2] + 1)} for l in range(1, x[2] + 1): for t in range(T): vec_ref[l][t] = df_res.loc[ (df_res['t'] == t + 1) & (df_res['decision_type'] == ref_method) & (df_res['sample'] == x[1]) & (df_res['Magnitude'] == x[0]) & (df_res['layer'] == l) & (df_res['no_resources'] == x[3]), 'resource_' + rc] # Compute distance of resource allocation vectors vector_res = {l: np.zeros(T) for l in range(1, x[2] + 1)} for l in range(1, x[2] + 1): row = (df_res['decision_type'] == x[4]) & (df_res['sample'] == x[1]) & \ (df_res['Magnitude'] == x[0]) & (df_res['layer'] == l) & \ (df_res['no_resources'] == x[3]) & (df_res['auction_type'] == x[6]) & \ (df_res['valuation_type'] == x[7]) & (df_res['judgment_type'] == x[5]) for t in range(T): vector_res[l][t] = df_res.loc[(df_res['t'] == t + 1) & row, 'resource_' + rc] # L2 norm distance = np.linalg.norm(vector_res[l] - vec_ref[l]) norm_distance = np.linalg.norm(vector_res[l] / float(x[3]) - \ vec_ref[l] / float(x[3])) # #L1 norm # distance = sum(abs(vector_res[l]-vec_ref[l])) # # correlation distance # distance = 1-scipy.stats.pearsonr(vector_res[l], vec_ref[l])[0] df_alloc_gap = df_alloc_gap.append( { 'decision_type': x[4], 'judgment_type': x[5], 'auction_type': x[6], 'valuation_type': x[7], 'sample': x[1], 'Magnitude': x[0], 'layer': l, 'no_resources': x[3], 'gap_' + rc: distance / float(vector_res[l].shape[0]), 'norm_gap_' + rc: norm_distance / float(vector_res[l].shape[0]) }, ignore_index=True) if idx % (len(combinations + optimal_combinations) / 10 + 1) == 0: update_progress(idx + 1, len(combinations + optimal_combinations)) update_progress(idx + 1, len(combinations + optimal_combinations)) return df_res, df_alloc_gap
def read_results(combinations, optimal_combinations, cost_types, root_result_dir='../results/', deaggregate=False, rslt_dir_lyr='/agents'): """ This function reads the results of analyses (INDP, JC, etc.) and the corresponding objects from file and aggregates the results in a dictionary. Parameters ---------- combinations : dict All combinations of magnitude, sample, judgment type, resource allocation type involved in the JC (or any other decentralized results) collected by :func:`generate_combinations`. optimal_combinations : dict All combinations of magnitude, sample, judgment type, resource allocation type involved in the INDP (or any other optimal results) collected by :func:`generate_combinations`. cost_types : str Cost types that should be read from results and will be shown in the plots. root_result_dir : 'str', optional Root directory where the results are stored. The default is '../results/'. deaggregate : bool, optional Should the de-aggregated results (for separate layers) be read. The default is False. rslt_dir_lyr : str, optional Directory inside the :func:`root result directory <read_results>` where the de-aggregated results (for separate layers) are. The default is '/agents'. Returns ------- cmplt_results : dict Dictionary that contains the read results. objs : dict Dictionary that contains the objects corresponding to the read results. .. todo:: Games: modify the NE analysis to accommodate the case of random signal """ columns = [ 't', 'Magnitude', 'cost_type', 'decision_type', 'judgment_type', 'auction_type', 'valuation_type', 'no_resources', 'sample', 'cost', 'normalized_cost', 'layer' ] cost_types += ['Under Supply Perc'] cmplt_results = pd.DataFrame(columns=columns, dtype=int) objs = {} print("\nAggregating Results") joinedlist = combinations + optimal_combinations for idx, x in enumerate(joinedlist): #: Make the directory out_dir_suffix_res = indp.get_resource_suffix({'V': x[10]}) full_suffix = '_L' + str(x[2]) + '_m' + str( x[0]) + '_v' + out_dir_suffix_res if x[4][:2] in ['jc', 'ng', 'bg'] or x[4][:5] in ['dp_jc']: full_suffix += '_' + x[5] if x[6] in ["MDA", "MAA", "MCA"]: full_suffix += '_AUCTION_' + x[6] + '_' + x[7] else: full_suffix += '_' + x[6] result_dir = root_result_dir + x[4] + '_results' + full_suffix assert os.path.exists(result_dir + '/actions_' + str(x[1]) + '_.csv'), 'Error:' + 'The combination or folder ' \ 'does not exist' + str(x) # Save all results to Pandas dataframe sample_result = indputils.INDPResults() sam_rslt_lyr = {l: indputils.INDPResults() for l in x[9]} sample_result = sample_result.from_csv(result_dir, x[1], suffix=x[8]) if deaggregate: for l in x[9]: sam_rslt_lyr[l] = sam_rslt_lyr[l].from_csv( result_dir + rslt_dir_lyr, x[1], suffix='L' + str(l) + '_' + x[8]) initial_cost = {} for c in cost_types: initial_cost[c] = sample_result[0]['costs'][c] norm_cost = 0 for t in sample_result.results: for c in cost_types: if initial_cost[c] != 0.0: norm_cost = sample_result[t]['costs'][c] / initial_cost[c] else: norm_cost = -1.0 values = [ t, x[0], c, x[4], x[5], x[6], x[7], x[3], x[1], float(sample_result[t]['costs'][c]), norm_cost, 'nan' ] cmplt_results = cmplt_results.append(dict(zip(columns, values)), ignore_index=True) if deaggregate: for l in x[9]: initial_cost = {} for c in cost_types: initial_cost[c] = sam_rslt_lyr[l][0]['costs'][c] norm_cost = 0 for t in sam_rslt_lyr[l].results: for c in cost_types: if initial_cost[c] != 0.0: norm_cost = sam_rslt_lyr[l][t]['costs'][ c] / initial_cost[c] else: norm_cost = -1.0 values = [ t, x[0], c, x[4], x[5], x[6], x[7], x[3], x[1], float(sam_rslt_lyr[l][t]['costs'][c]), norm_cost, l ] cmplt_results = cmplt_results.append(dict( zip(columns, values)), ignore_index=True) #: Getting back the JuCModel objects: if x[4][:2] in ['jc', 'ng', 'bg'] or x[4][:5] in ['dp_jc']: with open(result_dir + '/objs_' + str(x[1]) + '.pkl', 'rb') as f: objs[str(x)] = pickle.load(f) if idx % (len(joinedlist) // 100 + 1) == 0: update_progress(idx + 1, len(joinedlist)) update_progress(len(joinedlist), len(joinedlist)) return cmplt_results, objs
def run_judgment_call(params, save_jc=True, print_cmd=True, save_jc_model=False): """ Finds interdependent restoration strategies using a decentralized heuristic, Judgment Call :cite:`Talebiyan2019c,Talebiyan2019`. Parameters ---------- params : dict Global parameters, including number of iterations, judgment type, etc. save_jc : bool, optional If true, the results are saved to files. The default is True. print_cmd : bool, optional If true, the results are printed to console. The default is True. save_jc_model : bool, optional If true, optimization models and their solutions are printed to file. The default is False. Returns ------- : None """ if "NUM_ITERATIONS" not in params: params["NUM_ITERATIONS"] = 1 num_iterations = params["NUM_ITERATIONS"] time_limit = 10 * 60 # !!! Might be adjusted later # Creating JC objects c = 0 objs = {} params_copy = copy.deepcopy(params) # !!! deepcopy out_dir_suffix_res = indp.get_resource_suffix(params_copy) for jc in params["JUDGMENT_TYPE"]: params_copy['JUDGMENT_TYPE'] = jc for rst in params["RES_ALLOC_TYPE"]: params_copy['RES_ALLOC_TYPE'] = rst if rst not in ["MDA", "MAA", "MCA"]: output_dir_full = params["OUTPUT_DIR"] + '_L' + str(len(params["L"])) + '_m' + \ str(params["MAGNITUDE"]) + "_v" + out_dir_suffix_res + '_' + jc + '_' + \ rst + '/actions_' + str(params["SIM_NUMBER"]) + '_real.csv' if os.path.exists(output_dir_full): print('Judgment Call:', jc, rst, 'results are already there\n') else: objs[c] = JcModel(c, params_copy) c += 1 else: for vt in params["VALUATION_TYPE"]: params_copy['VALUATION_TYPE'] = vt output_dir_full = params["OUTPUT_DIR"] + '_L' + str(len(params["L"])) + '_m' + \ str(params["MAGNITUDE"]) + "_v" + out_dir_suffix_res + '_' + jc + '_AUCTION_' + \ rst + '_' + vt + '/actions_' + str(params["SIM_NUMBER"]) + '_real.csv' if os.path.exists(output_dir_full): print('Judgment Call:', jc, rst, vt, 'results are already there\n') else: objs[c] = JcModel(c, params_copy) c += 1 if not objs: return 0 # t=0 costs and performance. if params['DYNAMIC_PARAMS']: original_n = copy.deepcopy(objs[0].net) # !!! deepcopy dislocationutils.dynamic_parameters( objs[0].net, original_n, 0, params['DYNAMIC_PARAMS']['DEMAND_DATA']) v_0 = {x: 0 for x in params["V"].keys()} indp_results_initial = indp.indp(objs[0].net, v_0, 1, objs[0].layers, controlled_layers=objs[0].layers) for _, obj in objs.items(): print('--Running JC: ' + obj.judge_type + ', resource allocation: ' + obj.res_alloc_type) if obj.resource.type == 'AUCTION': a_model = next(iter(obj.resource.auction_model.values())) print('auction type: ' + a_model.auction_type + ', valuation: ' + a_model.valuation_type) if print_cmd: print("Num iterations=", params["NUM_ITERATIONS"]) # t=0 results. obj.results_judge = copy.deepcopy( indp_results_initial[1]) # !!! deepcopy obj.results_real = copy.deepcopy( indp_results_initial[1]) # !!! deepcopy for i in range(num_iterations): print("-Time Step (JC)", i + 1, "/", num_iterations) #: Resource Allocation res_alloc_time_start = time.time() if obj.resource.type == 'AUCTION': for keya in obj.resource.auction_model.keys(): obj.resource.auction_model[keya].auction_resources( obj, i + 1, print_cmd=print_cmd, compute_poa=True) obj.resource.time[i + 1] = time.time() - res_alloc_time_start # Judgment-based Decisions if print_cmd: print("Judge-based decisions: ") functionality = {l: {} for l in obj.layers} for l in obj.layers: if print_cmd: print("Layer-%d" % (l)) neg_layer = [x for x in obj.layers if x != l] functionality[l] = obj.judgments.create_judgment_dict( obj, neg_layer) obj.judgments.save_judgments(obj, functionality[l], l, i + 1) # Make decision based on judgments before communication if params['DYNAMIC_PARAMS']: dislocationutils.dynamic_parameters( objs[0].net, original_n, i + 1, params['DYNAMIC_PARAMS']['DEMAND_DATA']) indp_results = indp.indp(obj.net, obj.v_r[i + 1][l], 1, layers=obj.layers, controlled_layers=[l], functionality=functionality[l], print_cmd=print_cmd, time_limit=time_limit) obj.results_judge.extend(indp_results[1], t_offset=i + 1) obj.results_judge.results_layer[l][ i + 1]['costs']['Space Prep'] = indp_results[1].results[0][ 'costs']['Space Prep'] # Save models to file if save_jc_model: indp.save_indp_model_to_file(indp_results[0], obj.output_dir + "/Model", i + 1, l) # Modify network to account for recovery and calculate components. indp.apply_recovery(obj.net, obj.results_judge, i + 1) obj.results_judge.add_components(i + 1, indputils.INDPComponents. \ calculate_components(indp_results[0], obj.net, layers=[l])) # Re-evaluate judgments based on other agents' decisions if print_cmd: print("Re-evaluation: ") for l in obj.layers: if print_cmd: print("Layer-%d" % (l)) indp_results_real = realized_performance( obj, i + 1, functionality=functionality[l], judger_layer=l, print_cmd=print_cmd) obj.results_real.extend(indp_results_real[1], t_offset=i + 1) obj.correct_results_real(l, i + 1) if save_jc_model: indp.save_indp_model_to_file(indp_results_real[0], obj.output_dir + "/Model", i + 1, l, suffix='real') # Calculate sum of costs obj.recal_result_sum(i + 1) # Save results of D-iINDP run to file. if save_jc: obj.save_results_to_file(params["SIM_NUMBER"]) obj.save_object_to_file(params["SIM_NUMBER"])
def batch_run(params, fail_sce_param): """ Batch run different methods for a given list of damage scenarios, given global parameters. Parameters ---------- params : dict DESCRIPTION. fail_sce_param : dict DESCRIPTION. Returns ------- None. Writes to file """ # Set root directories base_dir = fail_sce_param['BASE_DIR'] damage_dir = fail_sce_param['DAMAGE_DIR'] topology = None infrastructure_data = None ext_interdependency = None if fail_sce_param['TYPE'] == 'Andres': infrastructure_data = 'shelby_old' ext_interdependency = "../data/INDP_4-12-2016" elif fail_sce_param['TYPE'] == 'WU': infrastructure_data = 'shelby_extended' if fail_sce_param['FILTER_SCE'] is not None: list_high_dam = pd.read_csv(fail_sce_param['FILTER_SCE']) elif fail_sce_param['TYPE'] == 'from_csv': infrastructure_data = 'shelby_extended' elif fail_sce_param['TYPE'] == 'synthetic': topology = fail_sce_param['TOPO'] print('----Running for resources: ' + str(params['V'])) for m in fail_sce_param['MAGS']: for i in fail_sce_param['SAMPLE_RANGE']: params["SIM_NUMBER"] = i params["MAGNITUDE"] = m try: list_high_dam if len(list_high_dam.loc[(list_high_dam.set == i) & \ (list_high_dam.sce == m)].index) == 0: continue except NameError: pass # Check if the results exist # !!! move it after initializing network for synthetic nets since L is identified there output_dir_full = '' if params["ALGORITHM"] in ["INDP"]: out_dir_suffix_res = indp.get_resource_suffix(params) output_dir_full = params["OUTPUT_DIR"] + '_L' + str(len(params["L"])) + '_m' + \ str(params["MAGNITUDE"]) + "_v" + out_dir_suffix_res + '/actions_' + str(i) + '_.csv' if os.path.exists(output_dir_full): print('results are already there\n') continue print('---Running Magnitude ' + str(m) + ' sample ' + str(i) + '...') if params['TIME_RESOURCE']: print('Computing repair times...') indp.time_resource_usage_curves(base_dir, damage_dir, i) print("Initializing network...") if infrastructure_data: params["N"], _, _ = indp.initialize_network( base_dir=base_dir, external_interdependency_dir=ext_interdependency, sim_number=0, magnitude=m, sample=i, v=params["V"], infrastructure_data=infrastructure_data, extra_commodity=params["EXTRA_COMMODITY"]) else: params["N"], params["V"], params[ 'L'] = indp.initialize_network( base_dir=base_dir, external_interdependency_dir=ext_interdependency, magnitude=m, sample=i, infrastructure_data=infrastructure_data, topology=topology) if params['DYNAMIC_PARAMS']: print("Computing dislocation data...") dyn_dmnd = dislocationutils.create_dynamic_param( params, N=params["N"], T=params["NUM_ITERATIONS"]) params['DYNAMIC_PARAMS']['DEMAND_DATA'] = dyn_dmnd if fail_sce_param['TYPE'] == 'WU': indp.add_wu_failure_scenario(params["N"], dam_dir=damage_dir, no_set=i, no_sce=m) elif fail_sce_param['TYPE'] == 'ANDRES': indp.add_failure_scenario(params["N"], dam_dir=damage_dir, magnitude=m, v=params["V"], sim_number=i) elif fail_sce_param['TYPE'] == 'from_csv': indp.add_from_csv_failure_scenario(params["N"], sample=i, dam_dir=damage_dir) elif fail_sce_param['TYPE'] == 'synthetic': indp.add_synthetic_failure_scenario(params["N"], dam_dir=base_dir, topology=topology, config=m, sample=i) if params["ALGORITHM"] == "INDP": indp.run_indp(params, layers=params['L'], controlled_layers=params['L'], T=params["T"], save_model=True, print_cmd_line=False, co_location=False) if params["ALGORITHM"] == "MH": mh.run_mh(params, validate=False, T=params["T"], layers=params['L'], controlled_layers=params['L'], saveModel=True, print_cmd_line=False, co_location=True) elif params["ALGORITHM"] == "INRG": gameutils.run_inrg(params, layers=params['L'], player_ordering=player_ordering) elif params["ALGORITHM"] == "BACKWARDS_INDUCTION": gametree.run_backwards_induction( params["N"], i, players=params['L'], player_ordering=player_ordering, T=params["T"], outdir=params["OUTPUT_DIR"]) elif params["ALGORITHM"] == "JC": dindputils.run_judgment_call(params, save_jc_model=False, print_cmd=False) elif params["ALGORITHM"] in ["NORMALGAME", "BAYESGAME"]: gameutils.run_game(params, save_results=True, print_cmd=False, save_model=False, plot2D=False) # !!!