pydcop.infrastructure.computations

The computations module contains base classes for computation and message.

You generally need to sub-class classes from this module when implementing your own DCOP algorithm.

class Message(msg_type, content=None)

Base class for messages.

you generally sub-class Message to define the message type for a DCOP algorithm. Alternatively you can use message_type() to create your own message type.

Parameters
  • msg_type (str) – the message type ; this will be used to select the correct handler for a message in a DcopComputation instance.

  • content (Any) – optional, usually you sub-class Message and add your own content attributes.

property size

Returns the size of the message.

You should overwrite this methods in subclasses, will be used when computing the communication load of an algorithm and by some distribution methods that optimize the distribution of computation for communication load.

Returns

size

Return type

int

property type

The type of the message.

Returns

message_type

Return type

str

message_type(msg_type: str, fields: List[str])

Class factory method for Messages

This utility method can be used to easily define new Message type without subclassing explicitly (and manually) the Message class. Tt output a class object which subclass Message.

Message instance can be created from the return class type using either keywords arguments or positional arguments (but not both at the same time).

Instances from Message classes created with message_type support equality, simple_repr and have a meaningful str representation.

Parameters
  • msg_type (str) – The type of the message, this will be return by msg.type (see example)

  • fields (List[str]) – The fields in the message

Returns

Return type

A class type that can be used as a message type.

Example

>>> MyMessage = message_type('MyMessage', ['foo', 'bar'])
>>> msg1 = MyMessage(foo=42, bar=21)
>>> msg = MyMessage(42, 21)
>>> msg.foo
42
>>> msg.type
'MyMessage'
>>> msg.size
0
register(msg_type: str)

Decorator for registering message handles in computations.

This decorator is meant to be used to register message handlers in computation class (subclasses of MessagePassingComputation).

A method decorated with @register(‘foo’) will be called automatically when the computation receives a message of type ‘foo’.

Message handler must accept 3 parameters : (sender_name, message, time). * sender_name is the name of the computation that sent the message * message is the message it-self, which is an instance of a subclass of Message * time is the time the message was received.

Parameters

msg_type (str) – the type of message

Example

> class C(MessagePassingComputation):
>    ...
>    @register('msg_on_c')
>    def handler_c(self, s, m, t):
>        print("received messages", m, "from", s)

See DsaTuto sample implementation for a complete example.

class MessagePassingComputation(name: str, *args, **kwargs)

MessagePassingComputation is the base class for all computations. It defines the computation lifecycle (start, pause, stop) and can send and receive messages.

When subclassing MessagePassingComputation, you can use the @register decorator on your subclass methods to register then as handler for a specific kind of message. For example:

> class MyComputation(MessagePassingComputation):
>    ...
>    @register('msg_on_c')
>    def handler_c(self, s, m, t):
>        print("received messages", m, "from", s)

Note

A computation is always be hosted and run on an agent, which works with a single thread. This means that its methods do not need to be thread safe as they will always be called sequentially in the same single thread.

Parameters

name (str) – The name of the computation.

add_periodic_action(period: float, cb: Callable)

Add an action that will be called every period seconds.

Parameters
  • period (float) – the period, in second

  • cb (Callable) – A callable, with no parameters

Returns

Return type

the callable

on_pause(paused: bool)

Called when pausing or resuming the computation.

This method is meant to be overwritten in subclasses.

Parameters

paused (boolean) – the new pause status. This method is only called is the status has changed

on_start()

Called when starting the computation.

This method is meant to be overwritten in subclasses.

on_stop()

Called when stopping the computation

This method is meant to be overwritten in subclasses.

post_msg(target: str, msg, prio: int = None, on_error=None)

Post a message.

Notes

This method should always be used when sending a message. The computation should never use the _msg_sender directly has this would bypass the pause state.

Parameters
  • target (str) – the target computation for the message

  • msg (an instance of Message) – the message to send

  • prio (int) – priority level

  • on_error (error handling method) – passed to the messaging component.

class DcopComputation(name, comp_def: pydcop.algorithms.ComputationDef)

Computation representing a DCOP algorithm.

DCOP algorithm computation are like base computation : they work by exchanging messages with each other. The only difference is that a DCOP computation has additional metadata representing the part of the DCOP it as been defined for.

Parameters
  • name (string) – the name of the computation

  • comp_def (ComputationDef) – the ComputationDef object contains the information about the dcop computation : algorithm used, neighbors, etc.

Notes

When subclassing DcopComputation, you must declare in __init__ the message handlers for the message’s type(s) of your algorithm. For example with the following _on_my_msg will be called for each incoming my-msg message.

self._msg_handlers[‘my_msg’] = self._on_my_msg

footprint()

The footprint of the computation.

A DCOP computation has a footprint, which represents the amount of memory this computation requires to run. This depends on the algorithm used and thus must be overwritten in subclasses. This footprint is used when distributing computation on agents, to ensure that agents only host computation they can run.

Returns

the footprint

Return type

float

property neighbors

The neighbors of this computation.

Notes

This is just a convenience shorthand to the neighbors of the node in the computation node :

my_dcop_computation.computation_def.node.neighbors

Returns

a list containing the names of the neighbor computations.

Return type

list of string

new_cycle()

For algorithms that have a concept of cycle, you must call this method (in the subclass) at the start of every new cycle. This is used to generate statistics by cycles.

Notes

You can just ignore this if you do not care about cycles.

post_to_all_neighbors(msg, prio: int = None, on_error=None)

Post a message to all neighbors of the computation.

Parameters
  • msg (an instance of Message) – the message to send

  • prio (int) – priority level

  • on_error (error handling method) – passed to the messaging component.

class VariableComputation(variable: pydcop.dcop.objects.Variable, comp_def: pydcop.algorithms.ComputationDef)

A VariableComputation is a dcop computation that is responsible for selecting the value of a variable.

See also

DcopComputation

property current_value

Return the value currently selected by the algorithm.

If a computation algorithm does no select a value, override this method to raise an exception. :return:

random_value_selection()

Select a random value from the domain of the variable of the VariableComputation.

value_selection(val, cost=0)

When the computation selects a value, it MUST be done by calling this method. This is necessary to be able to automatically monitor value changes. :param val: :param cost:

property variable

Variable: The variable this algorithm is responsible for, if any.