From 2fdaa0aa3c454aa3ee36e267e80f324170685a56 Mon Sep 17 00:00:00 2001 From: Lukas Ettel <34522828+LukasEttel@users.noreply.github.com> Date: Mon, 8 Jun 2020 11:37:11 +0200 Subject: [PATCH] release --- pom.xml | 6 +- .../ba/yoshikoWrapper/core/ParameterSet.java | 8 +- .../cytoUtil/GraphAnalyzer.java | 89 +++++++++++++++++++ .../graphModel/YoshikoCluster.java | 4 +- .../swing/components/EditCostPanel.java | 18 +++- .../swing/components/MainPanel.java | 23 +++-- .../swing/components/ResultPanel.java | 13 +-- .../taskFactories/CommandTaskFactory.java | 6 +- .../yoshikoWrapper/tasks/AlgorithmTask.java | 4 +- .../yoshikoAlgorithm/ClusteringAlgorithm.java | 1 - .../yoshikoAlgorithm/GraphTranslator.java | 67 +++++++++++++- .../YoshikoAlgoritmController.java | 1 + 12 files changed, 204 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 8c1c573..1fbd33d 100644 --- a/pom.xml +++ b/pom.xml @@ -32,8 +32,8 @@ </properties> <groupId>de.hhu.ba</groupId> - <artifactId>yoshikoStandalone</artifactId> - <version>0.1.1</version> + <artifactId>YoshikoStandalone</artifactId> + <version>1.0.0</version> <name>YoshikoStandalone</name> @@ -130,7 +130,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>4.8.2</version> + <version>4.11</version> <scope>test</scope> </dependency> <dependency> diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java index 48f1639..f267e05 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java @@ -54,6 +54,8 @@ public class ParameterSet implements TunableValidator public double defaultInsertionCost = -1; @Tunable(description="The default deletion cost that is to be used for edges without an associated weight",context="nogui") public double defaultDeletionCost = 1; + @Tunable(description="The threshold to tackle the problem of a completly poitive graph", context="nogui") + public double threshold = 0; @Tunable(description="A bitmask representing which reduction rules should be used",context="nogui") public String reductionRulesBitMask = "000000"; @@ -80,7 +82,11 @@ public class ParameterSet implements TunableValidator @Tunable(description="Determines the number of clusters that are to be generated. -1 generates the optimal amount of clusters in the sense of WCE",context="nogui") public int clusterCount = -1; - + + + //ugly passing of variables + public boolean containsOnlyPositiveEdges; + public double recomendetTreshold; /** * Default constructor, initializes the column mappings to provide a selection of fitting columns */ diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java index 24ca2d5..a6b8a07 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java @@ -2,6 +2,8 @@ package de.hhu.ba.yoshikoWrapper.cytoUtil; import java.util.List; +import de.hhu.ba.yoshikoWrapper.core.NetworkParsingException; +import de.hhu.ba.yoshikoWrapper.core.ParameterSet; import org.cytoscape.model.CyColumn; import org.cytoscape.model.CyEdge; import org.cytoscape.model.CyNetwork; @@ -160,4 +162,91 @@ public class GraphAnalyzer { } return false; } + + public static double recommendThreshold(CyNetwork net, ParameterSet parameterSet) throws NetworkParsingException{ + double threshold = parameterSet.threshold; + double maxEdgeWeight = Double.NEGATIVE_INFINITY; + double minEdgeWeight = Double.POSITIVE_INFINITY; + + for (CyEdge edge : net.getEdgeList()){ + double weight; + weight = extractValue(edge,net, parameterSet); + weight -= threshold; + + + if (weight < minEdgeWeight){ + minEdgeWeight = weight; + } + if (weight > maxEdgeWeight){ + maxEdgeWeight = weight; + } + } + + if (minEdgeWeight == maxEdgeWeight){ + return 0; + } + + if (minEdgeWeight >= 0){ + return (maxEdgeWeight+minEdgeWeight)/2; + } + return 0; + } + + private static double extractValue(CyEdge edge, CyNetwork network,ParameterSet parameterSet) throws NetworkParsingException { + CyColumn weightColumn = parameterSet.getWeightColumn(); + + //Parse editing costs + double weight = parameterSet.defaultDeletionCost; + + //Fetch entry and check if it exists + CyRow edgeEntry = network.getRow(edge); + + //Check if the column contains an entry for the respective edge + //It is possible, that there are missing entries + if (parameterSet.weightColumn != null){ + if (edgeEntry.get(weightColumn.getName(), weightColumn.getType()) != null){ + if (weightColumn.getType() == Integer.class) { + weight = 1.0*edgeEntry.get(weightColumn.getName(), Integer.class); + } + else if (weightColumn.getType() == Double.class) { + weight = edgeEntry.get(weightColumn.getName(), Double.class); + } + } + } + + + CyColumn permanentColumn = parameterSet.getPermanentColumn(); + CyColumn forbiddenColumn = parameterSet.getForbiddenColumn(); + + //Parse Forbidden/Permanent markers + boolean forbidden = false; + boolean permanent = false; + + if (permanentColumn != null) { + //Additional check as it is not required to have a value in every row + if (edgeEntry.get(permanentColumn.getName(), Boolean.class) != null) { + permanent = (boolean)edgeEntry.get(permanentColumn.getName(), Boolean.class); + } + } + if (forbiddenColumn != null) { + //Additional check as it is not required to have a value in every row + if (edgeEntry.get(forbiddenColumn.getName(), Boolean.class) != null) { + forbidden = (boolean)edgeEntry.get(forbiddenColumn.getName(), Boolean.class); + } + } + + //Check for edges that are forbidden AND permanent -> Throw exception + if (forbidden && permanent) { + throw new NetworkParsingException("dualInfinityError"); + } + + + if(permanent){ + return Double.POSITIVE_INFINITY; + }else if (forbidden){ + return Double.NEGATIVE_INFINITY; + } + + return weight; + } } \ No newline at end of file diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java index 57c4563..40beaed 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java @@ -164,8 +164,8 @@ public class YoshikoCluster { ) ); - view.setVisualProperty(NETWORK_WIDTH, new Double(width)); - view.setVisualProperty(NETWORK_HEIGHT, new Double(height)); + view.setVisualProperty(NETWORK_WIDTH, (double) width); + view.setVisualProperty(NETWORK_HEIGHT, (double) height); view.fitContent(); StyleManager.style(view, CyCore.visualMappingManager.getCurrentVisualStyle()); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java index 257ff59..d86de66 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java @@ -42,11 +42,13 @@ public class EditCostPanel extends JPanel { private final DoubleInputField icField; private final DoubleInputField dcField; + private final DoubleInputField threshholdField; private final JSeparator separator; private final JLabel icLabel; private final JLabel dcLabel; + private final JLabel threshholdLable; //private final HelpButton helpButton; @@ -59,18 +61,21 @@ public class EditCostPanel extends JPanel { icField = new DoubleInputField(Double.NEGATIVE_INFINITY,0); dcField = new DoubleInputField(0,Double.POSITIVE_INFINITY); + threshholdField = new DoubleInputField(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); icField.setText("-1.0"); icField.setToolTipText(LocalizationManager.get("icTooltip")); dcField.setText("1.0"); + threshholdField.setText("0.0"); separator = new JSeparator(JSeparator.HORIZONTAL); icLabel = new JLabel(LocalizationManager.get("defaultInsertion")); - dcLabel = new JLabel(LocalizationManager.get("defaultDeletion")); + dcLabel = new JLabel("Default deletion cost:"); + threshholdLable = new JLabel("Threshold for weight:"); //Add components - SwingUtil.addAll(this,columnMapper,separator,icLabel,icField,dcLabel,dcField); + SwingUtil.addAll(this,columnMapper,separator,icLabel,icField,dcLabel,dcField, threshholdLable, threshholdField); //SwingUtil.addAll(helpButton); @@ -86,11 +91,13 @@ public class EditCostPanel extends JPanel { .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(icLabel) .addComponent(dcLabel) + .addComponent(threshholdLable) ) .addGap(4) .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(icField) .addComponent(dcField) + .addComponent(threshholdField) ) ) ); @@ -109,6 +116,11 @@ public class EditCostPanel extends JPanel { .addGap(4) .addComponent(dcField) ) + .addGroup(layout.createParallelGroup(Alignment.BASELINE) + .addComponent(threshholdLable) + .addGap(4) + .addComponent(threshholdField) + ) ); this.setLayout(layout); @@ -124,6 +136,8 @@ public class EditCostPanel extends JPanel { return dcField.getValueAsDouble(); } + public double getThreshold() {return threshholdField.getValueAsDouble();} + public ColumnMapper getColumnMapper() { return columnMapper; } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java index 190eab5..a6eeb5e 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java @@ -23,6 +23,7 @@ package de.hhu.ba.yoshikoWrapper.swing.components; import static javax.swing.GroupLayout.DEFAULT_SIZE; import static javax.swing.GroupLayout.PREFERRED_SIZE; +import static javax.swing.JOptionPane.showMessageDialog; import java.awt.Component; import java.awt.Dialog.ModalExclusionType; @@ -49,7 +50,6 @@ import javax.swing.ScrollPaneConstants; import de.hhu.ba.yoshikoWrapper.taskFactories.CommandTaskFactory; import de.hhu.ba.yoshikoWrapper.taskFactories.YoshikoCommand; -import de.hhu.ba.yoshikoWrapper.tasks.AlgorithmTask; import org.cytoscape.application.swing.CytoPanelComponent; import org.cytoscape.application.swing.CytoPanelName; import org.cytoscape.model.CyNetwork; @@ -59,12 +59,9 @@ import org.cytoscape.work.TaskIterator; import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.ParameterSet; -import de.hhu.ba.yoshikoWrapper.cytoUtil.CommandExecutor; import de.hhu.ba.yoshikoWrapper.cytoUtil.GraphAnalyzer; -import de.hhu.ba.yoshikoWrapper.help.HelpLinks; import de.hhu.ba.yoshikoWrapper.swing.GraphicsLoader; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; -import org.cytoscape.work.TaskManager; /**This class describes the Swing Panel that the user interacts with in cytoscape * @@ -93,6 +90,8 @@ public class MainPanel extends JPanel implements CytoPanelComponent { private final JButton runButton; + public ParameterSet parameterSet; + /** * Main constructor, creates a new Panel and initializes subcomponents */ @@ -214,6 +213,8 @@ public class MainPanel extends JPanel implements CytoPanelComponent { CyNetwork networkToBeProcessed = CyCore.cy.getCurrentNetwork(); + parameterSet = fetchParameters(networkToBeProcessed); + //WARNINGS FOR FEATURES THAT ARE NOT RESEARCHED //TODO: (Obviously) research! if (GraphAnalyzer.isMultiGraph(networkToBeProcessed)) { @@ -225,7 +226,14 @@ public class MainPanel extends JPanel implements CytoPanelComponent { ); } - + try { + double recommendedThreshold = GraphAnalyzer.recommendThreshold(networkToBeProcessed, parameterSet); + if (!(recommendedThreshold==0)) { + showMessageDialog(null, "The provided graph only consists of edges with \n positive weight and will likely not yield a good result. \n Adjusting the threshold might be necessary. \n"+recommendedThreshold+" might be a good Threshold" , "Threshold-Warning",JOptionPane.WARNING_MESSAGE); + } + }catch (Exception exception){ + exception.printStackTrace(); + } //SWING BLACK MAGIC Window noWindow = null; JDialog statusWindow = new JDialog(noWindow); @@ -239,6 +247,8 @@ public class MainPanel extends JPanel implements CytoPanelComponent { CyCore.statusWindow = statusWindow; //SWING BLACK MAGIC + + CommandTaskFactory commandTaskFactory = new CommandTaskFactory(YoshikoCommand.PERFORM_ALGORITHM); TaskIterator taskIterator = commandTaskFactory.createTaskIterator(); @@ -247,8 +257,6 @@ public class MainPanel extends JPanel implements CytoPanelComponent { } catch (InterruptedException ex) { ex.printStackTrace(); } - - System.out.println(); } }; @@ -263,6 +271,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { ret.setWeightColumn(ecPanel.getWeightColumn()); ret.setPermanentColumn(ecPanel.getPermanentColumn()); ret.setForbiddenColumn(ecPanel.getForbiddenColumn()); + ret.threshold = ecPanel.getThreshold(); ret.defaultInsertionCost = ecPanel.getDefaultInsertionCost(); ret.defaultDeletionCost = ecPanel.getDefaultDeletionCost(); ret.useHeuristic = opModePanel.useHeuristic(); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java index 9d39b11..920b58d 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java @@ -31,18 +31,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Properties; -import javax.swing.BoxLayout; -import javax.swing.GroupLayout; +import javax.swing.*; import javax.swing.GroupLayout.ParallelGroup; import javax.swing.GroupLayout.SequentialGroup; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; -import javax.swing.LayoutStyle; -import javax.swing.SwingConstants; +import javax.swing.event.ChangeListener; import org.cytoscape.application.swing.CytoPanelComponent; import org.cytoscape.application.swing.CytoPanelName; @@ -275,5 +267,4 @@ NetworkAboutToBeDestroyedListener public void handleEvent(AboutToRemoveEdgesEvent e) { invalidateIfRelevant(e); } - } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java b/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java index 4d3135c..a4a294f 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java @@ -45,11 +45,7 @@ public class CommandTaskFactory implements TaskFactory{ } else if (command == YoshikoCommand.PERFORM_ALGORITHM) { return new TaskIterator( - new AlgorithmTask( - null, - CyCore.mainPanel.fetchParameters(CyCore.cy.getCurrentNetwork()) - ) - ); + new AlgorithmTask(null, CyCore.mainPanel.parameterSet)); } else return null; //TODO: Might be useful to generate an error/ throw an exception here as this should never be invoked } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java index 934d74c..ea0f96d 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java @@ -112,7 +112,6 @@ public class AlgorithmTask extends AbstractTask { //Generate solutionsPanel resultPanel = new ResultPanel(result); - //Show solution panel CyCore.registrar.registerService(resultPanel, CytoPanelComponent.class, new Properties()); //Focus solution panel @@ -130,8 +129,7 @@ public class AlgorithmTask extends AbstractTask { } } ); - eastPanel.getThisComponent().revalidate(); - + //eastPanel.getThisComponent().revalidate(); } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/ClusteringAlgorithm.java b/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/ClusteringAlgorithm.java index 8078e78..8c9e467 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/ClusteringAlgorithm.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/ClusteringAlgorithm.java @@ -437,7 +437,6 @@ public class ClusteringAlgorithm { if (edgeArray[i][j].startingWeight < 0){ clusteringCost -= edgeArray[i][j].startingWeight; System.out.println("Insert edge:("+i+","+ j+") with cost "+edgeArray[i][j].startingWeight); - } edgeArray[i][j].startingWeight = 0; } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/GraphTranslator.java b/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/GraphTranslator.java index 73fd93e..504d747 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/GraphTranslator.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/GraphTranslator.java @@ -1,26 +1,43 @@ package de.hhu.ba.yoshikoWrapper.yoshikoAlgorithm; import de.hhu.ba.yoshikoWrapper.core.CyCore; +import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.NetworkParsingException; import de.hhu.ba.yoshikoWrapper.core.ParameterSet; +import de.hhu.ba.yoshikoWrapper.cytoUtil.GraphAnalyzer; import de.hhu.ba.yoshikoWrapper.cytoUtil.NodeMap; import de.hhu.ba.yoshikoWrapper.cytoUtil.StyleManager; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution; +import de.hhu.ba.yoshikoWrapper.swing.components.MainPanel; import org.cytoscape.model.*; import org.cytoscape.model.subnetwork.CyRootNetwork; import org.cytoscape.model.subnetwork.CySubNetwork; import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.model.CyNetworkView; +import javax.swing.*; +import java.awt.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.*; +import java.util.List; + +import static javax.swing.JOptionPane.*; public final class GraphTranslator { private CyNetwork network; private ParameterSet parameterSet; + private boolean containsOnlyPositiveWeigths; + private double maxWeight; + private double minWeight; + private double deletionCostDefault; private double insertionCostDefault; + private double threshold; CyColumn weightColumn; @@ -34,13 +51,19 @@ public final class GraphTranslator { this.weightColumn = parameterSet.getWeightColumn(); this.deletionCostDefault = parameterSet.defaultDeletionCost; this.insertionCostDefault = parameterSet.defaultInsertionCost; + this.threshold = parameterSet.threshold; this.nodeMap = new HashMap<>(); + this.containsOnlyPositiveWeigths = true; } public YoshikoEdge[][] translateGraph() throws NetworkParsingException { + containsOnlyPositiveWeigths = true; this.makeGraph(); this.makeGraphComplete(); + parameterSet.containsOnlyPositiveEdges = containsOnlyPositiveWeigths; + parameterSet.recomendetTreshold = (minWeight + maxWeight)/2; + return edgeArray; } @@ -67,6 +90,10 @@ public final class GraphTranslator { double weight; weight = extractValue(e); + weight -= threshold; + if (weight < 0){ + containsOnlyPositiveWeigths = false; + } YoshikoEdge yoshikoEdge = new YoshikoEdge(e.getSUID(), weight, u, v); edgeArray[yoshikoEdge.source][yoshikoEdge.target]= yoshikoEdge; @@ -77,7 +104,7 @@ public final class GraphTranslator { for (int i = 1; i < edgeArray.length; i++){ for (int j = 0; j < i; j++){ if (edgeArray[i][j] == null){ - YoshikoEdge yoshikoEdge = new YoshikoEdge(-1, insertionCostDefault, i, j); + YoshikoEdge yoshikoEdge = new YoshikoEdge(-1, insertionCostDefault-threshold, i, j); edgeArray[i][j] = yoshikoEdge; } } @@ -153,4 +180,42 @@ public final class GraphTranslator { } } + public void writeClusters(List<List<Integer>> clusters, int k) { + FileWriter fileWriter = null; + BufferedWriter bufferedWriter = null; + + String s = network.getRow(network).get(CyNetwork.NAME, String.class); + + s = s.substring(0, s.indexOf(".")); + + if (k < 0) { + s = s + "yoshikoClustering"; + } else { + s = s+ "k-Clustering"; + } + + try { + File file = new File("C:\\Users\\User\\Desktop\\relevantClustEval\\optimalThreshold\\"+s); + file.createNewFile(); + fileWriter = new FileWriter(file); + bufferedWriter = new BufferedWriter(fileWriter); + for (int i = 0; i < clusters.size(); i++) { + List<Integer> cluster = clusters.get(i); + for (Integer nodeId : cluster) { + bufferedWriter.write(network.getRow(nodeMap.get(nodeId)).get(CyNetwork.NAME, String.class) + " " + i + "\n"); + } + } + bufferedWriter.close(); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + bufferedWriter.close(); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/YoshikoAlgoritmController.java b/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/YoshikoAlgoritmController.java index e08a1de..58a1833 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/YoshikoAlgoritmController.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/yoshikoAlgorithm/YoshikoAlgoritmController.java @@ -43,6 +43,7 @@ public class YoshikoAlgoritmController { result.addSolution(solution); taskMonitor.setStatusMessage("Processing Clusters"); + translator.writeClusters(clusters, k); translator.transateClusters(clusters, solution); } } \ No newline at end of file -- GitLab