DBSCAN: integration

parent d947286a
Pipeline #93822 failed with stages
in 5 minutes and 21 seconds
package de.monticore.lang.monticar.generator.middleware.clustering;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.DBSCANClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.MarkovClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.SpectralClusteringAlgorithm;
import de.se_rwth.commons.logging.Log;
......@@ -14,6 +15,7 @@ public class ClusteringAlgorithmFactory {
switch (kind){
case SPECTRAL_CLUSTERER: return new SpectralClusteringAlgorithm();
case MARKOV_CLUSTERER: return new MarkovClusteringAlgorithm();
case DBSCAN_CLUSTERER: return new DBSCANClusteringAlgorithm();
default: Log.error("0x1D54C: No clustering algorithm found for ClusteringKind " + kind);
}
return null;
......
......@@ -2,5 +2,6 @@ package de.monticore.lang.monticar.generator.middleware.clustering;
public enum ClusteringKind {
SPECTRAL_CLUSTERER,
MARKOV_CLUSTERER
MARKOV_CLUSTERER,
DBSCAN_CLUSTERER
}
package de.monticore.lang.monticar.generator.middleware.clustering.algorithms;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClusteringHelper;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.se_rwth.commons.logging.Log;
import smile.clustering.DBSCAN;
import java.util.*;
// DBSCAN clusterer product implementation
public class DBSCANClusteringAlgorithm implements ClusteringAlgorithm {
@Override
public List<Set<ExpandedComponentInstanceSymbol>> cluster(ExpandedComponentInstanceSymbol component, Object... args) {
List<Set<ExpandedComponentInstanceSymbol>> res = new ArrayList<>();
// params
Integer minPts= null;
Double radius= null;
// find mandatory params
Map<DBSCANClusteringBuilder.DBSCANParameters, Boolean> mandatoryParams = new HashMap<DBSCANClusteringBuilder.DBSCANParameters, Boolean>();
DBSCANClusteringBuilder.DBSCANParameters[] dbscanParams = DBSCANClusteringBuilder.DBSCANParameters.values();
for (DBSCANClusteringBuilder.DBSCANParameters param : dbscanParams) {
// set all mandatory params to "unset"
if (param.isMandatory()) mandatoryParams.put(param, false);
}
// Handle (optional) params for DBSCANClustering.
// Params come as one or multiple key-value-pairs in the optional varargs array for this method,
// with key as a string (containing the name of the parameter to pass thru to the clusterer) followed by its value as an object
DBSCANClusteringBuilder.DBSCANParameters key;
Object value;
int v = 0;
while (v < args.length) {
if (args[v] instanceof DBSCANClusteringBuilder.DBSCANParameters) {
key = (DBSCANClusteringBuilder.DBSCANParameters)args[v];
if (v+1 < args.length) {
value = args[v + 1];
switch (key) {
case DBSCAN_MIN_PTS:
if (value instanceof Integer) {
minPts= (Integer) value;
}
break;
case DBSCAN_RADIUS:
if (value instanceof Double) {
radius= (Double) value;
}
break;
}
// set mandatory param to "set"
if (key.isMandatory()) mandatoryParams.replace(key, true);
}
}
v = v + 2;
}
// are all mandatory params set?
boolean error= false;
Iterator iterator = mandatoryParams.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry param = (Map.Entry) iterator.next();
if (!(Boolean)param.getValue()) error= true;
}
if (error) {
Log.error("DBSCANClusteringAlgorithm: Mandatory parameter(s) missing!");
} else {
List<ExpandedComponentInstanceSymbol> subcompsOrderedByName = ComponentHelper.getSubcompsOrderedByName(component);
Map<String, Integer> labelsForSubcomps = ComponentHelper.getLabelsForSubcomps(subcompsOrderedByName);
double[][] adjMatrix = AutomaticClusteringHelper.createAdjacencyMatrix(subcompsOrderedByName,
ComponentHelper.getInnerConnectors(component),
labelsForSubcomps);
DBSCAN clustering;
DBSCANClusteringBuilder builder = new DBSCANClusteringBuilder(adjMatrix, minPts, radius);
clustering = builder.build();
int[] labels = clustering.getClusterLabel();
for (int i = 0; i < clustering.getNumClusters(); i++) {
res.add(new HashSet<>());
}
subcompsOrderedByName.forEach(sc -> {
int curClusterLabel = labels[labelsForSubcomps.get(sc.getFullName())];
res.get(curClusterLabel).add(sc);
});
}
return res;
}
}
package de.monticore.lang.monticar.generator.middleware.clustering.algorithms;
import smile.clustering.DBSCAN;
public class DBSCANClusteringBuilder {
private double[][] data; // expected: (weighted) adjacency matrix
private Integer minPts;
private Double radius;
// parameter list, true if mandatory
public enum DBSCANParameters {
DBSCAN_MIN_PTS(true),
DBSCAN_RADIUS(true);
private Boolean mandatory;
DBSCANParameters(Boolean mandatory) {
this.mandatory = mandatory;
}
public Boolean isMandatory() {
return this.mandatory;
}
}
public DBSCANClusteringBuilder(double[][] data, int minPts, double radius) {
this.data = data;
this.minPts = minPts;
this.radius= radius;
}
public DBSCANClusteringBuilder setData(double[][] data) {
this.data = data;
return this;
}
public DBSCANClusteringBuilder setMinPts(int minPts) {
this.minPts = minPts;
return this;
}
public DBSCANClusteringBuilder setRadius(double radius) {
this.radius = radius;
return this;
}
public DBSCAN build() {
DBSCAN dbc;
// |nodes| instances of data with pseudo x,y coords. set to node no.
double[][] pdata = new double[this.data.length][2];
for (int i=0; i<pdata.length; i++) {
pdata[i][0]= i;
pdata[i][1]= i;
}
dbc = new DBSCAN(pdata, new DBSCANDistance(data), minPts, radius);
return dbc;
}
}
......@@ -6,10 +6,7 @@ import de.monticore.lang.monticar.generator.middleware.clustering.AutomaticClust
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringAlgorithmFactory;
import de.monticore.lang.monticar.generator.middleware.clustering.ClusteringKind;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.DBSCANDistance;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.MarkovClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.SpectralClusteringAlgorithm;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.SpectralClusteringBuilder;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.*;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.impls.CPPGenImpl;
import de.monticore.lang.monticar.generator.middleware.impls.RosCppGenImpl;
......@@ -345,6 +342,12 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{
case SPECTRAL_CLUSTERER:
params= new Object[] { SpectralClusteringBuilder.SpectralParameters.SPECTRAL_NUM_CLUSTERS, 2 };
break;
case DBSCAN_CLUSTERER:
params= new Object[] {
DBSCANClusteringBuilder.DBSCANParameters.DBSCAN_MIN_PTS, 1,
DBSCANClusteringBuilder.DBSCANParameters.DBSCAN_RADIUS, 10.0
};
break;
}
testCreateClusters(ClusteringAlgorithmFactory.getFromKind(kind), params);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment