Skip to content

Commit

Permalink
Cleanup (#2)
Browse files Browse the repository at this point in the history
* final args and logger

* rm comments

* add author javadoc

* rename variables

* rm redundant constructor

* add logger

* bump version
  • Loading branch information
kkoutsilis committed Nov 22, 2022
1 parent 02348db commit 8639302
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 99 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ It requires 6 arguments in this order.
Example:

```bash
$ java −jar SACT−1.0−SNAPSHOT.jar ./exp1.csv ./res.csv 3 1 1 2
$ java −jar SACT−1.1−SNAPSHOT.jar ./exp1.csv ./res.csv 3 1 1 2
```

It will print the created clusters in the console as well as create a csv file with the clusters.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.kkoutsilis</groupId>
<artifactId>SACT</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.1-SNAPSHOT</version>

<name>SACT</name>

Expand Down
31 changes: 19 additions & 12 deletions src/main/java/com/kkoutsilis/App.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.kkoutsilis;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.kkoutsilis.algorithms.ClusteringAlgorithm;
import com.kkoutsilis.algorithms.HCNN;
import com.kkoutsilis.graphs.Graph;
Expand All @@ -8,18 +14,18 @@
import com.kkoutsilis.utilities.CsvHandler;
import com.kkoutsilis.utilities.NearestNeighbour;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author kkoutsilis
*/
public class App {
public static void main(String[] args) throws Exception {
String inputFilePath = args[0];
String outputFilePath = args[1];
int k = Integer.parseInt(args[2]);
int fistNearestNeighbourAlgorithm = Integer.parseInt(args[3]);
int secondNearestNeighbourAlgorithm = Integer.parseInt(args[4]);
int n = Integer.parseInt(args[5]);
final Logger logger = Logger.getLogger(App.class.getName());
final String inputFilePath = args[0];
final String outputFilePath = args[1];
final int k = Integer.parseInt(args[2]);
final int fistNearestNeighbourAlgorithm = Integer.parseInt(args[3]);
final int secondNearestNeighbourAlgorithm = Integer.parseInt(args[4]);
final int n = Integer.parseInt(args[5]);

long startTime = System.nanoTime();

Expand Down Expand Up @@ -70,9 +76,10 @@ public static void main(String[] args) throws Exception {
s.forEach(v -> System.out.print(v.getLabel() + " "));
System.out.println();
}
System.out.println("Clustering execution time in milliseconds: " + elapsedTime / 1000000);
logger.log(Level.INFO,
() -> "Clustering execution time in milliseconds: " + elapsedTime / 1000000);

SilhouetteCoefficient quality = new SilhouetteCoefficient(result, graph);
System.out.printf("Silhouette Coefficient: %.03f", quality.calculate());
logger.log(Level.INFO, () -> String.format("Silhouette Coefficient: %.03f", quality.calculate()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import java.util.List;
import java.util.Set;

/**
* @author kkoutsilis
*/
public interface ClusteringAlgorithm {
List<Set<Vertex>> fit() throws Exception;
}
123 changes: 60 additions & 63 deletions src/main/java/com/kkoutsilis/algorithms/HCNN.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@
import com.kkoutsilis.utilities.Distance;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
* @author kkoutsilis
*/
public class HCNN implements ClusteringAlgorithm {
private Graph graph;
private List<Integer> indexes;
private List<Vertex> G;
private List<Vertex> data;
private int n;
private Map<Vertex, Set<Vertex>> fistNnAlgorithm;
private Map<Vertex, Set<Vertex>> secondNnAlgorithm;
private final Logger logger = Logger.getLogger(HCNN.class.getName());

public HCNN() {
}

public HCNN(Graph graph, int n, Map<Vertex, Set<Vertex>> fistNnAlgorithm, Map<Vertex, Set<Vertex>> secondNnAlgorithm) {
public HCNN(Graph graph, int n, Map<Vertex, Set<Vertex>> fistNnAlgorithm,
Map<Vertex, Set<Vertex>> secondNnAlgorithm) {
this.graph = graph;
this.n = n;
this.fistNnAlgorithm = fistNnAlgorithm;
Expand All @@ -32,76 +35,71 @@ public HCNN(Graph graph, int n, Map<Vertex, Set<Vertex>> fistNnAlgorithm, Map<Ve
for (int i = 0; i < this.graph.getVertices().size(); i++) {
this.indexes.add(i);
}
this.G = new ArrayList<>(this.graph.getVertices().keySet());
this.data = new ArrayList<>(this.graph.getVertices().keySet());
}

@Override
public List<Set<Vertex>> fit() throws Exception {
this.logger.log(Level.INFO, "Fitting...");
ClustersAndOutliers clustersAndOutliers = this.initializeClustering();
List<Set<Vertex>> C = clustersAndOutliers.getClusters();
Set<Vertex> D = clustersAndOutliers.getOutliers();
List<Set<Vertex>> clusters = clustersAndOutliers.getClusters();
Set<Vertex> outliers = clustersAndOutliers.getOutliers();

while (C.size() > this.n) {
int L = C.size();
// line 4
float tmax = 0;
for (int i = 0; i < L; i++) {
for (int j = i + 1; j < L; j++) {
float similarity = sim(C.get(i), C.get(j));
if (tmax < similarity) {
tmax = similarity;
while (clusters.size() > this.n) {
int l = clusters.size();
float tMax = 0;
for (int i = 0; i < l; i++) {
for (int j = i + 1; j < l; j++) {
float similarity = sim(clusters.get(i), clusters.get(j));
if (tMax < similarity) {
tMax = similarity;
}
}
}
// line 5
if (tmax == 0) {
if (tMax == 0) {
break;
}
// line 7
Set<MSP> msp = new LinkedHashSet<>();
for (int i = 0; i < L; i++) {
for (int j = i + 1; j < L; j++) {
float similarity = sim(C.get(i), C.get(j));
if (similarity == tmax) {
for (int i = 0; i < l; i++) {
for (int j = i + 1; j < l; j++) {
float similarity = sim(clusters.get(i), clusters.get(j));
if (similarity == tMax) {
msp.add(new MSP(i, j));
}
}
}
// line 8-10
DisjointSets DS = new DisjointSets();
for (Set<Vertex> vertices : C) {
DS.makeSet(vertices);
DisjointSets disjointSets = new DisjointSets();
for (Set<Vertex> vertices : clusters) {
disjointSets.makeSet(vertices);
}
// line 11-12
for (MSP msp1 : msp) {
int i = msp1.getI();
int j = msp1.getJ();
DS.union(C.get(i), C.get(j));
disjointSets.union(clusters.get(i), clusters.get(j));
}
// line 13-16
for (int i = 0; i < L; i++) {
int index = DS.findSet(C.get(i));
Set<Vertex> repr = DS.getRepresentative(index).getHead().getData();
if (repr != C.get(i)) {
repr.addAll(C.get(i));
C.set(i, Collections.emptySet());
for (int i = 0; i < l; i++) {
int index = disjointSets.findSet(clusters.get(i));
Set<Vertex> repr = disjointSets.getRepresentative(index).getHead().getData();
if (repr != clusters.get(i)) {
repr.addAll(clusters.get(i));
clusters.set(i, Collections.emptySet());
}
}
// line 17-20
List<Set<Vertex>> Ctemp = new ArrayList<>(C);
C = new ArrayList<>();
for (Set<Vertex> c : Ctemp) {
List<Set<Vertex>> tempClusters = new ArrayList<>(clusters);
clusters = new ArrayList<>();
for (Set<Vertex> c : tempClusters) {
if (!c.isEmpty()) {
C.add(c);
clusters.add(c);
}
}
}
C = assignOutliers(C, D);
clusters = assignOutliers(clusters, outliers);

return C;
return clusters;
}

private List<Set<Vertex>> assignOutliers(List<Set<Vertex>> clusters, Set<Vertex> outliers) {
this.logger.log(Level.INFO, "Assigning outliers...");
float[] label = new float[this.indexes.size() + 1];
Set<Vertex> loners = new HashSet<>();
for (int i = 0; i <= this.indexes.size(); i++) {
Expand Down Expand Up @@ -150,7 +148,7 @@ private List<Set<Vertex>> assignOutliers(List<Set<Vertex>> clusters, Set<Vertex>
}

private ClustersAndOutliers initializeClustering() {
// initializing
this.logger.log(Level.INFO, "Initializing clusters...");
int nOfIndexes = this.indexes.size();
CorePair[] corePairs = new CorePair[nOfIndexes];
int[] label = new int[nOfIndexes];
Expand All @@ -162,8 +160,7 @@ private ClustersAndOutliers initializeClustering() {
Set<Vertex> outliers = new LinkedHashSet<>();
float[][] structSimZ = new float[nOfIndexes][nOfIndexes];

// lines 2-7
for (Vertex i : this.G) {
for (Vertex i : this.data) {
Set<Vertex> Q = this.fistNnAlgorithm.get(i);
Set<Vertex> tmp = new HashSet<>(this.fistNnAlgorithm.get(i));
for (Vertex j : tmp) {
Expand All @@ -174,12 +171,11 @@ private ClustersAndOutliers initializeClustering() {
}
}

// line 8
List<PairSim> pairSims = new ArrayList<>();
for (int i = 0; i < nOfIndexes; i++) {
for (int j = i + 1; j < nOfIndexes; j++) {
Vertex vI = this.G.get(i);
Vertex vJ = this.G.get(j);
Vertex vI = this.data.get(i);
Vertex vJ = this.data.get(j);
float structSim = z(vI, vJ);
if (structSim > 0) {
pairSims.add(new PairSim(vI.getLabel(), vJ.getLabel(), structSim));
Expand All @@ -195,14 +191,14 @@ private ClustersAndOutliers initializeClustering() {
int j = pairSim.getJ() - 1;
if (label[i] == 0 && label[j] == 0) {
last += 1;
label[i] = label[j] = last;// Not sure about that, line 14
label[i] = label[j] = last;
corePairs[last] = new CorePair(i, j);
Vertex vI = this.G.get(i);
Vertex vJ = this.G.get(j);
Vertex vI = this.data.get(i);
Vertex vJ = this.data.get(j);
Set<Vertex> union = new LinkedHashSet<>(fistNnAlgorithm.get(vI));
union.addAll(this.fistNnAlgorithm.get(vJ));
for (Vertex u : union) {
int ui = this.G.indexOf(u); // wrong ??
int ui = this.data.indexOf(u);
if (label[ui] == 0) {
label[ui] = last;
}
Expand All @@ -211,14 +207,14 @@ private ClustersAndOutliers initializeClustering() {
int h = corePair.getI();
int k = corePair.getJ();

Vertex vuI = this.G.get(ui);
Vertex vuI = this.data.get(ui);
float max = z(vuI, vI);
float temp = z(vuI, vJ);
if (max < temp) {
max = temp;
}
Vertex vH = this.G.get(h);
Vertex vK = this.G.get(k);
Vertex vH = this.data.get(h);
Vertex vK = this.data.get(k);

float min = z(vuI, vH);
temp = z(vuI, vK);
Expand All @@ -234,21 +230,20 @@ private ClustersAndOutliers initializeClustering() {
}
}

// line 23-28
List<Set<Vertex>> clusters = new ArrayList<>();
for (int i : this.indexes) {
for (int i = 0; i <= this.indexes.size(); i++) {
clusters.add(new HashSet<>());
}
for (int i : this.indexes) {
Vertex vI = this.G.get(i);
Vertex vI = this.data.get(i);
if (label[i] > 0) {
clusters.get(label[i]).add(vI);
}
if (label[i] == 0) {
outliers.add(vI);
}
}
clusters.removeIf(Set::isEmpty); // Not the best but it works for now.
clusters.removeIf(Set::isEmpty); // Not the best but works for now.
return new ClustersAndOutliers(clusters, outliers);

}
Expand Down Expand Up @@ -292,6 +287,8 @@ private int link(Set<Vertex> clusterA, Set<Vertex> clusterB) {
}

private float sim(Set<Vertex> clusterA, Set<Vertex> clusterB) {
return ((float) conn(clusterA, clusterB) / (float) (clusterA.size() * clusterB.size())) * ((float) link(clusterA, clusterB) / (float) clusterA.size()) * ((float) link(clusterB, clusterA) / (float) clusterB.size());
return ((float) conn(clusterA, clusterB) / (float) (clusterA.size() * clusterB.size()))
* ((float) link(clusterA, clusterB) / (float) clusterA.size())
* ((float) link(clusterB, clusterA) / (float) clusterB.size());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.kkoutsilis.algorithms.helpers;


import com.kkoutsilis.graphs.Vertex;

import java.util.List;
import java.util.Set;

/**
* @author kkoutsilis
*/
public class ClustersAndOutliers {
private List<Set<Vertex>> clusters;
private Set<Vertex> outliers;
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/kkoutsilis/algorithms/helpers/CorePair.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.util.Objects;

/**
* @author kkoutsilis
*/
public class CorePair {
private int i;
private int j;
Expand Down Expand Up @@ -38,8 +41,10 @@ public void setPair(int i, int j) {

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CorePair)) return false;
if (this == o)
return true;
if (!(o instanceof CorePair))
return false;
CorePair corePair = (CorePair) o;
return getI() == corePair.getI() && getJ() == corePair.getJ();
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/kkoutsilis/algorithms/helpers/MSP.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.kkoutsilis.algorithms.helpers;

/**
* @author kkoutsilis
*/
public class MSP {
private int i;
private int j;
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/kkoutsilis/algorithms/helpers/PairSim.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.util.Objects;

/**
* @author kkoutsilis
*/
public class PairSim {
private int i;
private int j;
Expand Down Expand Up @@ -48,8 +51,10 @@ public void setPairSim(int i, int j, float similarity) {

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PairSim)) return false;
if (this == o)
return true;
if (!(o instanceof PairSim))
return false;
PairSim pairSim = (PairSim) o;
return getI() == pairSim.getI() && getJ() == pairSim.getJ() && getSimilarity() == pairSim.getSimilarity();
}
Expand Down
Loading

0 comments on commit 8639302

Please sign in to comment.