use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.PartitionQueue in project constellation by constellation-app.
the class InfomapBase method runPartition.
public void runPartition() {
hierarchicalCodelength = oneLevelCodelength;
indexCodelength = oneLevelCodelength;
moduleCodelength = 0;
if (config.isTwoLevel()) {
partition();
hierarchicalCodelength = codelength;
for (final NodeBase module : getRoot().getChildren()) {
module.setCodelength(calcCodelengthFromFlowWithinOrExit(module));
}
return;
}
final PartitionQueue partitionQueue = new PartitionQueue();
if (config.getFastHierarchicalSolution() != 0) {
final int numLevelsCreated = findSuperModulesIterativelyFast(partitionQueue);
// Print current hierarchical solution.
if (config.getFastHierarchicalSolution() < 3 && hierarchicalCodelength < bestIntermediateCodelength) {
bestIntermediateCodelength = hierarchicalCodelength;
bestIntermediateStatistics = new StringBuilder();
printPerLevelCodelength(bestIntermediateStatistics);
if (config.getNetworkFile() != null) {
printNetworkData(new File(config.getNetworkFile()).getName() + "_fast");
}
}
if (config.getFastHierarchicalSolution() == 1) {
deleteSubLevels();
queueTopModules(partitionQueue);
} else {
resetModuleFlowFromLeafNodes();
partitionQueue.setLevel(numLevelsCreated);
}
} else {
partitionAndQueueNextLevel(partitionQueue);
}
if (config.getFastHierarchicalSolution() > 2 || partitionQueue.size() == 0) {
return;
}
if (config.getVerbosity() == 0) {
LOGGER.log(Level.INFO, "Recursive sub-structure compression: ");
} else {
final String log = String.format("Current codelength: %f + %f = %f%n", indexCodelength, hierarchicalCodelength - indexCodelength, hierarchicalCodelength);
LOGGER.log(Level.INFO, log);
LOGGER.log(Level.INFO, "Trying to find deeper structure under current modules recursively...");
}
double sumConsolidatedCodelength = hierarchicalCodelength - partitionQueue.getModuleCodelength();
while (partitionQueue.size() > 0) {
if (config.getVerbosity() > 0) {
final String log = String.format("Level %d: %f%% of the flow in %d modules. Partitioning... ", partitionQueue.getLevel(), partitionQueue.getFlow() * 100, partitionQueue.size());
LOGGER.log(Level.INFO, log);
}
final PartitionQueue nextLevelQueue = new PartitionQueue();
// Partition all modules in the queue and fill up the next level queue.
processPartitionQueue(partitionQueue, nextLevelQueue);
final double leftToImprove = partitionQueue.getModuleCodelength();
sumConsolidatedCodelength += partitionQueue.getIndexCodelength() + partitionQueue.getLeafCodelength();
final double limitCodelength = sumConsolidatedCodelength + leftToImprove;
if (config.getVerbosity() == 0) {
final String formattedString = String.format(FOUR_FORMAT, ((hierarchicalCodelength - limitCodelength) / hierarchicalCodelength) * 100);
LOGGER.log(Level.INFO, formattedString);
} else {
final String log = String.format("done! Codelength: %f + %f (+ %f left to improve) -> limit: %.10f bits.\n", partitionQueue.getIndexCodelength(), partitionQueue.getLeafCodelength(), leftToImprove, limitCodelength);
LOGGER.log(Level.INFO, log);
}
hierarchicalCodelength = limitCodelength;
partitionQueue.swap(nextLevelQueue);
}
if (config.getVerbosity() == 0) {
LOGGER.log(Level.INFO, "to codelength {0}", hierarchicalCodelength);
}
}
use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.PartitionQueue 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;
}
Aggregations