pydcop.algorithms.maxsum

MaxSum: Belief-propagation DCOP algorithm

Max-Sum [FRPJ08] is an incomplete inference-based DCOP algorithm.

This is a synchronous implementation of Max-Sum, where messages are sent and received in cycles. For an asynchronous version, see AMaxSum.

Algorithm Parameters

  • damping: float, default = 0.5

    Amount of damping [0-1].

  • damping_nodes: “vars”, “factors”, “both” or “none”, default = “both”

    Nodes that apply damping to messages.

  • stability: float, default = 0.1 (STABILITY_COEFFICIENT)

    Stability detection coefficient

  • noise: float, default = 0.01

    Noise level for variables

  • start_messages: “leafs”, “leafs_vars”, “all”, default = “leafs”

    Nodes that initiate messages.

FIXME: add support for stop_cycle

Example

pydcop solve -algo maxsum  \
  --algo_param stop_cycle:30 \
 -d adhoc graph_coloring_csp.yaml

FIXME: add results

See also

A-Max-Sum: an asynchronous implementation of Max-Sum.

class MaxSumFactorComputation(comp_def: ComputationDef)
footprint() float

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

on_new_cycle(messages, cycle_id) List | None

Called when switching to a new cycle.

This method must be overridden in derived classes, this is where you write the logic of your synchronous algorithm. It is automatically called when all messages have been received for the current cycle and should be handled. When handling these messages, the computation will generally also send messages to some of its neighbors; this can be achieved either by using post_msg or by returning the list of messages that must be sent for this cycle. Notice that these messages will be delivered in the next cycle.

Notes

You are only allowed to send at most one message to any given neighbor in a cycle. If you send several messages to the same neighbor, a ComputationException will be raised by this neighbor in the next cycle, when receiving them.

Parameters:
  • messages (dict) – all the messages received for this cycle (i.e. that have been set by neighbors during the previous cycle). The keys of the dict are the sender of the message, the values are tuple (message, time).

  • cycle_id (int) – id for this cycle

Returns:

messages – a list of tuples (target, message) with the messages to be sent to neighbors for this cycle (which they will receive at the next cycle).

Return type:

list of None

on_start()

Called when starting the computation.

This method is meant to be overwritten in subclasses.

class MaxSumMessage(costs: Dict)
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

class MaxSumVariableComputation(comp_def: ComputationDef)
on_new_cycle(messages, cycle_id) List | None

Called when switching to a new cycle.

This method must be overridden in derived classes, this is where you write the logic of your synchronous algorithm. It is automatically called when all messages have been received for the current cycle and should be handled. When handling these messages, the computation will generally also send messages to some of its neighbors; this can be achieved either by using post_msg or by returning the list of messages that must be sent for this cycle. Notice that these messages will be delivered in the next cycle.

Notes

You are only allowed to send at most one message to any given neighbor in a cycle. If you send several messages to the same neighbor, a ComputationException will be raised by this neighbor in the next cycle, when receiving them.

Parameters:
  • messages (dict) – all the messages received for this cycle (i.e. that have been set by neighbors during the previous cycle). The keys of the dict are the sender of the message, the values are tuple (message, time).

  • cycle_id (int) – id for this cycle

Returns:

messages – a list of tuples (target, message) with the messages to be sent to neighbors for this cycle (which they will receive at the next cycle).

Return type:

list of None

on_start() None

Called when starting the computation.

This method is meant to be overwritten in subclasses.

approx_match(costs: Dict[Any, float], prev_costs: Dict[Any, float], stability_coef: float) bool

Check if a cost message match the previous message.

Costs are considered to match if the variation is bellow STABILITY_COEFF.

Parameters:
  • costs (Dict[val, cost]) – Cost information as a dictionary mapping values to costs

  • prev_costs (Dict[val, cost]) – Previous costs as a dict val -> cost

  • stability_coef (float) – If the difference between the two is less than this value, the costs are considered to match.

Returns:

bool

Return type:

True if costs match prev_costs

communication_load(src: FactorComputationNode | VariableComputationNode, target: str) float

The communication cost of an edge between a variable and a factor.

Parameters:
  • src (VariableComputationNode) – The ComputationNode for the source variable.

  • target (str) – the name of the other variable src is sending messages to

Returns:

the size of messages between computation and target.

Return type:

float

computation_memory(computation: FactorComputationNode | VariableComputationNode) float

Memory footprint associated with the maxsum computation node.

Notes

Two formulations of the memory footprint are possible for factors : * If the constraint is given by a function (intentional), the factor

only needs to keep the costs sent by each variable and the footprint is the total size of these cost vectors.

  • If the constraints is given extensively the size of the hypercube of costs must also be accounted for.

Parameters:

computation (FactorComputationNode or VariableComputationNode) – A computation node for a factor or a variable in the factor-graph.

Returns:

the memory footprint of the computation.

Return type:

float

costs_for_factor(variable: Variable, factor: str, factors: List[RelationProtocol], costs: Dict) Dict[Any, float]

Produce the message that must be sent to factor f.

The content if this message is a d -> cost table, where * d is a value from the domain * cost is the sum of the costs received from all other factors except f for this value d for the domain.

Parameters:
  • variable (Variable) – the variable sending the message

  • factor (str) – the name of the factor the message will be sent to

  • factors (list of Constraints) – the constraints this variables depends on

  • costs (dict) – the accumulated costs received by the variable from all factors

Returns:

a dict containing a cost for each value in the domain of the variable

Return type:

Dict

factor_costs_for_var(factor: RelationProtocol, variable: Variable, recv_costs, mode: str)

Computes the marginals to be send by a factor to a variable

The content of this message is a table d -> mincost where * d is a value of the domain of the variable v * mincost is the minimum value of f when the variable v take the

value d

Parameters:
  • factor (Constraint) – the factor that will send these cost to variable

  • variable (Variable) –

  • recv_costs (Dict) – a dict containing the costs received from other variables

  • mode (str) – “min” or “max”

Returns:

a dict that associates a cost to each value in the domain of variable

Return type:

Dict

select_value(variable: Variable, costs: Dict[str, Dict], mode: str) Tuple[Any, float]

Select the value for variable with the best cost / reward (depending on mode)

Parameters:
  • variable (Variable) – the variable for which we need to select a value

  • costs (Dict) – a dict { factorname : { value : costs}} representing the cost messages received from factors

  • mode (str) – min or max

Returns:

a Tuple containing the selected value and the corresponding cost for this computation.

Return type:

Tuple