Exemplo n.º 1
0
    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"]))
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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"])
Exemplo n.º 8
0
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)  # !!!