Commit 8fea1b05 authored by Philipp Spohr's avatar Philipp Spohr
Browse files

Added support for auto config of reduction rules

parent 147092ef
......@@ -22,5 +22,7 @@ public class ParameterSet {
public boolean useHeuristic;
public int solCount;
public boolean disableMultiThreading;
/**Describes whether auto configuration of the reduction rules is to be used. Overrides the bit mask.**/
public boolean suggestReduction;
}
......@@ -2,10 +2,19 @@ package de.hhu.ba.yoshikoWrapper.cytoUtil;
import java.util.List;
import org.cytoscape.model.CyColumn;
import org.cytoscape.model.CyEdge;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyRow;
import org.slf4j.Logger;
import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger;
public class GraphAnalyzer {
private static Logger logger = YoshikoLogger.getInstance().getLogger();
public static boolean isMultiGraph(CyNetwork net) {
//TODO: Better algorithm?
......@@ -47,4 +56,87 @@ public class GraphAnalyzer {
}
return false;
}
/**
* Generates a fitting bitmask by choosing the reduction rules that appear to be the best choice based on current research
* @param containsRealValues
* @param heuristic
* @return
*/
public static String suggestReductionRules(boolean containsRealValues, boolean heuristic) {
//TODO: Maybe also choose SNR Factor?
//TODO: More research, identify good rules
boolean useCRule = false,useCCRule= false,useACRule= false,useHERule= false,usePDRRule= false,useSNRule = false;
String ret = "";
//First of all: We don't choose any rules when in heuristic mode
if (!heuristic) {
//We check if the graph contains real weights
if (!containsRealValues) {
useCRule = true;
useCCRule = true;
useACRule = true;
useHERule = true;
}
usePDRRule = true;
useSNRule = true;
}
ret += (useCRule ? "1" : "0");
ret += (useCCRule ? "1" : "0");
ret += (useACRule ? "1" : "0");
ret += (useHERule ? "1" : "0");
ret += (usePDRRule ? "1" : "0");
ret += (useSNRule ? "1" : "0");
//logger.info("Suggesting the following reduction-rules bitmask: "+ret);
System.out.println("Suggesting the following reduction-rules bitmask: "+ret);
return ret;
}
public static boolean containsRealValues(
CyNetwork net,
CyColumn weightColumn,
CyColumn permanentColumn,
CyColumn forbiddenColumn,
double defaultInsertionCost,
double defaultDeletionCost)
{
//Simple checks: Deletion and Insertion Costs
if (defaultInsertionCost % 1 != 0 || defaultDeletionCost % 1 != 0) {
return true;
}
if (net != null){
//Fetch edges
List<CyEdge> edges = net.getEdgeList();
//Loop over edges
for (CyEdge e : edges) {
//Fetch entry and check if it exists
CyRow edgeEntry = net.getRow(e);
//Check if there is a weight column defined, else skip
if (weightColumn != null){
//Check if the column contains an entry for the respective edge
//It is possible, that there are missing entries
if (edgeEntry.get(weightColumn.getName(), weightColumn.getType()) != null){
if (weightColumn.getType() == Double.class) {
double weight = edgeEntry.get(weightColumn.getName(), Double.class);
if (weight%1!=0) {
return true;
}
}
}
}
}
}
return false;
}
}
......@@ -31,7 +31,7 @@ import de.hhu.ba.yoshikoWrapper.swig.SolutionFlags;
/**Basic data class that represents a CES instance internally. By using this class the C++ resources can be freed upon retrieval.
*
*/
public class YoshikoResult {
public class YoshikoResult{
private CyNetwork originalGraph;
......
/*******************************************************************************
* Copyright (C) 2017 Philipp Spohr
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
......@@ -34,47 +34,47 @@ import de.hhu.ba.yoshikoWrapper.swing.SwingUtil;
@SuppressWarnings("serial") //Will never be serialized
public class EditCostPanel extends JPanel {
//SWING COMPONENTS
private final ColumnMapper columnMapper;
private final DoubleInputField icField;
private final DoubleInputField dcField;
private final JLabel icLabel;
private final JLabel dcLabel;
private final HelpButton helpButton;
//private final HelpButton helpButton;
public EditCostPanel() {
//Initialize components
helpButton = new HelpButton();
//helpButton = new HelpButton();
columnMapper = new ColumnMapper();
icField = new DoubleInputField(Double.NEGATIVE_INFINITY,0);
dcField = new DoubleInputField(0,Double.POSITIVE_INFINITY);
icField.setText("-1.0");
icField.setToolTipText(LocalizationManager.get("icTooltip"));
dcField.setText("1.0");
icLabel = new JLabel(LocalizationManager.get("defaultInsertion"));
dcLabel = new JLabel(LocalizationManager.get("defaultDeletion"));
//Add components
SwingUtil.addAll(this,icLabel,icField);
SwingUtil.addAll(this,dcLabel,dcField);
SwingUtil.addAll(helpButton);
//SwingUtil.addAll(helpButton);
SwingUtil.addAll(this,columnMapper);
//Layout
GroupLayout layout = new GroupLayout(this);
layout.setHorizontalGroup(layout.createParallelGroup()
.addComponent(helpButton,Alignment.TRAILING)
//.addComponent(helpButton,Alignment.TRAILING)
.addComponent(columnMapper)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
......@@ -88,9 +88,9 @@ public class EditCostPanel extends JPanel {
)
)
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(helpButton)
//.addComponent(helpButton)
.addComponent(columnMapper)
.addGroup(layout.createParallelGroup(Alignment.BASELINE)
.addComponent(icLabel)
......@@ -103,20 +103,20 @@ public class EditCostPanel extends JPanel {
.addComponent(dcField)
)
);
this.setLayout(layout);
}
//SETTER / GETTER
public CyColumn getWeightColumn() {
return columnMapper.getEditingCostColumn();
}
public CyColumn getPermanentColumn() {
return columnMapper.getPermanentColumn();
}
public CyColumn getForbiddenColumn() {
return columnMapper.getForbiddenColumn();
}
......@@ -124,7 +124,7 @@ public class EditCostPanel extends JPanel {
public double getDefaultInsertionCost() {
return icField.getValueAsDouble();
}
public double getDefaultDeletionCost() {
return dcField.getValueAsDouble();
}
......@@ -132,5 +132,5 @@ public class EditCostPanel extends JPanel {
public ColumnMapper getColumnMapper() {
return columnMapper;
}
}
......@@ -58,7 +58,9 @@ 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.core.YoshikoLoader;
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.LibraryPanelFactory;
import de.hhu.ba.yoshikoWrapper.swing.SwingUtil;
......@@ -117,7 +119,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent {
@Override
public void actionPerformed(ActionEvent e) {
//CommandExecutorTaskFactory fac;
CommandExecutor.executeCommand("cybrowser", "show",HelpLinks.mainInfo , null);
}
});
......@@ -312,7 +314,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent {
AbstractTask yoshiko = new AlgorithmTask(
popupLevel,
networkToBeProcessed,
fetchParameter()
fetchParameters(networkToBeProcessed)
);
/**
* Don't queue multiple runs at once because that will get messy
......@@ -340,7 +342,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent {
* Fetches all the parameters from the various swing components and packs them into a neat abstract wrapper class
* @return The currently selected parameter wrapped in a ParameterSet
*/
private ParameterSet fetchParameter() {
private ParameterSet fetchParameters(CyNetwork net) {
ParameterSet ret = new ParameterSet();
ret.timeLimit = opModePanel.getTimeLimit();
ret.weightColumn = ecPanel.getWeightColumn();
......@@ -348,11 +350,12 @@ public class MainPanel extends JPanel implements CytoPanelComponent {
ret.forbiddenColumn = ecPanel.getForbiddenColumn();
ret.defaultInsertionCost = ecPanel.getDefaultInsertionCost();
ret.defaultDeletionCost = ecPanel.getDefaultDeletionCost();
ret.useHeuristic = opModePanel.useHeuristic();
ret.reductionRulesBitMask = reductionRulesChooser.getBitMask();
ret.suggestReduction = reductionRulesChooser.useAutoConfig();
ret.snrMultFactor = reductionRulesChooser.getMultFactor();
ret.useTriangleCuts = opModePanel.useTriangleCuts();
ret.usePartitionCuts = opModePanel.usePartitionCuts();
ret.useHeuristic = opModePanel.useHeuristic();
ret.solCount = opModePanel.getSolCount();
ret.disableMultiThreading = opModePanel.isMultiThreadingDisabled();
return ret;
......
/*******************************************************************************
* Copyright (C) 2017 Philipp Spohr
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
......@@ -25,12 +25,16 @@ import static javax.swing.GroupLayout.DEFAULT_SIZE;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.swing.GroupLayout.Alignment;
import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
......@@ -39,40 +43,54 @@ import de.hhu.ba.yoshikoWrapper.swing.SwingUtil;
@SuppressWarnings("serial")
public class ReductionRulesChooser extends JPanel{
private final JCheckBox useAutoConfig;
private final JSeparator separator;
private final JCheckBox useCRule;
private final JCheckBox useCCRule;
private final JCheckBox useACRule;
private final JCheckBox useHERule;
private final JCheckBox usePDRRule;
private final JCheckBox useSNRule;
private final DoubleInputField multFactor;
private final JPanel SNPanel;
public ReductionRulesChooser() {
//Initialize subcomponents
useAutoConfig = new JCheckBox(LocalizationManager.get("autoConfig"));
useAutoConfig.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
enableRuleSelection(e.getStateChange()== ItemEvent.DESELECTED ? true : false);
}
});
separator = new JSeparator(SwingConstants.HORIZONTAL);
//TODO: Localization
useCRule = new JCheckBox("Use Clique Rule");
useCCRule = new JCheckBox("Use Critical-Clique Rule");
useACRule = new JCheckBox("Use Almost-Clique Rule");
useHERule = new JCheckBox("Use Heavy-Edge 3 in 1 Rule");
usePDRRule = new JCheckBox("Use Parameter Dependent Reduction Rule");
useSNRule = new JCheckBox("Use Similar Neighborhood Rule");
multFactor = new DoubleInputField(1, Double.POSITIVE_INFINITY);
multFactor.setText("1.0");
SNPanel = new JPanel();
SNPanel.setLayout(new BoxLayout(SNPanel,BoxLayout.X_AXIS));
SwingUtil.addAll(SNPanel,new JLabel(LocalizationManager.get("multFactor")),multFactor);
useSNRule.setSelected(true);
useCRule.setSelected(true);
useCCRule.setSelected(true);
useACRule.setSelected(true);
useHERule.setSelected(true);
usePDRRule.setSelected(true);
enableRuleSelection(false);
useAutoConfig.setSelected(true);
useSNRule.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
......@@ -84,9 +102,11 @@ public class ReductionRulesChooser extends JPanel{
}
}
});
SwingUtil.addAll(this,
useAutoConfig,
separator,
useCRule,
useCCRule,
useACRule,
......@@ -95,23 +115,27 @@ public class ReductionRulesChooser extends JPanel{
useSNRule,
SNPanel
);
//Layout
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING,true)
.addComponent(useAutoConfig, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(separator, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useCCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useCCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useACRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useHERule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(usePDRRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useSNRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(SNPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(SNPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(useAutoConfig, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(separator, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useCCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(useACRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
......@@ -120,12 +144,23 @@ public class ReductionRulesChooser extends JPanel{
.addComponent(useSNRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(SNPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
);
this.setLayout(layout);
}
protected void enableRuleSelection(boolean enable) {
useCRule.setEnabled(enable);
useCCRule.setEnabled(enable);
useACRule.setEnabled(enable);
useHERule.setEnabled(enable);
usePDRRule.setEnabled(enable);
useSNRule.setEnabled(enable);
multFactor.setEnabled(enable);
}
/** Creates a 6 Bit bitmask representing the currently selected choice of reduction rules.
* @return
*/
......@@ -139,7 +174,11 @@ public class ReductionRulesChooser extends JPanel{
ret += (useSNRule.isSelected() ? "1" : "0");
return ret;
}
public boolean useAutoConfig() {
return useAutoConfig.isSelected();
}
public double getMultFactor() {
if (useSNRule.isSelected()) {
return multFactor.getValueAsDouble();
......
......@@ -51,7 +51,7 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster;
import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution;
import de.hhu.ba.yoshikoWrapper.swing.SwingUtil;
import de.hhu.ba.yoshikoWrapper.tasks.CreateClusterViews;
import de.hhu.ba.yoshikoWrapper.tasks.CreateClusterViewsTask;
import de.hhu.ba.yoshikoWrapper.tasks.CreateMetaGraphTask;
/**
* Swing Component, that represents one solution of a Yoshiko result and displays it
......@@ -149,7 +149,7 @@ public class SolutionTab extends JPanel {
}
CyCore.dialogTaskManager.execute(
new TaskIterator(1,
new CreateClusterViews(
new CreateClusterViewsTask(
selectedClusters
)
)
......
......@@ -3,7 +3,9 @@ package de.hhu.ba.yoshikoWrapper.taskFactories;
import org.cytoscape.work.TaskFactory;
import org.cytoscape.work.TaskIterator;
import de.hhu.ba.yoshikoWrapper.core.ParameterSet;
import de.hhu.ba.yoshikoWrapper.tasks.AlgorithmTask;
import de.hhu.ba.yoshikoWrapper.tasks.CreateClusterViewsTask;
public class CommandTaskFactory implements TaskFactory{
......@@ -21,7 +23,11 @@ public class CommandTaskFactory implements TaskFactory{
public TaskIterator createTaskIterator() {
//We simply switch between the possible commands
if (command == YoshikoCommand.CREATE_CLUSTER_VIEW) {
return null;
return new TaskIterator(
new CreateClusterViewsTask(
null
)
);
}
else if (command == YoshikoCommand.CREATE_META_GRAPH) {
return null;
......@@ -31,7 +37,7 @@ public class CommandTaskFactory implements TaskFactory{
new AlgorithmTask(
null,
null,
null
new ParameterSet()
)
);
}
......
......@@ -32,6 +32,7 @@ import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import org.slf4j.Logger;
......@@ -41,6 +42,7 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
import de.hhu.ba.yoshikoWrapper.core.NetworkParser;
import de.hhu.ba.yoshikoWrapper.core.ParameterSet;
import de.hhu.ba.yoshikoWrapper.core.StatusInformer;
import de.hhu.ba.yoshikoWrapper.cytoUtil.GraphAnalyzer;
import de.hhu.ba.yoshikoWrapper.cytoUtil.NodeMap;
import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster;
import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoResult;
......@@ -54,7 +56,7 @@ import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface;
import de.hhu.ba.yoshikoWrapper.swing.components.ResultPanel;
public class AlgorithmTask extends AbstractTask {
public class AlgorithmTask extends AbstractTask implements ObservableTask {
//Constants
private static final String SOLUTION_COLUMN_PREFIX = "yoshikoSolution_"; //TODO: Make customizable?
......@@ -77,12 +79,15 @@ public class AlgorithmTask extends AbstractTask {
public CyNetwork net;
//Temps, pointing to and need to be freed in C++
private LibraryInput input;
private ClusterEditingSolutions result;
private CoreAlgorithm ca;
private LibraryInput c_input;
private ClusterEditingSolutions c_result;
private CoreAlgorithm c_algorithm;
private ResultPanel resultPanel;
private YoshikoResult result;
/**
* Default constructor, creates a new AlgorithmTask
* @param statusWindow The Window in which the status-bar is to be shown, can be null
......@@ -111,7 +116,7 @@ public class AlgorithmTask extends AbstractTask {
//Get current network
if (net == null) {
logger.warn("CoreAlgorithm called on a net that is NULL!");
throw new Exception("CoreAlgorithm called on a net that is NULL!"