Node Linker
Node Linker allows you to easily link one node ("i") with another node
("j") according to some user-defined probability. The idea here is
that i will create a link with some other agent chosen at random. The
choice of who to link with is determined by a vector of relative
weights assigned to other agents that i may possibly link with. The
probabilty of i linking with j is determined using these weights, and
that these weights are updated over the iterations of the simulation
in response to network evolution.
For example, the probability of i creating a link with j may be
calculated by dividing j's current weight by the sum of all the
weights in the weight vector. Assuming then that i does link with j,
j's weight may then be updated by some amount increasing the
probabilty that i will link with j again.
The actual usage of Node Linker is described below in the
usage section below.
Default Network Node. Node Linker must
be added only to a Default Network Node.
Properties are the items that appear in the property pane when you click
on a component in the project tree. For more information of properties, see
here.
Actions |
See the section on Actions and editing
them if you are unfamiliar with Actions.
Node Linker defines two actions by default.
- getProbabilty. This action is used to calculate the probabilty of
one node linking to another.
- update. This action is used update the vector of node weights by
the specified amount.
See the usage section below for more information.
|
Name |
This name is used internally by SimBuilder and should not contain any
spaces.
|
Parameters |
See the the parameters section of the help docs
for information on creating and editing parameters.
Here you can define any parameters you want your node linker to have.
See the usage section below for more information.
|
Start Weight |
The starting weight for nodes in the weight vector.
|
|
Fields are variables that the component exposes for your use in code. For
example, if there is a field named sumt, you can refer to
that field with self.sum in your NQPy code.
discount |
The past discount. A float value between 0 and 1. This can be set with the
setPastDiscount action / method.
|
sum |
The current sum of the weight vector.
|
|
Many of the SimBuilder components are based on Java code. What this means
is that these components come with built-in fields and methods inherited from
their Java parent classes. The docs below describe these built in fields
and methods.
Node Linker is based on the java class
AbstractProbabilityRule.
AbstractProbablilityrRules implements some generic functionality for ProbabilityRule-s. The idea
here is that this AbstractProbabilityRule contains a vector of weights
associated with a list of Objects. Sub-classes can use this vector
of weights in their update and getProbability methods. For example,
update may add or substract some amount from an objects associated
weight and recalculate the probability accordingly.
The of a Java parent class can be used
just as if they were parameters in your own model. For example,
self.descriptors and so on. The format used below is
field name : field type
description
where the field type is a Java class type.
-
weights :
FloatArrayList
- The list of wieghts for each object
-
weightMap :
Hashtable
- Maps Objects to the weights in the weight map.
|
|
The of a Java parent
class can be used just as if they were actions in your own model. For example,
self.setRngSeed(33) and so on. The format used below is
method name(argument types, if any) : return type - an optional explanation
of the return type
description
where the return type is a Java class type.
-
addNode(
Object
,
float
) :
- Adds a node with the specified weight.
-
addToNodeWeight(
Object
,
float
) :
float
- Adds the specified value to the current weight for the
specified node.
-
calcSum(
) :
- Calculates the sum of the vector of weights.
-
getWeight(
Object
) :
float
- Gets the weight of the specified node.
-
getWeightListIndex(
Object
) :
int
- Returns the index position in the list of weights for the
specified object. The returned value is the index for the weight
value of the specified object.
-
makeProbabilityMap(
RangeMap
) :
RangeMap
- Recreate the probability map for the list of Objects
contained by this AbstractProbabilityRule using the specified
RangeMap.
update(
Object
) :
Updates the weights for the specified object by 1.
|
|
Adding a NodeLinker to an Agent component adds two parameters and some
code to that Agent component. The two parameters are:
- _linker. _linker is of type Linker (see Linker in the RePast
javadoc), and is what an agent will use to create links between
itself and other nodes.
- startWeight. This corresponds to the start weight property above,
and allows the you to change the start weight when the RePast
simulation is running.
NodeLinker also adds code to the Agent's init action. The code looks
like:
### uchicago.src.simbuilder.beans.NodeLinker Generated Code ###
rule = NodeLinker(self.model.getAgentList(), self.startWeight, self)
self._linker = Linker(rule)
The first line here is a comment and identifies the next two lines as
SimBuilder (not user) generated code. The next two lines create a
NodeLinker and then create _linker using that newly created
NodeLinker. The important point here is that the NodeLinker here is
created using the NodeLinker component as a template (much the same as
agents are created), and that this NodeLinker is now part of _linker.
Three three important actions / methods that _linker has are:
- init. The init action initializes _linker for link creation by
recreating the probability map. The probability map is created by
calling the getProbability action of the NodeLinker, passing in each
node to which a link could be created. The map itself maps nodes to
probabilities, the larger the probability the more likely that node
will be chosen as a the end of a link. init should be called before
any calls to makeLink if the result of those calls is to reflect any
updates.
- makeLink(from, edge, amtToUpdate). Using the current probabilty map
(see 1. above) this method creates an edge between a randomly chosen node and
the from node. It also calls NodeLinker's update action passing in the
randomly chosen node and the amtToUpdate.
- makeLink(from, edge). This merely calls the above with amount to
update of 1.
The important points here are how _linker uses NodeLinker's
getProbability action to create the probability map, and how _linker
uses NodeLinker's update action to update the weight vector.
Implementing getProbabilty and update:
getProbability and update are
unlike user defined actions in that they have arguments passed in to
them. You can see these arguments in the variables pane of the Action
editor. They are specific to these two actions respectively and are
not prefixed by self.
- getProbability. This action has a single passed in argument -
otherNode. This "otherNode" is the node for which we want to calculate
the probability. If, for example, we are calculating the probability
by getting the current weight of otherNode and dividing it by the sum
of the all the weights then the source code to getProbabilty would
look like:
return self.getWeight(otherNode) / self.sum
Notice the return keyword here. getProbability must return some
numeric value and the return keyword does this. If you do not include
the return statement, you'll either get an appropriate error message
or a cryptic one reporting Compiler Error: Compilation not supported
on expr_stmt. In either case, you need to return a value.
- update. This action has two passed in arguments, otherNode and
amtToUpdate. The intention here is that you update the vector of
weights using these values. otherNode is the node whose weight we want
to update, and amtToUpdate is the amount we want to update the
weight. Of course, you can do whatever transformations of this
amtToUpdate value you like, or ignore it all together. The simplest
update to the weight vector looks like:
self.addToNodeWeight(otherNode, amtToUpdate)
which simply adds otherNode amtToUpdate to the current weight of the
otherNode.
The NodeLinker inherits several important methods / actions and
variables from its java ancestors. These are described below.
- sum. This is the current sum of the weight vector. It is
recalculated each time _linker.init() is called.
- getWeight(otherNode) - this returns the weight for otherNode.
- addToNodeWeight(otherNode, amtToUpdate) - this adds the amtToUpdate
to the current weight of otherNode.
Using a NodeLinker then is a matter of adding one to an agent
component in the SimBuilder project pane, and then defining the
getProbability and update methods to suit your own needs. The agent
then uses the _linker parameter provided by the NodeLinker component
to make links based on the probabilities update etc. defined in
NodeLinker. This is typically done in the step action. For example the
following step action code,
self.clearOutEdges()
self._linker.makeLink(self, DefaultDrawableEdge(), 1)
removes any previously created outgoing edges from the agent, and then
creates a new link between this agent ("self") and one chosen at
random. DefaultDrawableEdge is used as the edge, and the weight of the
randomly chosen otherNode is updated by 1.
The sample simulations distributed with SimBuilder contain some simulations
using the NodeLinker, so see those for more complicated examples.
|