From 598779089e67608ea8c592ef75697eb5c1ba37bf Mon Sep 17 00:00:00 2001
From: Dmytro Pukhkaiev <dmytro.pukhkaiev@tu-dresden.de>
Date: Fri, 7 Dec 2018 16:37:52 +0100
Subject: [PATCH] Linear normalizer with Java

---
 .../clustering/AbstractNormalizer.java        | 14 +++++
 .../solving/clustering/HardwareComponent.java | 26 +++++++-
 .../st/mquat/solving/clustering/KMeans.java   | 62 ++++++++++++++++---
 .../solving/clustering/LinearNormalizer.java  | 25 ++++++++
 .../mquat/solving/clustering/Normalizer.java  |  7 +++
 .../solving/clustering/StudentNormalizer.java | 12 ++++
 6 files changed, 137 insertions(+), 9 deletions(-)
 create mode 100644 jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/AbstractNormalizer.java
 create mode 100644 jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/LinearNormalizer.java
 create mode 100644 jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/Normalizer.java
 create mode 100644 jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/StudentNormalizer.java

diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/AbstractNormalizer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/AbstractNormalizer.java
new file mode 100644
index 0000000..2f91011
--- /dev/null
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/AbstractNormalizer.java
@@ -0,0 +1,14 @@
+package de.tudresden.inf.st.mquat.solving.clustering;
+
+import java.util.Map;
+
+public abstract class AbstractNormalizer implements Normalizer {
+    Map<String, Double> minValue;
+    Map<String, Double> maxValue;
+
+    public AbstractNormalizer(Map<String, Double> minValue,  Map<String, Double> maxValue){
+        this.minValue = minValue;
+        this.maxValue = maxValue;
+    }
+
+}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java
index 5f334aa..aebe9cb 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java
@@ -4,6 +4,9 @@ import de.tudresden.inf.st.mquat.jastadd.model.Resource;
 import weka.core.DenseInstance;
 import weka.core.Instance;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /***
  * An entity unifying WEKA instances and Jastadd resources
  */
@@ -11,10 +14,15 @@ public class HardwareComponent {
 
     private Resource resource;
     private Instance instance;
+    //TODO: do it with Jastadd
+    private Map<String, Double> value;
+    private Map<String, Double> normalizedValue;
 
-    public HardwareComponent(Resource resource, int attributes_number) {
+    HardwareComponent(Resource resource, int attributes_number) {
         this.resource = resource;
         this.instance = new DenseInstance(attributes_number);
+        value = new HashMap<>();
+        normalizedValue = new HashMap<>();
     }
 
     public Resource getResource() {
@@ -32,4 +40,20 @@ public class HardwareComponent {
     public void setInstance(Instance instance) {
         this.instance = instance;
     }
+
+    public Map<String, Double> getValue() {
+        return value;
+    }
+
+    public void setValue(Map<String, Double> value) {
+        this.value = value;
+    }
+
+    public Map<String, Double> getNormalizedValue() {
+        return normalizedValue;
+    }
+
+    public void setNormalizedValue(Map<String, Double> normalizedValue) {
+        this.normalizedValue = normalizedValue;
+    }
 }
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java
index 04ea64d..fd1746c 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java
@@ -6,9 +6,7 @@ import weka.clusterers.*;
 import weka.core.Attribute;
 import weka.core.Instances;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 /***
  * Wrapper for WEKA SimpleKMeans. Clustering based on:
@@ -28,6 +26,10 @@ public class KMeans{
     // list of resources
     private ArrayList<HardwareComponent> hardwareComponentList = new ArrayList<>();
 
+    /***
+     * Prepare clustering algorithm, extract WEKA instances from Jastadd model
+     * @param model Jastadd model
+     */
     public KMeans(Root model) {
         // create attributes for instances
         Attribute cpu = new Attribute("cpu");
@@ -53,16 +55,20 @@ public class KMeans{
                     String typeName = sub.getType().getName().getName();
                     switch (typeName) {
                         case "CPU":
-                            hardwareComponent.getInstance().setValue(cpu, sub.getCurrentValueByPropertyName("frequency"));
+                            hardwareComponent.getValue().put("CPU", sub.getCurrentValueByPropertyName("frequency"));
+                            //hardwareComponent.getInstance().setValue(cpu, sub.getCurrentValueByPropertyName("frequency"));
                             break;
                         case "RAM":
-                            hardwareComponent.getInstance().setValue(ram, sub.getCurrentValueByPropertyName("total"));
+                            hardwareComponent.getValue().put("RAM", sub.getCurrentValueByPropertyName("total"));
+                            //hardwareComponent.getInstance().setValue(ram, sub.getCurrentValueByPropertyName("total"));
                             break;
                         case "DISK":
-                            hardwareComponent.getInstance().setValue(disk, sub.getCurrentValueByPropertyName("total"));
+                            hardwareComponent.getValue().put("DISK", sub.getCurrentValueByPropertyName("total"));
+                            //hardwareComponent.getInstance().setValue(disk, sub.getCurrentValueByPropertyName("total"));
                             break;
                         case "NETWORK":
-                            hardwareComponent.getInstance().setValue(network, sub.getCurrentValueByPropertyName("throughput"));
+                            hardwareComponent.getValue().put("NETWORK", sub.getCurrentValueByPropertyName("throughput"));
+                            //hardwareComponent.getInstance().setValue(network, sub.getCurrentValueByPropertyName("throughput"));
                             break;
                         default:
                             throw new RuntimeException("Unable to transform unknown resource of type" + typeName);
@@ -73,8 +79,48 @@ public class KMeans{
             }
         }
 
-        for (HardwareComponent hwc : hardwareComponentList)
+        Map<String, Double> minValue = new HashMap<>();
+        Map<String, Double> maxValue = new HashMap<>();
+
+        for (HardwareComponent hwc :hardwareComponentList){
+            for (String key : hwc.getValue().keySet()){
+                if (! minValue.containsKey(key))
+                    minValue.put(key, hwc.getValue().get(key));
+                else if (minValue.get(key) > hwc.getValue().get(key))
+                    minValue.put(key, hwc.getValue().get(key));
+
+                if (! maxValue.containsKey(key))
+                    maxValue.put(key, hwc.getValue().get(key));
+                else if (maxValue.get(key) < hwc.getValue().get(key))
+                    maxValue.put(key, hwc.getValue().get(key));
+            }
+        }
+        LinearNormalizer linearNormalizer = new LinearNormalizer(minValue, maxValue);
+
+        for (HardwareComponent hwc : hardwareComponentList) {
+            hwc.setNormalizedValue(linearNormalizer.normalize(hwc));
+            for (String key : hwc.getNormalizedValue().keySet()){
+                switch (key){
+                    case "CPU":
+                        hwc.getInstance().setValue(cpu, hwc.getNormalizedValue().get(key));
+
+                        break;
+                    case "RAM":
+                        hwc.getInstance().setValue(ram, hwc.getNormalizedValue().get(key));
+                        break;
+                    case "DISK":
+                        hwc.getInstance().setValue(disk, hwc.getNormalizedValue().get(key));
+                        break;
+                    case "NETWORK":
+                        hwc.getInstance().setValue(network, hwc.getNormalizedValue().get(key));
+
+                        break;
+                    default:
+                        throw new RuntimeException("Unable to transform unknown resource of type" + key);
+                }
+            }
             resources.add(hwc.getInstance());
+        }
 
         k = (int) (0.2 * model.getHardwareModel().getResourceList().asJavaCollection().size());
 
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/LinearNormalizer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/LinearNormalizer.java
new file mode 100644
index 0000000..345a8e9
--- /dev/null
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/LinearNormalizer.java
@@ -0,0 +1,25 @@
+package de.tudresden.inf.st.mquat.solving.clustering;
+
+import de.tudresden.inf.st.mquat.jastadd.model.Resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class LinearNormalizer extends AbstractNormalizer implements Normalizer  {
+
+    public LinearNormalizer(Map<String, Double> minValue,  Map<String, Double> maxValue)
+    {
+        super(minValue, maxValue);
+    }
+
+    @Override
+    public Map<String, Double> normalize(HardwareComponent hardwareComponent) {
+        Map<String, Double> normalizedHWC = new HashMap<>();
+        for (String key : hardwareComponent.getValue().keySet()){
+            double normalized =
+                    (hardwareComponent.getValue().get(key) - minValue.get(key))/(maxValue.get(key) - minValue.get(key));
+            normalizedHWC.put(key, normalized);
+        }
+        return normalizedHWC;
+    }
+}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/Normalizer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/Normalizer.java
new file mode 100644
index 0000000..5754695
--- /dev/null
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/Normalizer.java
@@ -0,0 +1,7 @@
+package de.tudresden.inf.st.mquat.solving.clustering;
+
+import java.util.Map;
+
+public interface Normalizer {
+    Map<String, Double> normalize(HardwareComponent resource);
+}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/StudentNormalizer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/StudentNormalizer.java
new file mode 100644
index 0000000..2ec9b3d
--- /dev/null
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/StudentNormalizer.java
@@ -0,0 +1,12 @@
+package de.tudresden.inf.st.mquat.solving.clustering;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class StudentNormalizer implements Normalizer {
+
+    @Override
+    public Map<String, Double> normalize(HardwareComponent hardwareComponent) {
+        return new HashMap<>();
+    }
+}
-- 
GitLab