/** * * Copyright 2013 Davide Nunes Authors : Davide Nunes <davex.pt@gmail.com> * Website : http://davidenunes.com * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * This file is part of network-api. * * network-api is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * The network-api is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * network-api. If not, see <http://www.gnu.org/licenses/gpl.html>. */ package org.bhave.network.model.impl; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.math3.random.RandomDataGenerator; import org.apache.commons.math3.random.RandomGenerator; import org.bhave.network.api.Network; import org.bhave.network.api.Node; import org.bhave.network.model.KRegularModel; import com.google.inject.Inject; import com.google.inject.Provider; /** * Implementation of {@link KRegularModel} * * @author Davide Nunes */ public class DefaultKRegularModel extends AbstractNetworkModel implements KRegularModel { private static final String K_PARAM = P_K; private static final String NUM_NODES_PARAM = P_NUM_NODES; @Inject public DefaultKRegularModel(Configuration config, RandomGenerator random, Provider<Network> networkProvider) { super(config, random, networkProvider); } @Override Configuration defaultConfiguration(Configuration config) { config.setProperty(NUM_NODES_PARAM, 3); config.setProperty(K_PARAM, 1); config.setProperty(PARAM_SEED, System.currentTimeMillis()); return config; } @Override public void configure(Configuration configuration) throws ConfigurationException { int numNodes = configuration.getInt(NUM_NODES_PARAM); int k = configuration.getInt(K_PARAM); if (numNodes < 0) { throw new ConfigurationException(NUM_NODES_PARAM + " must be > 0"); } if (k < 1 || k > (numNodes / 2)) { throw new ConfigurationException(K_PARAM + " must be within 1 <= k <= (" + NUM_NODES_PARAM + ") / 2"); } } @Override public void generateNetwork() { int numNodes = config.getInt(NUM_NODES_PARAM); int k = config.getInt(K_PARAM); Node[] nodes = new Node[numNodes]; // add nodes to the network for (int i = 0; i < numNodes; i++) { Node newNode = network.createNode(); network.addNode(newNode); nodes[i] = newNode; } // use the existing random number generator to shuffle our nodeArray RandomDataGenerator randomPerm = new RandomDataGenerator(random); int[] perm = randomPerm.nextPermutation(numNodes, numNodes); // create the regular network for (int i = 0; i < numNodes; i++) { int j = 1; // add links to the next k neighbours without duplicated links while (j <= k) { Node n1 = nodes[perm[i]]; Node n2 = nodes[perm[(i + j) % numNodes]]; if (!network.containsLinks(n1, n2)) { network.addLink(n1, n2); } j++; } } } @Override public void configure(int numNodes, int k, long seed) throws ConfigurationException { config.setProperty(NUM_NODES_PARAM, numNodes); config.setProperty(K_PARAM, k); config.setProperty(PARAM_SEED, seed); this.configure(config); } }