scml.scml2019.common ==================== .. py:module:: scml.scml2019.common .. autoapi-nested-parse:: Common data-structures and objects used throughout the SCM world implementation Attributes ---------- .. autoapisummary:: scml.scml2019.common.INVALID_STEP scml.scml2019.common.NO_PRODUCTION scml.scml2019.common.DEFAULT_NEGOTIATOR scml.scml2019.common.QUANTITY scml.scml2019.common.TIME scml.scml2019.common.UNIT_PRICE Classes ------- .. autoapisummary:: scml.scml2019.common.Product scml.scml2019.common.InputOutput scml.scml2019.common.Process scml.scml2019.common.ManufacturingProfile scml.scml2019.common.FactoryStatusUpdate scml.scml2019.common.RunningCommandInfo scml.scml2019.common.Job scml.scml2019.common.ProductionNeed scml.scml2019.common.MissingInput scml.scml2019.common.ProductionFailure scml.scml2019.common.ProductionReport scml.scml2019.common.SCMLAgreement scml.scml2019.common.CFP scml.scml2019.common.SCMLAction scml.scml2019.common.ManufacturingProfileCompiled scml.scml2019.common.ProductManufacturingInfo scml.scml2019.common.FinancialReport scml.scml2019.common.Loan scml.scml2019.common.InsurancePolicy scml.scml2019.common.FactoryState scml.scml2019.common.Factory Module Contents --------------- .. py:data:: INVALID_STEP :value: -1000 .. py:data:: NO_PRODUCTION :value: -1 .. py:data:: DEFAULT_NEGOTIATOR :value: 'negmas.sao.AspirationNegotiator' .. py:data:: QUANTITY :value: 0 Index of quantity in negotiation issues .. py:data:: TIME :value: 1 Index of time in negotiation issues .. py:data:: UNIT_PRICE :value: 2 Index of unit price in negotiation issues .. py:class:: Product .. py:attribute:: __slots__ :value: ['id', 'production_level', 'name', 'expires_in', 'catalog_price'] A product that can be transacted in. .. py:attribute:: id :type: int Product index. Must be set during construction and **MUST** be unique for products in the same world .. py:attribute:: production_level :type: int The level of this product in the production graph. .. py:attribute:: name :type: str Object name .. py:attribute:: expires_in :type: Optional[int] Number of steps within which the product must be consumed. None means never .. py:attribute:: catalog_price :type: Optional[float] Catalog price of the product. .. py:method:: __str__() String representation is simply the name .. py:method:: __post_init__() .. py:method:: __hash__() .. py:class:: InputOutput An input/output to a production process .. py:attribute:: __slots__ :value: ['product', 'quantity', 'step'] .. py:attribute:: product :type: int Index of the product used as input or output .. py:attribute:: quantity :type: int Quantity needed/produced .. py:attribute:: step :type: float Relative time within the production at which the input is needed (output is produced) .. py:class:: Process .. py:attribute:: __slots__ :value: ['id', 'production_level', 'name', 'inputs', 'outputs', 'historical_cost'] .. py:attribute:: id :type: int A manufacturing process. .. py:attribute:: production_level :type: int The level of this process in the production graph .. py:attribute:: name :type: str Object name .. py:attribute:: inputs :type: List[InputOutput] list of input product name + quantity required and time of consumption relative to the time required for production (value from 0 to 1) .. py:attribute:: outputs :type: List[InputOutput] list of output product names, quantity required and when it becomes available relative to the time required for production (value from 0 to 1) .. py:attribute:: historical_cost :type: Optional[float] Average cost for running this process in some world. Filled by the world .. py:method:: __str__() String representation is simply the name .. py:method:: __post_init__() .. py:method:: __hash__() The hash depends only on the name .. py:class:: ManufacturingProfile The costs/time required for running a process on a line (with associated cancellation costs etc). This data-structure carries full information about the `Process` es instead of just its index as in `ManufacturingProfileCompiled`. It is intended to be used to construct factories .. seealso:: `Factory` .. py:attribute:: __slots__ :value: ['n_steps', 'cost', 'initial_pause_cost', 'running_pause_cost', 'resumption_cost',... .. py:attribute:: n_steps :type: int Number of steps needed to complete the manufacturing .. py:attribute:: cost :type: float Cost of manufacturing .. py:attribute:: initial_pause_cost :type: float Cost of pausing incurred only at the step a pause is started .. py:attribute:: running_pause_cost :type: float Running cost of pausing .. py:attribute:: resumption_cost :type: float Cost of resuming a process .. py:attribute:: cancellation_cost :type: float Cost of cancelling the process before the last step .. py:attribute:: line :type: int The line index .. py:attribute:: process :type: Process The `Process` associated with this profile .. py:class:: FactoryStatusUpdate .. py:attribute:: __slots__ :value: ['balance', 'storage'] .. py:attribute:: balance :type: float The update to the balance .. py:attribute:: storage :type: Dict[int, int] The updates to be applied to the storage after this step .. py:method:: __post_init__() .. py:method:: make_empty() -> None Makes the update an empty one. .. py:method:: combine(other: FactoryStatusUpdate) -> None Combines this status update with another one in place :param other: The other status update :returns: None .. py:method:: combine_sets(dst: Dict[int, FactoryStatusUpdate], src: Dict[int, FactoryStatusUpdate]) :classmethod: Combines a set of updates over time with another in place (overriding `first`) :param dst: First set of updates to be combined into :param src: second set of updates to be combined from Returns: .. py:property:: is_empty .. py:method:: empty() :classmethod: .. py:method:: __str__() .. py:class:: RunningCommandInfo .. py:attribute:: __slots__ :value: ['profile', 'beg', 'end', 'action', 'updates', 'step', 'paused'] .. py:attribute:: profile :type: ManufacturingProfile The manufacturing profile associated with this command. Most importantly, it gives the process and line .. py:attribute:: beg :type: int The time the command is to be executed .. py:attribute:: end :type: int The number of steps starting at `beg` for this command to end (it ends at end - 1) .. py:attribute:: step :type: int The time-step relative to `beg` at the factory is currently executing the `Process` indicated in `profile`. `step` will always go up by one every simulation step except if the command is paused where it does not change .. py:attribute:: paused :type: bool True if the command is paused .. py:attribute:: action :type: str The command type. For the current implementation it will always be run or none for no command .. py:attribute:: updates :type: Dict[int, FactoryStatusUpdate] The status updates implied by this command with their times relative to `beg` .. py:property:: n_steps :type: int .. py:method:: ended_before(t: int) .. py:method:: started_on_or_after(t: int) .. py:method:: __str__() .. py:property:: is_none .. py:method:: do_nothing() :classmethod: .. py:class:: Job Describes a job to be run on one production line of a `Factory`. .. py:attribute:: __slots__ :value: ['profile', 'time', 'line', 'action', 'contract', 'override'] .. py:attribute:: profile :type: int The process for run commands .. py:attribute:: time :type: int The time the command is to be executed .. py:attribute:: line :type: int Index of the line on which the job is to be scheduled. Notice that it will be ignored for `run` actions. .. py:attribute:: action :type: str The command type. For the current implementation it can be run/pause/resume/stop/cancel with `cancel` cancelling any other command type. .. py:attribute:: contract :type: Optional[negmas.situated.Contract] The sell contract associated with the command .. py:attribute:: override :type: bool Whether to override existing commands when the job is to be executed. .. py:method:: __str__() .. py:method:: is_cancelling(job: Job) -> bool Determines if the given jobs cancels this one :param job: Returns: .. py:class:: ProductionNeed Describes some quantity of a product that is needed to honor a (sell) contract. .. py:attribute:: __slots__ :value: ['product', 'needed_for', 'quantity_to_buy', 'quantity_in_storage', 'step'] .. py:attribute:: product :type: int The product needed .. py:attribute:: needed_for :type: negmas.situated.Contract The contract for which the product is needed .. py:attribute:: quantity_to_buy :type: int The quantity need to be bought .. py:attribute:: quantity_in_storage :type: int The quantity already found in storage .. py:attribute:: step :type: int The time step at which the product is needed .. py:method:: __str__() String representation is simply the name .. py:class:: MissingInput .. py:attribute:: __slots__ :value: ['product', 'quantity'] .. py:attribute:: product :type: int .. py:attribute:: quantity :type: int .. py:method:: __str__() .. py:class:: ProductionFailure .. py:attribute:: __slots__ :value: ['line', 'command', 'missing_inputs', 'missing_money', 'missing_space'] .. py:attribute:: line :type: int ID of the line that failed .. py:attribute:: command :type: RunningCommandInfo Information about the command that failed .. py:attribute:: missing_inputs :type: List[MissingInput] The missing inputs if any with their quantities .. py:attribute:: missing_money :type: float The amount of money needed for production that is not available .. py:attribute:: missing_space :type: int The amount space needed in storage but not found .. py:method:: __str__() .. py:class:: ProductionReport .. py:attribute:: line :type: int ID of the line .. py:attribute:: started :type: Optional[RunningCommandInfo] Commands started .. py:attribute:: continuing :type: Optional[RunningCommandInfo] Command that is continuing .. py:attribute:: finished :type: Optional[RunningCommandInfo] Command finished .. py:attribute:: failure :type: Optional[ProductionFailure] Failures .. py:attribute:: updates :type: FactoryStatusUpdate Updates applied to the factory .. py:property:: failed .. py:property:: is_empty .. py:property:: no_production .. py:method:: __str__() .. py:class:: SCMLAgreement .. py:attribute:: time :type: int delivery time .. py:attribute:: unit_price :type: float unit price .. py:attribute:: quantity :type: int quantity .. py:attribute:: penalty :type: Optional[float] :value: None penalty .. py:attribute:: signing_delay :type: int :value: -1 Delay between agreement conclusion and signing it to be binding .. py:method:: __getitem__(k) .. py:method:: get(k, default=None) .. py:method:: asdict() .. py:method:: to_dict() .. py:method:: keys() .. py:method:: values() .. py:method:: items() .. py:class:: CFP A Call for proposal upon which a negotiation can start .. py:attribute:: is_buy :type: bool If true, the author wants to buy otherwise to sell. Non-negotiable. .. py:attribute:: publisher :type: str the publisher name. Non-negotiable. .. py:attribute:: product :type: int product ID. Non-negotiable. .. py:attribute:: time :type: Union[int, Tuple[int, int], List[int]] delivery time. May be negotiable. .. py:attribute:: unit_price :type: Union[float, Tuple[float, float], List[float]] unit price. May be negotiable. .. py:attribute:: quantity :type: Union[int, Tuple[int, int], List[int]] quantity. May be negotiable. .. py:attribute:: penalty :type: Optional[Union[float, Tuple[float, float], List[float]]] :value: None penalty per missing item in case the seller cannot provide the required quantity. May be negotiable. .. py:attribute:: signing_delay :type: Optional[Union[int, Tuple[int, int], List[int]]] :value: None The grace period after which the agents are asked to confirm signing the contract .. py:attribute:: money_resolution :type: Optional[float] :value: None If not None then it is the minimum unit of money (e.g. 1 for dollar, 0.01 for cent, etc) .. py:attribute:: id :type: str :value: '' Unique CFP ID .. py:method:: __str__() .. py:method:: satisfies(query: Dict[str, Any]) -> bool Tests whether the CFP satisfies the conditions set by the query :param query: A dictionary given the conditions. See `Remarks` for details Remarks: - The query dictionary can be used to specify any conditions that are required in the CFP. Only CFPs that satisfy ALL the conditions specified in the query are considered satisfying the query. The following keys can be set with corresponding meanings: is_buy True or False. If both are OK, just do not add this key publisher A string or `SCML2019Agent` specifying a specific publisher publishers A list of publishers (see publisher key) product A string specifying a product name products A list of products (see product key) time A number, list or 2-items-tuple (range) specifying possible times to consider satisfactory unit_price A number, list or 2-items-tuple (range) specifying possible prices to consider satisfactory quantity A number, list or 2-items-tuple (range) specifying possible quantities to consider OK penalty A number, list or 2-items-tuple (range) specifying possible penalties to consider satisfactory .. py:property:: issues Returns the set of issues associated with this CFP. Notice that some of the issues may have a single value .. py:property:: outcomes .. py:property:: min_time .. py:property:: max_time .. py:property:: min_quantity .. py:property:: max_quantity .. py:property:: min_unit_price .. py:property:: max_unit_price .. py:property:: min_signing_delay .. py:property:: max_signing_delay .. py:property:: min_penalty .. py:property:: max_penalty .. py:method:: to_dict() .. py:method:: from_dict(idict: Dict[str, Any], class_name: Optional[str] = None) -> CFP :classmethod: .. py:class:: SCMLAction .. py:attribute:: line :type: str Line to execute the action on (need not be given if the profile is given .. py:attribute:: profile :type: Optional[int] Index of the profile to execute .. py:attribute:: action :type: str The action which may be start, stop, pause, resume .. py:attribute:: time :type: int :value: 0 Time to execute the action at .. py:class:: ManufacturingProfileCompiled The costs/time required for running a process on a line (with associated cancellation costs etc). .. seealso:: `Factory` .. py:attribute:: __slots__ :value: ['n_steps', 'cost', 'initial_pause_cost', 'running_pause_cost', 'resumption_cost',... .. py:attribute:: n_steps :type: int Number of steps needed to complete the manufacturing .. py:attribute:: cost :type: float Cost of manufacturing .. py:attribute:: initial_pause_cost :type: float Cost of pausing incurred only at the step a pause is started .. py:attribute:: running_pause_cost :type: float Running cost of pausing .. py:attribute:: resumption_cost :type: float Cost of resuming a process .. py:attribute:: cancellation_cost :type: float Cost of cancelling the process before the last step .. py:attribute:: line :type: int The line index .. py:attribute:: process :type: int The `Process` index .. py:method:: from_manufacturing_profile(profile: ManufacturingProfile, process2ind: Dict[Process, int]) :classmethod: .. py:class:: ProductManufacturingInfo Gives full information about a manufacturing process that can generate or consume a product. .. seealso:: `consuming` and `producing` of `Factory` .. py:attribute:: __slots__ :value: ['profile', 'quantity', 'step'] .. py:attribute:: profile :type: int The `ManufacturingProfile` index .. py:attribute:: quantity :type: int The quantity generated/consumed by running this manufacturing info .. py:attribute:: step :type: int The step from the beginning at which the `Product` is received/consumed .. py:class:: FinancialReport Reports that financial standing of an agent at a given time in the simulation .. py:attribute:: agent :type: str Agent ID .. py:attribute:: step :type: int Time of the report .. py:attribute:: cash :type: float Cash at hand .. py:attribute:: liabilities :type: float Total liabilities (loans) .. py:attribute:: inventory :type: float Value of everything in the inventory priced at catalog prices. .. py:attribute:: credit_rating :type: float The agent's credit rating as a fraction of the maximum credit rating (1 indicates highest credit rating). .. py:property:: balance The balance of the agent defined as the difference between its available cash + inventory and its liabilities Remarks: - If the inventory was not calculated (due to having at least one product with unknown catalog price), it is used as zero in the equation. .. py:class:: Loan .. py:attribute:: amount :type: float Loan amount .. py:attribute:: starts_at :type: int The time-step at which payment starts .. py:attribute:: total :type: float The total to be paid including the amount + interests .. py:attribute:: interest :type: float The interest rate per step .. py:attribute:: installment :type: float The amount to be paid in one installment .. py:attribute:: n_installments :type: int The number of installments .. py:method:: __str__() .. py:class:: InsurancePolicy .. py:attribute:: premium :type: float .. py:attribute:: contract :type: negmas.situated.Contract .. py:attribute:: at_time :type: int .. py:attribute:: against :type: scml.scml2019.agent.SCML2019Agent .. py:class:: FactoryState Read Only State of a factory .. py:attribute:: max_storage :type: int Maximum storage allowed in this factory .. py:attribute:: line_schedules :type: numpy.ndarray An array of n_lines * n_steps giving the line schedules .. py:attribute:: storage :type: Dict[int, int] Mapping from product index to the amount available in the inventory .. py:attribute:: wallet :type: float Money available for purchases .. py:attribute:: hidden_money :type: float Amount of money hidden by the agent .. py:attribute:: hidden_storage :type: Dict[int, int] Mapping from product index to the amount hidden by the agent .. py:attribute:: loans :type: float The total money owned as loans .. py:attribute:: n_lines :type: int The number of lines in the factory, will be set using the `profiles` input .. py:attribute:: profiles :type: List[ManufacturingProfile] A list of profiles used to initialize the factory .. py:attribute:: next_step :type: int Next simulation step for this factory .. py:attribute:: commands :type: numpy.ndarray The production command currently running .. py:attribute:: jobs :type: Dict[Tuple[int, int], Job] The jobs waiting to be run on the factory indexed by (time, line) tuples .. py:class:: Factory Represents a factory within an SCML world. It is only accessed by the SCML2020World so it need not be made public. .. py:attribute:: initial_storage :type: dataclasses.InitVar[Dict[int, int]] Initial storage .. py:attribute:: initial_wallet :type: dataclasses.InitVar[float] :value: 0.0 Initial Wallet .. py:attribute:: id :type: str :value: '' Object name .. py:attribute:: profiles :type: List[ManufacturingProfile] :value: [] A list of profiles used to initialize the factory .. py:attribute:: max_storage :type: int :value: 9223372036854775807 Maximum storage allowed in this factory .. py:attribute:: min_storage :type: int :value: 0 Minimum allowed storage per product .. py:attribute:: min_balance :type: int | float :value: 0 Minimum allowed balance .. py:attribute:: initial_balance :type: float :value: 0.0 Initial balance of the factory .. py:attribute:: _commands :type: numpy.ndarray The production command currently running .. py:attribute:: _line_schedules :type: numpy.ndarray .. py:attribute:: _storage :type: Dict[int, int] Mapping from product index to the amount available in the inventory .. py:attribute:: _total_storage :type: int :value: 0 Total storage .. py:attribute:: _wallet :type: float :value: 0 Money available for purchases .. py:attribute:: _hidden_money :type: float :value: 0 Amount of money hidden by the agent .. py:attribute:: _hidden_storage :type: Dict[int, int] Mapping from product index to the amount hidden by the agent .. py:attribute:: _loans :type: float :value: 0.0 The total money owned as loans .. py:attribute:: _n_lines :type: int The number of lines in the factory, will be set using the `profiles` input .. py:attribute:: _jobs :type: Dict[Tuple[int, int], Job] The jobs waiting to be run on the factory indexed by (time, line) tuples .. py:attribute:: _next_step :type: int :value: 0 Current simulation step .. py:attribute:: _carried_updates :type: FactoryStatusUpdate Carried updates from last executed command .. py:attribute:: _world :type: negmas.situated.World :value: None .. py:method:: attach_to_world(world) .. py:method:: __post_init__(initial_storage: Dict[int, int], initial_wallet=0.0) .. py:property:: hidden_money :type: float .. py:property:: hidden_storage :type: Dict[int, int] .. py:property:: n_lines :type: int .. py:property:: jobs :type: Dict[Tuple[int, int], Job] .. py:property:: commands :type: numpy.ndarray .. py:property:: line_schedules :type: numpy.ndarray .. py:property:: wallet :type: float .. py:property:: storage :type: Dict[int, int] .. py:property:: loans :type: float .. py:property:: total_storage :type: int .. py:property:: balance :type: float The total balance of the factory .. py:property:: total_balance :type: float total balance including hidden money .. py:property:: next_step :type: int .. py:method:: add_loan(total: float) -> None .. py:method:: receive(payment: float) -> None .. py:method:: pay(payment: float) -> None .. py:method:: transport_to(product: int, quantity: int) -> None .. py:method:: buy(product: int, quantity: int, price: float) -> None .. py:method:: sell(product: int, quantity: int, price: float) -> None .. py:method:: transport_from(product: int, quantity: int) -> None .. py:method:: hide_funds(amount: float) -> None .. py:method:: hide_product(product: int, quantity: int) -> None .. py:method:: unhide_funds(amount: float) -> None .. py:method:: unhide_product(product: int, quantity: int) -> None .. py:method:: schedule(job: Job, override=False) -> None Schedules the given job at its `time` and `line` optionally overriding whatever was already scheduled :param job: :param override: :returns: Success/failure .. py:method:: _apply_updates(updates: FactoryStatusUpdate) -> None .. py:method:: step() -> List[ProductionReport] .. py:method:: _run(profile: ManufacturingProfile, override=True) -> None running is executed at the beginning of the step t :param profile: the profile to start giving both the line and process :param override: If true, override any running processes paying cancellation cost for these processes Remarks: - The output of a process that runs from step t to step t + n - 1 will only be in storage at step t + n .. py:method:: _pause(line: int) -> None pausing is executed at the end of the step :param line: the line on which the process is running :returns: The status updated for all times that need to be updated to cancel the command if it is not None. If None is returned then scheduling failed. :rtype: Optional[Dict[int, FactoryStatusUpdate]] Remarks: - Not implemented yet - pausing when nothing is running is not an error and will return an empty status update .. py:method:: _resume(line: int) -> None resumption is executed at the end of the step (starting next step count down) :param line: the line on which the process is running :returns: The status updated for all times that need to be updated to cancel the command if it is not None. If None is returned then scheduling failed. :rtype: Optional[Dict[int, FactoryStatusUpdate]] Remarks: - Not implemented yet - resuming when nothing is paused is not an error and will return an empty status update .. py:method:: _stop(line: int) -> None stopping is executed at the beginning of the current step :param line: the line on which the process is running :returns: The status updated for all times that need to be updated to cancel the command if it is not None. If None is returned then scheduling failed. :rtype: Optional[Dict[int, FactoryStatusUpdate]] Remarks: - stopping when nothing is running is not an error and will just return an empty schedule .. py:method:: _step_line(line: int) -> ProductionReport Steps the line to the time-step `t` assuming that it is already stepped to time-step t-1 given the storage :param line: the line to step :returns: ProductionReport