Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 1c67d146 authored by Adrien's avatar Adrien
Browse files

maxDiversity working

parent 63f8ea09
No related branches found
No related tags found
No related merge requests found
package kdiv;
import java.util.Map;
/**
* A container class to store the diversity value and the optimal distribution.
*/
public class DiversityResult<T> {
private final double maxDiversity;
private final Map<T, Double> distribution;
public DiversityResult(double maxDiversity, Map<T, Double> distribution) {
this.maxDiversity = maxDiversity;
this.distribution = distribution;
}
public double getMaxDiversity() {
return maxDiversity;
}
public Map<T, Double> getDistribution() {
return distribution;
}
@Override
public String toString() {
return "Max Diversity: " + maxDiversity + "\nDistribution: " + distribution;
}
}
...@@ -3,6 +3,7 @@ package kdiv; ...@@ -3,6 +3,7 @@ package kdiv;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
class DoubleMapSimilarity<T> implements Similarity<T> { class DoubleMapSimilarity<T> implements Similarity<T> {
private final Map<T, Map<T, Double>> similarityMap = new HashMap<>(); private final Map<T, Map<T, Double>> similarityMap = new HashMap<>();
...@@ -31,4 +32,32 @@ class DoubleMapSimilarity<T> implements Similarity<T> { ...@@ -31,4 +32,32 @@ class DoubleMapSimilarity<T> implements Similarity<T> {
} }
return null; //Return 0.0 if no similarity is found (But for now it return null if cat1.class != cat2.class) return null; //Return 0.0 if no similarity is found (But for now it return null if cat1.class != cat2.class)
} }
// #TODO Not sure on how to do that ###
/*public Double getSimilarity(Integer int1, Integer int2) {
double res = int2-int1;
return res;
}*/
// --- Functions used in the maximum diversity computation ---
/**
* Get the size of similarityMap
* @return
*/
public int getSize() {
return similarityMap.size();
}
/**
* Get the keyset of similarityMap
* @return
*/
public Set<T> getKey() {
return similarityMap.keySet();
}
} }
\ No newline at end of file
...@@ -3,6 +3,10 @@ package kdiv; ...@@ -3,6 +3,10 @@ package kdiv;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* Main used for test now.
*/
public class Main { public class Main {
static final String UNSTRUCT = "unstructdist"; static final String UNSTRUCT = "unstructdist";
...@@ -18,34 +22,47 @@ public class Main { ...@@ -18,34 +22,47 @@ public class Main {
* - Compute the diversity with q = i * - Compute the diversity with q = i
*/ */
Sample samp = new Sample(); Sample samp = new Sample();
Map<String, Map<String, Double>> distrib = samp.createSampleDistribution(); Map<Object, Map<Object, Double>> distrib = samp.createSampleDistribution();
Map<String, DoubleMapSimilarity<String>> similarity = new HashMap<>(); Map<Object, DoubleMapSimilarity<Object>> similarity = new HashMap<>();
similarity.put(UNSTRUCT, samp.createSampleDistance(UNSTRUCT)); similarity.put(UNSTRUCT, samp.createSampleDistance(UNSTRUCT));
similarity.put(LINEAR, samp.createSampleDistance(LINEAR)); similarity.put(LINEAR, samp.createSampleDistance(LINEAR));
similarity.put(GRAPHSEM, samp.createSampleDistance(GRAPHSEM)); similarity.put(GRAPHSEM, samp.createSampleDistance(GRAPHSEM));
similarity.put(NAMESEM, samp.createSampleDistance(NAMESEM)); similarity.put(NAMESEM, samp.createSampleDistance(NAMESEM));
//For this sample data, we expect a : positive & decreasing result
//Iterate over each distance matrix and compute max diversity
for (Map.Entry<Object, DoubleMapSimilarity<Object>> distanceMatrix : similarity.entrySet()) {
Object matrix_key = distanceMatrix.getKey();
DoubleMapSimilarity<Object> distanceMatrix_i = distanceMatrix.getValue();
//Compute max diversity
DiversityResult<Object> maxDivResult = MathUtils.maxDiversity(distanceMatrix_i);
//Extract values
for (Map.Entry<String, DoubleMapSimilarity<String>> distanceMatrix : similarity.entrySet()) { double maxDiversity = maxDivResult.getMaxDiversity();
String matrix_key = distanceMatrix.getKey(); Map<Object, Double> optimalDistribution = maxDivResult.getDistribution();
DoubleMapSimilarity<String> distanceMatrix_i = distanceMatrix.getValue();
System.out.println("--- MATRIX : "+ matrix_key); //Print results
for (Map.Entry<String, Map<String, Double>> entry : distrib.entrySet()) { System.out.println("=== MATRIX: " + matrix_key + " ===");
String distrib_key = entry.getKey(); System.out.println("Max Diversity: " + maxDiversity);
Map<String, Double> distrib_i = entry.getValue(); System.out.println("Optimal Distribution: " + optimalDistribution);
System.out.println("--- KEY : "+ distrib_key); System.out.println("------------------------------------\n");
for (int i = 0 ; i <= 10 ; i++) { for (Map.Entry<Object, Map<Object, Double>> entry : distrib.entrySet()) {
double diversityAti = MathUtils.diversity(distrib_i, distanceMatrix_i, i); Object distrib_key = entry.getKey();
System.out.println("Diversity at "+ i +" is "+ diversityAti); Map<Object, Double> distrib_i = entry.getValue();
System.out.println("--- KEY : "+ distrib_key);
for (int i = 0 ; i <= 10 ; i++) {
double diversityAti = MathUtils.diversity(distrib_i, distanceMatrix_i, i);
System.out.println("Diversity at q = "+ i +" is "+ diversityAti);
}
}
System.out.println();
}
} }
}
System.out.println();
}
}
} }
......
package kdiv; package kdiv;
import java.util.HashMap; import java.util.*;
import java.util.Map; import org.apache.commons.math3.linear.*;
/** /**
* Provide mathematical tools. * Provide mathematical tools.
...@@ -29,7 +29,7 @@ public class MathUtils { ...@@ -29,7 +29,7 @@ public class MathUtils {
* *
* @param <T> * @param <T>
* @param distrib * @param distrib
* @return * @return A normalized map.
*/ */
public static <T> Map<T, Double> relativeAbundance(Map<T, Double> distrib) { public static <T> Map<T, Double> relativeAbundance(Map<T, Double> distrib) {
Map<T, Double> rab = new HashMap<>(); Map<T, Double> rab = new HashMap<>();
...@@ -59,7 +59,7 @@ public class MathUtils { ...@@ -59,7 +59,7 @@ public class MathUtils {
* @param exp * @param exp
* @return * @return
*/ */
public static <T> double summation(Map<T, Double> distrib, DoubleMapSimilarity<String> similarity , double exp) { public static <T> double summation(Map<T, Double> distrib, DoubleMapSimilarity<T> similarity , double exp) {
Map<T, Double> rab = relativeAbundance(distrib); Map<T, Double> rab = relativeAbundance(distrib);
//System.out.println("RAB" + rab.toString()); //System.out.println("RAB" + rab.toString());
double result = 0.0; double result = 0.0;
...@@ -68,10 +68,10 @@ public class MathUtils { ...@@ -68,10 +68,10 @@ public class MathUtils {
for (T cat : distrib.keySet()) { for (T cat : distrib.keySet()) {
if (distrib.get(cat) != 0) { if (distrib.get(cat) != 0) {
double innerResult = 0.0; double innerResult = 0.0;
//Inner summation over each category (ocat) //Inner summation over each category (ocat)
for (T ocat : distrib.keySet()) { for (T ocat : distrib.keySet()) {
if (distrib.get(ocat) != 0) { if (distrib.get(ocat) != 0) { //We assume that sim.get(cat).get(ocat) exists
//We assume that sim.get(cat).get(ocat) exists.
Double similaritya = (distanceToSimilarity(similarity.getSimilarity(cat, ocat))); Double similaritya = (distanceToSimilarity(similarity.getSimilarity(cat, ocat)));
innerResult += rab.get(ocat) * similaritya; innerResult += rab.get(ocat) * similaritya;
} }
...@@ -90,7 +90,7 @@ public class MathUtils { ...@@ -90,7 +90,7 @@ public class MathUtils {
* @param sim * @param sim
* @return * @return
*/ */
public static <T> double prodation(Map<T, Double> distrib, DoubleMapSimilarity<String> similarity) { public static <T> double prodation(Map<T, Double> distrib, DoubleMapSimilarity<T> similarity) {
Map<T, Double> rab = relativeAbundance(distrib); Map<T, Double> rab = relativeAbundance(distrib);
double result = 1.0; double result = 1.0;
...@@ -119,7 +119,7 @@ public class MathUtils { ...@@ -119,7 +119,7 @@ public class MathUtils {
* @param q * @param q
* @return * @return
*/ */
public static <T> double diversity(Map<T, Double> distrib, DoubleMapSimilarity<String> sim, double q) { public static <T> double diversity(Map<T, Double> distrib, DoubleMapSimilarity<T> sim, double q) {
if (q==1) { if (q==1) {
return prodation(distrib, sim); return prodation(distrib, sim);
} else { } else {
...@@ -127,4 +127,125 @@ public class MathUtils { ...@@ -127,4 +127,125 @@ public class MathUtils {
return Math.pow(sum, 1/(1-q)); return Math.pow(sum, 1/(1-q));
} }
} }
/**
* Compute the maximum diversity distribution and return both the diversity and the distribution.
* @param similarityMatrix The similarity matrix.
* @return DiversityResult containing max diversity and optimal distribution.
*/
public static <T> DiversityResult<T> maxDiversity(DoubleMapSimilarity<T> similarityMatrix) {
//Parameters initialization
Set<T> elements = similarityMatrix.getKey();
List<T> elementList = new ArrayList<>(elements);
int n = elementList.size();
double maxDiversity = 0;
List<T> bestSubset = null;
RealVector bestWeights = null;
Map<T, Double> bestDistribution = null;
//Iterate over all non-empty subsets
for (int k = 1; k <= n; k++) {
for (Set<T> subset : generateCombinations(elementList, k)) {
List<T> subsetList = new ArrayList<>(subset);
RealMatrix subMatrix = createSubMatrix(similarityMatrix, subsetList);
try {
RealVector b = new ArrayRealVector(k, 1.0);
DecompositionSolver solver = new LUDecomposition(subMatrix).getSolver();
RealVector weights = solver.solve(b);
if (areNonNegative(weights)) {
double magnitude = weights.getL1Norm();
if (magnitude > maxDiversity) {
maxDiversity = magnitude;
bestSubset = subsetList;
bestWeights = weights;
bestDistribution = computeDistribution(bestSubset, bestWeights, maxDiversity);
}
}
} catch (SingularMatrixException e) {
// Ignore singular matrices
}
}
}
return new DiversityResult<>(maxDiversity, bestDistribution != null ? bestDistribution : new HashMap<>());
}
/*
* ---- Helpers for generating subsets
*/
/**
* Generate all k-sized subsets of a given list.
*/
private static <T> Set<Set<T>> generateCombinations(List<T> elements, int k) {
Set<Set<T>> result = new HashSet<>();
generateCombinationsHelper(elements, k, 0, new HashSet<>(), result);
return result;
}
/**
* Recursive helper method to generate combinations.
*/
private static <T> void generateCombinationsHelper(List<T> elements, int k, int index, Set<T> current, Set<Set<T>> result) {
if (current.size() == k) {
result.add(new HashSet<>(current));
return;
}
for (int i = index; i < elements.size(); i++) {
current.add(elements.get(i));
generateCombinationsHelper(elements, k, i + 1, current, result);
current.remove(elements.get(i));
}
}
/*
* Helpers for matrix manipulation
*/
/**
* Create a sub-matrix for the given subset from the similarity matrix.
*/
private static <T> RealMatrix createSubMatrix(DoubleMapSimilarity<T> similarityMatrix, List<T> subset) {
int size = subset.size();
RealMatrix matrix = new Array2DRowRealMatrix(size, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
double similarity = similarityMatrix.getSimilarity(subset.get(i), subset.get(j));
double distance = similarity != 0 ? distanceToSimilarity(similarity) : 1.0;
matrix.setEntry(i, j, distance);
}
}
return matrix;
}
/**
* Check if all elements in a RealVector are non-negative.
*/
private static boolean areNonNegative(RealVector vector) {
for (int i = 0; i < vector.getDimension(); i++) {
if (vector.getEntry(i) < 0) {
return false;
}
}
return true;
}
/**
* Compute the probability distribution from weights.
*/
private static <T> Map<T, Double> computeDistribution(List<T> subset, RealVector weights, double maxDiversity) {
Map<T, Double> distribution = new HashMap<>();
for (int i = 0; i < subset.size(); i++) {
distribution.put(subset.get(i), weights.getEntry(i) / maxDiversity);
}
return distribution;
}
} }
...@@ -3,20 +3,23 @@ package kdiv; ...@@ -3,20 +3,23 @@ package kdiv;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Sample { /**
* This is a example file of how a similarity between ontolongies can be done
*/
public class Sample {
/** /**
* Create a sample distribution as a HashMap. For now, the sample is equidistributed * Create a sample distribution as a HashMap. For now, the sample is equidistributed
* @return * @return
*/ */
public Map<String, Map<String, Double>> createSampleDistribution() { public Map<Object, Map<Object, Double>> createSampleDistribution() {
Map<String, Map<String, Double>> distrib = new HashMap<>(); Map<Object, Map<Object, Double>> distrib = new HashMap<>();
//There is (for now) only a distribution where all the ontology are equally diverse //There is (for now) only a distribution where all the ontology are equally diverse
//In order to show all distribution used in the python code, we might have to do a map of map so that we can store them //In order to show all distribution used in the python code, we might have to do a map of map so that we can store them
Map<String, Double> dist1 = new HashMap<>(); Map<Object, Double> dist1 = new HashMap<>();
dist1.put("A", 0.0); dist1.put("A", 0.0);
dist1.put("B", 0.0); dist1.put("B", 0.0);
dist1.put("C", 1.0); dist1.put("C", 1.0);
...@@ -24,7 +27,7 @@ public class Sample { ...@@ -24,7 +27,7 @@ public class Sample {
dist1.put("E", 0.0); dist1.put("E", 0.0);
distrib.put("dist1", dist1); distrib.put("dist1", dist1);
Map<String, Double> dist2 = new HashMap<>(); Map<Object, Double> dist2 = new HashMap<>();
dist2.put("A", 0.0); dist2.put("A", 0.0);
dist2.put("B", 0.5); dist2.put("B", 0.5);
dist2.put("C", 0.0); dist2.put("C", 0.0);
...@@ -32,7 +35,7 @@ public class Sample { ...@@ -32,7 +35,7 @@ public class Sample {
dist2.put("E", 0.0); dist2.put("E", 0.0);
distrib.put("dist2", dist2); distrib.put("dist2", dist2);
Map<String, Double> dist3 = new HashMap<>(); Map<Object, Double> dist3 = new HashMap<>();
dist3.put("A", 0.0); dist3.put("A", 0.0);
dist3.put("B", 0.2); dist3.put("B", 0.2);
dist3.put("C", 0.6); dist3.put("C", 0.6);
...@@ -40,7 +43,7 @@ public class Sample { ...@@ -40,7 +43,7 @@ public class Sample {
dist3.put("E", 0.0); dist3.put("E", 0.0);
distrib.put("dist3", dist3); distrib.put("dist3", dist3);
Map<String, Double> dist4 = new HashMap<>(); Map<Object, Double> dist4 = new HashMap<>();
dist4.put("A", 0.1); dist4.put("A", 0.1);
dist4.put("B", 0.1); dist4.put("B", 0.1);
dist4.put("C", 0.6); dist4.put("C", 0.6);
...@@ -48,7 +51,7 @@ public class Sample { ...@@ -48,7 +51,7 @@ public class Sample {
dist4.put("E", 0.1); dist4.put("E", 0.1);
distrib.put("dist4", dist4); distrib.put("dist4", dist4);
Map<String, Double> dist5 = new HashMap<>(); Map<Object, Double> dist5 = new HashMap<>();
dist5.put("A", 0.5); dist5.put("A", 0.5);
dist5.put("B", 0.0); dist5.put("B", 0.0);
dist5.put("C", 0.0); dist5.put("C", 0.0);
...@@ -56,7 +59,7 @@ public class Sample { ...@@ -56,7 +59,7 @@ public class Sample {
dist5.put("E", 0.5); dist5.put("E", 0.5);
distrib.put("dist5", dist5); distrib.put("dist5", dist5);
Map<String, Double> dist6 = new HashMap<>(); Map<Object, Double> dist6 = new HashMap<>();
dist6.put("A", 0.1); dist6.put("A", 0.1);
dist6.put("B", 0.2); dist6.put("B", 0.2);
dist6.put("C", 0.4); dist6.put("C", 0.4);
...@@ -64,7 +67,7 @@ public class Sample { ...@@ -64,7 +67,7 @@ public class Sample {
dist6.put("E", 0.1); dist6.put("E", 0.1);
distrib.put("dist6", dist6); distrib.put("dist6", dist6);
Map<String, Double> dist7 = new HashMap<>(); Map<Object, Double> dist7 = new HashMap<>();
dist7.put("A", 0.2); dist7.put("A", 0.2);
dist7.put("B", 0.2); dist7.put("B", 0.2);
dist7.put("C", 0.2); dist7.put("C", 0.2);
...@@ -82,8 +85,8 @@ public class Sample { ...@@ -82,8 +85,8 @@ public class Sample {
* @return * @return
* @throws Exception * @throws Exception
*/ */
public DoubleMapSimilarity<String> createSampleDistance(String graph) throws Exception { public DoubleMapSimilarity<Object> createSampleDistance(String graph) throws Exception {
DoubleMapSimilarity<String> similarity = new DoubleMapSimilarity<>(); DoubleMapSimilarity<Object> similarity = new DoubleMapSimilarity<>();
if (graph.equals("unstructdist")) { if (graph.equals("unstructdist")) {
/* /*
......
package kdiv; package kdiv;
/** /**
* The Similarity class get the similarity between two categories. * The Similarity interface to get the similarity between two categories.
*/ */
public interface Similarity<T> { public interface Similarity<T> {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment