Source code for karma_game_library.entities.game_parameters

# Karma Game Library, Copyrights Kevin Riehl 2023, <kriehl@ethz.ch>

# Imports
import numpy as np
import pickle
from typing import List, Dict, Callable
import karma_game_library

# Classes

[docs]class GameParameters: """ A class to encapsulate all parameters necessary to describe a Karma game for policy computation and simulation purposes. It is used when instantiating StateDistribution and Policy objects, as well as it is used for Simulator and Optimizer. """ ##### Parameters #### # scalars _num_agents = 0 _num_participants = 0 _num_types = 0 _num_urgencies = 0 _num_actions = 0 _num_state_karmas = 0 # sets _set_types = () _set_urgencies = () _set_state_karmas = () _set_actions = () _set_outcomes = () # maps _map_type_temp_preference = {} _map_urgency_immediate_cost = {} # lsts of initial population _lst_init_types = [] _lst_init_urgencies = [] _lst_init_karmas = [] # functions _func_cost = None _func_outcome = None _func_payment = None _func_overflow_distribution = None _func_karma_redistribution = None _func_urgency_transition = None # tollerances & thresholds _validation_tol_up = 1.005 _validation_tol_dn = 0.995 _creation_thr_state = 0.0005 _creation_thr_action = 0.001 _autocorrect_factor_state = 1.001 ##### Constructor ####
[docs] def __init__(self, num_agents : int, num_participants : int, num_types : int, num_urgencies : int, num_outcomes : int, num_average_karma : int, map_type_temp_preference : Dict[int, float], lst_init_types : List[int], lst_init_urgencies : List[int], lst_init_karmas : List[int], func_cost: Callable, func_outcome: Callable, func_payment: Callable, func_urgency_transition: Callable, func_overflow_distribution: Callable, func_karma_redistribution: Callable): """ This constructor initializes the GameParameters instance and checks the validity of the given parameters. Parameters ---------- num_agents : int The number agents in the population (the population size). num_participants : int The number of agents that participate in an interaction. num_types : int The finite number of possible agent types. num_urgencies : int The finite number of possible agent urgencies. num_outcomes : int The finite number of possible outcomes for a participant. num_average_karma : int The initial state is focussed on num_average_karma. The average Karma will remain constant. map_type_temp_preference : Dict[int, float]: [type] -> [temporal preference] This map maps the given agent type to a temporal preference between 0.0 and 1.0. lst_init_types : List[int] This list of integers represents the list of agent types. The agent types (temporal preferences) cannot change over time. lst_init_urgencies : List[int] This list of integers represents the list of initial agent urgencies. lst_init_karmas : List[int] This list of integers represents the list of initial agents' karma balances. func_cost : Callable, (urgency, outcome) -> (cost) This function takes the urgency and outcome of a participant and returns the costs that result of to it. The cost should be a positive number as the software framework works with negative costs. func_outcome : Callable, (lst_actions) -> (outcomes) This function takes the interaction participant actions and returns an integers representing the interaction outcome. The outcomes is a vector of outcomes for each participant. func_payment : Callable, (actions, outcomes) -> (payments, karma_overflow) This function takes the participants actions and interaction outcomes and returns the lists of payments and karma_overflow. Note, payments are added to the karma balances of participants. Note2: This function cannot be probabilistic! func_urgency_transition : Callable, (atype, urgency, outcome, set_urgencies) -> (urgency_next) This function takes an agent type, urgency, and outcome, and returns the next agent urgency. This enables the user to model the urgency_next in dependence of outcome. The outcome is encoded as follows: -1 means the agent didnt participate an interaction this epoch, otherwise it is the max outcome of all interactions from this epoch the agent participated. One could model the urgency transition with type specific finite state machines for instance. func_overflow_distribution : Callable, (pop_karmas, karma_overflow) -> (pop_karmas_next) This function takes the population karma balances, and the payment overflow, and distributes it across the population. func_karma_redistribution : Callable, (pop_karmas) -> (pop_karmas_next) This function takes the population (represented by karma balances) and returns a list of integers representing the new karma balances of agents after redistribution. Raises ------ Exception In case the input parameters are not plausible a specific exception will be raised. Returns ------- None """ # Plausibility checks before karma_game_library.check.non_negative(num_agents, "num_agents") karma_game_library.check.non_negative(num_participants, "num_participants") karma_game_library.check.non_negative(num_types, "num_types") karma_game_library.check.non_negative(num_urgencies, "num_urgencies") karma_game_library.check.non_negative(num_average_karma, "num_average_karma") karma_game_library.check.map_values_bounded(map_type_temp_preference, 0.0, 1.0, "map_type_temp_preference") karma_game_library.check.list_length(lst_init_types, num_agents, "lst_init_types") karma_game_library.check.list_length(lst_init_urgencies, num_agents, "lst_init_urgencies") karma_game_library.check.list_length(lst_init_karmas, num_agents, "lst_init_karmas") karma_game_library.check.func_not_none(func_outcome, "func_outcome") karma_game_library.check.func_not_none(func_payment, "func_payment") karma_game_library.check.func_not_none(func_urgency_transition, "func_urgency_transition") karma_game_library.check.func_not_none(func_overflow_distribution, "func_overflow_distribution") karma_game_library.check.func_not_none(func_karma_redistribution, "func_karma_redistribution") # Setting parameters # scalars self._num_agents = num_agents self._num_participants = num_participants self._num_types = num_types self._num_urgencies = num_urgencies self._num_actions = num_average_karma self._num_state_karmas = num_average_karma*4 self._num_average_karma = num_average_karma # sets self._set_types = np.arange(num_types) self._set_urgencies = np.arange(num_urgencies) self._set_state_karmas = np.arange(self._num_state_karmas) self._set_actions = np.arange(self._num_actions) self._set_outcomes = np.arange(num_outcomes) # maps self._map_type_temp_preference = map_type_temp_preference # lsts of initial population self._lst_init_types = lst_init_types self._lst_init_urgencies = lst_init_urgencies self._lst_init_karmas = lst_init_karmas # functions self._func_cost = func_cost self._func_outcome = func_outcome self._func_payment = func_payment self._func_urgency_transition = func_urgency_transition self._func_overflow_distribution = func_overflow_distribution self._func_karma_redistribution = func_karma_redistribution # Plausibility checks after karma_game_library.check.map_keys(map_type_temp_preference, self._set_types, "map_type_temp_preference", "set_types")
def _enlarge_karma_space(self): """ This function enlarges the karma space in case it is computationally required. Parameters ---------- None Returns ------- None """ self._set_state_karmas = np.append(self._set_state_karmas, self._num_state_karmas) self._num_state_karmas += 1 def _enlarge_action_space(self): """ This function enlarges the action space in case it is computationally required. Parameters ---------- None Returns ------- None """ self._set_actions = np.append(self._set_actions, self._num_actions) self._num_actions += 1
def save(parameters: GameParameters, target_file: str): """ This function stores the GameParameters to a file. Parameters ---------- parameters : GameParameters A GameParameters instance. target_file : str The file to store the GameParameters. Returns ------- None """ file_writer = open(target_file, "wb") pickle.dump(parameters, file_writer, pickle.HIGHEST_PROTOCOL) file_writer.close() def load(source_file: str): """ This function loads the GameParameters from a file. Parameters ---------- source_file : str The file to load the GameParameters from. Returns ------- parameters : GameParameters A GameParameters instance. """ file_reader = open(source_file, 'rb') parameters = pickle.load(file_reader) file_reader.close() return parameters GameParameters.save = staticmethod(save) GameParameters.load = staticmethod(load)