Search in sources :

Example 16 with NodeBase

use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.

the class TreeData method addNewNode.

public int addNewNode(final int position, final String name, final double flow, final double teleportWeight) {
    final NodeBase node = nodeFactory.createNode(name, flow, teleportWeight);
    node.setOriginalIndex(position);
    root.addChild(node);
    leafNodes.add(node);
    return node.getOriginalIndex();
}
Also used : NodeBase(au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase)

Example 17 with NodeBase

use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.

the class InfomapBase method processPartitionQueue.

private boolean processPartitionQueue(final PartitionQueue queue, final PartitionQueue nextLevelQueue, final boolean tryIndexing) {
    final int numModules = queue.size();
    final double[] indexCodelengths = new double[numModules];
    final double[] moduleCodelengths = new double[numModules];
    final double[] leafCodelengths = new double[numModules];
    final PartitionQueue[] subQueues = new PartitionQueue[numModules];
    for (int i = 0; i < numModules; i++) {
        subQueues[i] = new PartitionQueue();
    }
    // This loop can be parallelised?
    for (int moduleIndex = 0; moduleIndex < numModules; moduleIndex++) {
        final NodeBase module = queue.get(moduleIndex);
        // Delete former sub-structure if exists.
        module.getSubStructure().setSubInfomap(null);
        module.setCodelength(calcCodelengthFromFlowWithinOrExit(module));
        // If only trivial substructure is to be found, no need to create infomap instance to find sub-module structures.
        if (module.getChildDegree() <= 2) {
            leafCodelengths[moduleIndex] = module.getCodelength();
            continue;
        }
        final PartitionQueue subQueue = subQueues[moduleIndex];
        subQueue.setLevel(queue.getLevel() + 1);
        final InfomapBase subInfomap = getNewInfomapInstance(config, rg);
        subInfomap.subLevel = subLevel + 1;
        subInfomap.initSubNetwork(module, false);
        subInfomap.partitionAndQueueNextLevel(subQueue, tryIndexing);
        // If non-trivial substructure is found which improves the codelength, store it on the module.
        final boolean nonTrivialSubstructure = subInfomap.getNumTopModules() > 1 && subInfomap.getNumTopModules() < subInfomap.getNumLeafNodes();
        final boolean improvement = nonTrivialSubstructure && (subInfomap.hierarchicalCodelength < module.getCodelength() - config.getMinimumCodelengthImprovement());
        if (improvement) {
            indexCodelengths[moduleIndex] = subInfomap.indexCodelength;
            moduleCodelengths[moduleIndex] = subInfomap.moduleCodelength;
            module.getSubStructure().setSubInfomap(subInfomap);
        } else {
            leafCodelengths[moduleIndex] = module.getCodelength();
            module.getSubStructure().setExploredWithoutImprovement(true);
            subQueue.setSkip(true);
        // Else use the codelength from the flat substructure
        }
    }
    double sumLeafCodelength = 0.0;
    double sumIndexCodelength = 0.0;
    double sumModuleCodelengths = 0.0;
    int nextLevelSize = 0;
    for (int moduleIndex = 0; moduleIndex < numModules; moduleIndex++) {
        nextLevelSize += subQueues[moduleIndex].isSkip() ? 0 : subQueues[moduleIndex].size();
        sumLeafCodelength += leafCodelengths[moduleIndex];
        sumIndexCodelength += indexCodelengths[moduleIndex];
        sumModuleCodelengths += moduleCodelengths[moduleIndex];
    }
    queue.setIndexCodelength(sumIndexCodelength);
    queue.setLeafCodelength(sumLeafCodelength);
    queue.setModuleCodelength(sumModuleCodelengths);
    // Collect the sub-queues and build the next-level queue.
    nextLevelQueue.setLevel(queue.getLevel() + 1);
    nextLevelQueue.resize(nextLevelSize);
    int nextLevelIndex = 0;
    for (int moduleIndex = 0; moduleIndex < numModules; moduleIndex++) {
        final PartitionQueue subQueue = subQueues[moduleIndex];
        if (!subQueue.isSkip()) {
            for (int subIndex = 0; subIndex < subQueue.size(); ++subIndex) {
                nextLevelQueue.set(nextLevelIndex++, subQueue.get(subIndex));
            }
            nextLevelQueue.setFlow(nextLevelQueue.getFlow() + subQueue.getFlow());
            nextLevelQueue.setNonTrivialFlow(nextLevelQueue.getNonTrivialFlow() + subQueue.getNonTrivialFlow());
            nextLevelQueue.setNumNonTrivialModules(nextLevelQueue.getNumNonTrivialModules() + subQueue.getNumNonTrivialModules());
        }
    }
    return nextLevelSize > 0;
}
Also used : NodeBase(au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase) PartitionQueue(au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.PartitionQueue)

Example 18 with NodeBase

use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.

the class InfomapBase method partitionEachModule.

/**
 * For each module, create a new infomap instance and clone the interior
 * structure of the module as the new network to partition. Collect the
 * results by populating the index member of each leaf node with the
 * sub-module structure found by partitioning each module.
 */
private void partitionEachModule(final int recursiveCount, final boolean fast) {
    int moduleIndexOffset = 0;
    for (final NodeBase module : getRoot().getChildren()) {
        // If only one child in the module, no need to create infomap instance to find sub-module structures.
        if (module.getChildDegree() == 1) {
            for (final NodeBase node : module.getChildren()) {
                node.setIndex(moduleIndexOffset);
            }
            moduleIndexOffset += 1;
            continue;
        }
        if (DEBUG) {
            final String log = String.format(">>>>>>>>>>>>>>>>>> RUN SUB_INFOMAP on node n%d with childDegree: %d >>>>>>>>>>>>\n", module.getId(), module.getChildDegree());
            LOGGER.log(Level.INFO, log);
        }
        final InfomapBase subInfomap = getNewInfomapInstance(config, rg);
        // To not happen to get back the same network with the same seed.
        subInfomap.reseed(NodeBase.uid());
        subInfomap.subLevel = subLevel + 1;
        subInfomap.initSubNetwork(module, false);
        subInfomap.partition(recursiveCount, fast);
        if (DEBUG) {
            LOGGER.log(Level.INFO, "<<<<<<<<<<<<<<<<<<< BACK FROM SUB_INFOMAP!!!! <<<<<<<<<<<<<<<<<<<%n");
            final String log = String.format("Node n%d with %d leaf-nodes gave %d sub-clusters%n", module.getId(), subInfomap.treeData.getNumLeafNodes(), subInfomap.treeData.getRoot().getChildDegree());
            LOGGER.log(Level.INFO, log);
        }
        final Iterator<NodeBase> originalLeafNodeIt = module.getChildren().iterator();
        for (final NodeBase node : subInfomap.treeData.getLeaves()) {
            originalLeafNodeIt.next().setIndex(node.getParent().getIndex() + moduleIndexOffset);
        }
        moduleIndexOffset += subInfomap.treeData.getRoot().getChildDegree();
    }
}
Also used : NodeBase(au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase)

Example 19 with NodeBase

use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.

the class InfomapBase method partition.

private void partition(final int recursiveCount, final boolean fast, final boolean forceConsolidation) {
    if (DEBUG) {
        final String log = String.format("%s.partition(%d,%s,%s)%n", getClass().getSimpleName(), recursiveCount, fast, forceConsolidation);
        LOGGER.log(Level.INFO, log);
    }
    final boolean verbose = (subLevel == 0 && config.getVerbosity() != 0) || (isSuperLevelOnTopLevel() && config.getVerbosity() == 2);
    if (treeData.getFirstLeaf().getParent() != getRoot()) {
        final String log = String.format("Already partitioned with codelength %d in %d modules.%n", codelength, getNumTopModules());
        LOGGER.log(Level.INFO, log);
        return;
    }
    setActiveNetworkFromChildrenOfRoot();
    initConstantInfomapTerms();
    initModuleOptimization();
    if (verbose) {
        if (config.getVerbosity() == 0) {
            LOGGER.log(Level.INFO, "Two-level compression: ");
        } else {
            LOGGER.log(Level.INFO, "Trying to find modular structure...");
            final String log = String.format("Initiated to codelength %f + %f = %f in %d modules.%n", indexCodelength, moduleCodelength, codelength, getNumTopModules());
            LOGGER.log(Level.INFO, log);
        }
    }
    final double initialCodelength = codelength;
    mergeAndConsolidateRepeatedly(forceConsolidation, fast);
    if (DEBUG) {
        final String log = String.format("[codelength, initialCodelength = %f,%f]%n", codelength, initialCodelength);
        LOGGER.log(Level.INFO, log);
    }
    double oldCodelength = oneLevelCodelength;
    double compression = (oldCodelength - codelength) / oldCodelength;
    if (verbose && config.getVerbosity() == 0) {
        final String log = String.format(FOUR_FORMAT, compression * 100);
        LOGGER.log(Level.INFO, log);
    }
    if (!fast && config.getTuneIterationLimit() != 1 && getNumTopModules() != getNumLeafNodes()) {
        int tuneIterationCount = 1;
        int coarseTuneLevel = config.getCoarseTuneLevel() - 1;
        boolean doFineTune = true;
        oldCodelength = codelength;
        while (getNumTopModules() > 1) {
            if (doFineTune) {
                fineTune();
                if (codelength > oldCodelength - initialCodelength * config.getMinimumRelativeTuneIterationImprovement() || codelength > oldCodelength - config.getMinimumCodelengthImprovement()) {
                    break;
                }
                compression = (oldCodelength - codelength) / oldCodelength;
                if (verbose && config.getVerbosity() == 0) {
                    final String log = String.format(FOUR_FORMAT, compression * 100);
                    LOGGER.log(Level.INFO, log);
                }
                oldCodelength = codelength;
            } else {
                coarseTune(config.isAlternateCoarseTuneLevel() ? (++coarseTuneLevel % config.getCoarseTuneLevel()) : config.getCoarseTuneLevel() - 1);
                if (codelength > oldCodelength - initialCodelength * config.getMinimumRelativeTuneIterationImprovement() || codelength > oldCodelength - config.getMinimumCodelengthImprovement()) {
                    break;
                }
                compression = (oldCodelength - codelength) / oldCodelength;
                if (verbose && config.getVerbosity() == 0) {
                    final String log = String.format(FOUR_FORMAT, compression * 100);
                    LOGGER.log(Level.INFO, log);
                }
                oldCodelength = codelength;
            }
            ++tuneIterationCount;
            if (config.getTuneIterationLimit() == tuneIterationCount) {
                break;
            }
            doFineTune = !doFineTune;
        }
    }
    if (verbose) {
        if (config.getVerbosity() == 0) {
            final String fmt = String.format("%s.%df", "%", config.getVerboseNumberPrecision());
            final String cl = String.format(fmt, codelength);
            final String log = String.format("to %d modules with codelength %s%n", getNumTopModules(), cl);
            LOGGER.log(Level.INFO, log);
        } else {
            final String log = String.format("Two-level codelength: %f + %f = %f%n", indexCodelength, moduleCodelength, codelength);
            LOGGER.log(Level.INFO, log);
        }
    }
    if (!fast && recursiveCount > 0 && getNumTopModules() != 1 && getNumTopModules() != getNumLeafNodes()) {
        partitionEachModule(recursiveCount - 1);
        // Prepare leaf network to move into the sub-module structure given from partitioning each module.
        setActiveNetworkFromLeafs();
        int i = 0;
        for (final NodeBase leaf : treeData.getLeaves()) {
            moveTo.set(i, leaf.getIndex());
            assert moveTo.get(i) < activeNetwork.size();
            i++;
        }
        initModuleOptimization();
        moveNodesToPredefinedModules();
        // Consolidate the sub-modules and store the current module structure in the sub-modules before replacing it.
        consolidateModules(true, true);
        // Set module indices from a zero-based contiguous set.
        int packedModuleIndex = 0;
        for (final NodeBase module : getRoot().getChildren()) {
            module.setOriginalIndex(packedModuleIndex++);
            module.setIndex(module.getOriginalIndex());
        }
    }
}
Also used : NodeBase(au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase)

Example 20 with NodeBase

use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.

the class InfomapBase method setActiveNetworkFromChildrenOfRoot.

private void setActiveNetworkFromChildrenOfRoot() {
    if (DEBUG) {
        final String log = String.format("%s.setActiveNetworkFromChildrenOfRoot() with child degree %d...\n", getClass().getSimpleName(), getRoot().getChildDegree());
        LOGGER.log(Level.INFO, log);
    }
    final int numNodes = getRoot().getChildDegree();
    activeNetwork = nonLeafActiveNetwork;
    Resizer.resize(activeNetwork, numNodes, null);
    assert nonLeafActiveNetwork.size() == numNodes;
    int i = 0;
    for (final NodeBase child : getRoot().getChildren()) {
        activeNetwork.set(i, child);
        i++;
    }
}
Also used : NodeBase(au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase)

Aggregations

NodeBase (au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase)30 Node (au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.Node)6 PartitionQueue (au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.PartitionQueue)2 MultiMap (au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.util.MultiMap)2 Map (java.util.Map)2 TreeMap (java.util.TreeMap)2 FlowBase (au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.traits.FlowBase)1 TreeData (au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.tree.TreeData)1 Tuple (au.gov.asd.tac.constellation.utilities.datastructure.Tuple)1 File (java.io.File)1