Library | Version | Basic usage | Geo | RS | HDFF | Measures |
ParMa | latest | y | ||||
URaNuS | latest | y | ||||
Colt | 1.2 | y (Uranus) | ||||
Apache Collections generic | 4.01 | y | ||||
Log4J | 1.2.8 | y | ||||
JScience | 4.3.1 | ? | ||||
Units | 0.0.1 | ? | ||||
JavaCSV | 2.1 | y (Parma) | ||||
JUNG algorithms | 2.0.1 | y | ||||
JUNG API | 2.0.1 | y | ||||
JUNG Graph impl | 2.0.1 | y | ||||
JUNG IO | 2.0.1 | y | ||||
JTS | 1.7.1 | y | ||||
Geo-API | 2.1-M2 | y | ||||
GeoTools Main | 2.3.3 | y | ||||
GeoTools EPSG Wkt | 2.3.3 | y | ||||
GeoTools Referencing | 2.3.3 | y | ||||
JRI | 0.5.1 | y | ||||
Repast simphony bin and src | 2.0.1 | y | ||||
SAF | 2.0.1 | ? | ||||
Wstx asl | 3.2.6 | ? | ||||
STAX API | 1.0.1 | ? | ||||
VecMath | 1.3.1 | ? | ||||
Commons Math3 | 3.2 | y |
If you struggle with finding one of these libraries or getting a working version look in the libs folder of MoRe's source code
Adapt and call the following method from your build(context) method after initialisation of agents:
// Define your social context if it is not the main context Context<YourAgent> socialContext = context.getSubContext(socialContextId); // Instantiate your edge factory in case you want to use custom edge objects. // Otherwise, use MRepastEdge<AgentType> as edge type parameter and use new MRsEdgeFactory<AgentType, MRepastEdge<AgentType>() MRsEdgeFactory<YourAgent, YourEdge> eFac = new YourEdgeFactory(); MoreRsNetworkBuilder<YourAgent, YourEdge> networkBuilder = new MGeoRsWattsBetaSwBuilder(eFac, socialNetworkName); MoreRsNetwork<YourAgent, YourEdge> network = networkBuilder.buildNetwork(agents); socialContext.addProjection(network); // init More MManager.init(); MManager.setSchedule(new MRsSchedule(RunEnvironment.getInstance().getCurrentSchedule())); // Register network at MoRe MNetworkManager.setNetwork(network, socialNetworkName);
Consider the following steps to initialise MoRe properly:
NOTE: Make sure to set up parameters before MManager.init() is called because otherwise defined parameters may not be considered during the initialisation of random number streams!
MoRe incorporates the Apache Log4J framework. See the website for configuring the logging framework properly in order to achieve the desired output. This is especially important to get meaningful warnings and error messages. Two basic configuration file can be found in config/log4j (with specific settings mostly out-commented). Note that the configuration file needs to be within the Java classpath.
The MMilieuNetDataReader can be used to read milieu-specific parameters from a database (often used for generating heterogeneous, agent type specific networks). First, set according parameters in your model:
PmParameterManager.setParameter(MSqlPa.TBLNAME_NET_PREFS, "param_milieu_net"); PmParameterManager.setParameter(MSqlPa.TBLNAME_NET_PREFS_LINKS, "param_milieu_links"); PmParameterManager.setParameter(MNetworkBuildingPa.MILIEU_NETPREFS_PARAMID, new Integer(1));
Make also sure general DB settings are set correctly (see ). Then, call the data reader:
new MMilieuNetDataReader().initParameters();
The MMilieuNetDataCsvReader and MMilieuNetLinkDataCsvReader parameter readers are able to import milieu-specific parameters from CSV files.
The first one requires parameters to be specified in the first row (header). The parameter MNetworkBuildingPa.MILIEU_NETWORK_CSV_COLUMNPREFIX defines a prefix for parameter definitions that needs to be omitted from the fully qualified classname in the header.
PmParameterManager.getNewInstance pm = PmParameterManager.getNewInstance(); pm.setParam(MNetworkBuildingPa.MILIEU_NETWORK_CSV_MILIEUS, "./path/to/SocialNetworkMilieuParameter.csv"); new MMilieuNetDataCsvReader(pm).initParameters();
The second reader loads milieu-specific composition preferences and may not contain a header:
PmParameterManager.getNewInstance pm = PmParameterManager.getNewInstance(); pm.setParam(MNetworkBuildingPa.MILIEU_NETWORK_CSV_MILIEU_LINKS, "./path/to/SocialNetworkMilieuLinksParameter.csv"); new MMilieuNetDataCsvReader(pm).initParameters();
Setting MNetworkBuildingPa.MILIEU_NETWORK_CSV_DELIMITER can be use to adjust the readers to the applied delimiter (default is ','):
pm.setParam(MNetworkBuildingPa.MILIEU_NETWORK_CSV_DELIMITER, ',')
The test classes de.cesr.more.testing.param.reader.MMilieuNetDataCsvReaderTest and de.cesr.more.testing.param.reader.MMilieuNetLinkDataCsvReaderTest contain working examples. According CSV files are located at ./test/res/.
The concept of network and node measures works as follows:
The central class for managing node measures is MNodeMeasureManager. To obtain an instance of the node measure manager call MNodeMeasureManager.getInstance(). However, make sure to set the schedule before:
MNetworkManager.setSchedule(MoreSchedule schedule)
To use the Repast Simphony schedule (adapter from RS's ISchedule to MoreSchudule) call
MNetworkMeasureManager.setSchedule(new MRsSchedule(RunEnvironment.getInstance().getCurrentSchedule()));
Every MoreMeasure has a parameter map. The map contains key - (default)value pairs of parameters. the user may walk through the map and alter parameter values to adjust measure calculations. For instance, to set scheduling parameters:
// set scheduling parameters: Map < String , Object > params = new HashMap < String , Object >(); params.put(MNetworkMeasureManager.ParameterKeys.START.name(), new Integer(1)); int interval = (Integer) PmParameterManager.getParameter(SocNetPa.ANALYSE_NETWORKS_INTERVAL); params.put(MNetworkMeasureManager.ParameterKeys.INTERVAL.name(), new Integer(interval)); params.put(MNetworkMeasureManager.ParameterKeys.END.name(), MScheduleParameters.END_TICK); params.put(MNetworkMeasureManager.ParameterKeys.PRIORITY.name(), MScheduleParameters.FIRST_PRIORITY);
NOTE: It is not guaranteed that a MoreMeasure provides a non-empty map!
The params map (see above) is then passed when triggering a measure calculation:
// add measures for overall network: MNodeMeasureManager.getInstance().addMeasureCalculation(ModelManager.SOCNET_NAME, MBasicNodeMeasureSupplier.Short.N_STAT_AVGPATH.getName(), params);
More offers features to access node measures. The agent class needs to implement the interface MoreNodeMeasureSupport:
protected MNodeMeasures measures = new MNodeMeasures();
@Override public void setNetworkMeasureObject( MoreNetwork<? extends MoreNodeMeasureSupport, ?> network, MMeasureDescription key, Number value) { measures.setNetworkMeasureObject(network, key, value); } @Override public Number getNetworkMeasureObject( MoreNetwork<? extends MoreNodeMeasureSupport, ?> network, MMeasureDescription key) { if (measures.getNetworkMeasureObject(network, key) == null) { // <- LOGGING logger.error("No measure defined for key " + key); // LOGGING -> } return measures.getNetworkMeasureObject(network, key); }
The central class for managing network measures is MNetworkMeasureManager. To obtain an instance of the network manager call <<<MNetworkMeasureManager.getInstance(). However, make sure to set the schedule before: MNetworkManager.setSchedule(MoreSchedule schedule)!
The params map (see above) is then passed when triggering a measure calculation:
MNetworkManager netMan = MNetworkManager.getInstance(); netMan.addMeasureCalculation(net, MCentralityNetMSupplier.Short.NET_CEN_DEGREE.getName(), params);
As default, the MNetworkMeasureManager imports measure definitions from MBasicNetworkMeasureSupplier (see JavaDoc for details). Further measure definitions are added by passing an instance of MoreMeasureSupplier to MNetworkMeasureManager#addMeasureSupplier(supplier). See Implementing Custom Measures for further instructions.
MoRe supports the definition of subnetworks according to criteria that may be derived from Java object properties to calculate network measures for certain network parts, for instance. As a default, subnetworks consist of nodes that fulfill given criteria and all links of the original network between these nodes. To define a subnetwork accomplish the following steps:
MNetworkManager.storeVertexSubnetwork(network, predicate, subnetwork_name)
Network may be the name of a network already registered at the MNetworkManager or an instance of MoreNetwork.
public enum Short { YOUR_MEASURE("YourMeasureName"); String name; private Short(String name) { this.name = name; } public String getName() { return name; } }
private DirectedInfoMapModularitySupplier() { categories.add(MNetworkMeasureCategory.NETWORK_MODULARITY); addMeasures(); }
A MNetworkMeasureSupplier should be implemented as singleton since it does not make sense to have more than one supplier. However, the MAbstractMeasureSupplier overrides equals() and compares regarding the class name but does not prevent subclasses from overriding its equals() method.
private void addMeasures() { MMeasureDescription description = new MMeasureDescription( MNetworkMeasureCategory.NETWORK_MODULARITY, Short.YOUR_MEASURE.getName(), "Your measure description"); measures.put(description, new MAbstractNetworkMeasure(description, Double.class) { @Override public <T, EdgeType extends MoreEdge<? super T>> MoreAction getAction( final MoreNetwork<T, EdgeType> network, Map<String, Object> parameters) { return new MAbstractAction() { @Override public void execute() { double value = <calculate your measure here>; MNetworkManager.setNetworkMeasure( network, new MMeasureDescription( Short.NET_MOD_UNDIRECTED_INFOMAP .getName()), value); } @Override public String toString() { return Short.YOUR_MEASURE.getName() + "(" + network.getName() + ")"; } }; } }); }
MNetworkMeasureManager.getInstance().addMeasureSupplier( YourMeasureSupplier.getInstance());
The scheduling parameters (start, interval, end) are defined in the parameter map that is interpreted by MNetworkMeasureManager or MNodeMeasureManager. Therefore, generating MoreActions does not need to define a MSchedulingParameter.
With MoreEgoNetworkManagerComp MoRe provides an agent component that can manage agent's links. Agents may implement MoreEgoNetworkManagingAgent to guarantee access to the component.
The MoreEgoNetworkManagerComp delegates MoreEgoNetworkEvents to potentially different MoreEgoNetworkProcessors. To configure the MoreEgoNetworkManagerComp using a map as configuration object, code accordingly:
MoreEgoNetworkProcessor<MoreNetworkAgent, MoreEdge>> yourEdgeProcessor = new MoreEgoNetworkProcessor<MoreNetworkAgent, MoreEdge>>() { public void process(A agent, MoreNetwork<A, E> network) { // do something } }; Map<MoreEgoNetworkEvent, MoreEgoNetworkProcessor<MoreNetworkAgent, MoreEdge>> map = MEgoNetworkManagerComp.getEmptyProcessorMap(); map.put(MLinkManagingEvent.getInstance(), yourEdgeProcessor); agent.setEgoNetworkManager(new MEgoNetworkManagerComp<MoreNetworkAgent, MoreEdge>(map));
MoreEgoNetworkProcessor can handle different kinds of MoreEgoNetworkEvents which currently are:
There are a number of MoreEgoNetworkProcessor for specific effects available that can be put into the configuration map directly or be extended (it is recommended to consult the source code since their effects can be quite complex):
To activate link management, the MoreEgoNetworkManagerComp needs to be called with the according event:
agent.getEgoNetworkManager().process(MLinkManagingEvent.getInstance(), agent, network);
MoRe provides the MoreFadingWeightEdge interface which is implemented by all More internal implementations of MoreEdge and support the automatic, constanst dedcrease or increase of all edge weights. The according method is scheduled using a MoreAction.
The RS networks usually deal with changes of edges in the geography via MoreGeoNetworkEdgeModifier, but do not care about adding and removing nodes to and from contexts and geographies. The reason is that these node objects are expected to survive even if they are deleted from the network.
Networks can be stored using MoreIoUtilities: +-- MoreIoUtilities.outputGraph(r.getNetwork(), new File(tickFilename(r))); +--
It is furthermore possible to write specific node attributes into the GraphML file:
Map<String, GraphMLMetadata<Agent>> vertexMetadata = new HashMap<String, GraphMLMetadata<Agent>>(); vertexMetadata.put("X", new GraphMLMetadata<Agent>("X coordinate", "NA", new Transformer<Agent, String>() { @Override public String transform(Agent agent) { return agent.getX(); } })); MoreIoUtilities.outputGraph(r.getNetwork(), new File(tickFilename(r)), vertexMetadata, null);
MoRe uses its own instance of URandomService. Basically, it defines two different random number generators:
By default, and when only a global random seed (RANDOM_SEED) is defined, these point to a single global random number generators (RND_STREAM). However, these streams can be fed by distinct random seeds:
The streams are initialised by calling
MManager.init()
To influence the entire random number generation in MoRe it is sufficient to set the parameter RANDOM_SEED:
PmParameterManager.setParameter(MRandomPa.RANDOM_SEED, new Integer(1));
To influence the random number generation of certain parts of MoRe change the according random number seed, e.g.:
PmParameterManager.setParameter(MRandomPa.RANDOM_SEED_NETWORK_BUILDING, new Integer(2));
Furthermore, it is possible to register custom random number generators for a certain part of MoRe:
MManager.getURandomService().registerGenerator((String) PmParameterManager .getParameter(MRandomPa.RND_STREAM_NETWORK_BUILDING), new MersenneTwister(3));
Alternatively, you may register your custom random number generator and adapt the stream name parameter accordingly.
See the URaNuS manual for further information, especially Full Flexibility.