Skip to content

Commit

Permalink
Closes #2 Updated to MQ
Browse files Browse the repository at this point in the history
  • Loading branch information
StephanPirnbaum committed Jul 27, 2017
1 parent 3232fb3 commit e02df09
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.buchmais.sarf.benchmark;

import com.buchmais.sarf.SARFRunner;
import com.buchmais.sarf.repository.MetricRepository;

import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
* @author Stephan Pirnbaum
*/
public class ModularizationQualityCalculator {

public static Double computeSimilarityBasedMQ(Map<Long, Set<Long>> decomposition) {
Double intraConnectivity = 0d;
Double interConnectivity = 0d;
MetricRepository metricRepository = SARFRunner.xoManager.getRepository(MetricRepository.class);
for (Map.Entry<Long, Set<Long>> component1 : decomposition.entrySet()) {
long[] ids1 = component1.getValue().stream().mapToLong(l -> l).toArray();
int denominator = ids1.length == 1 ? 1 : ((ids1.length * (ids1.length - 1)) / 2);
intraConnectivity += metricRepository.computeSimilarityCohesionInComponent(ids1) / denominator;
for (Map.Entry<Long, Set<Long>> component2 : decomposition.entrySet()) {
if (!Objects.equals(component1.getKey(), component2.getKey())) {
long[] ids2 = component2.getValue().stream().mapToLong(l -> l).toArray();
denominator = ((ids1.length + ids2.length) * (ids1.length + ids2.length - 1)) / 2;
interConnectivity += metricRepository.computeSimilarityCouplingBetweenComponents(ids1, ids2) / denominator;
}
}
}
intraConnectivity /= decomposition.size();
interConnectivity /= (decomposition.size() * (decomposition.size() - 1)) / 2;
return intraConnectivity - interConnectivity;
}

public static Double computeCouplingBasedMQ(Map<Long, Set<Long>> decomposition) {
Double intraConnectivity = 0d;
Double interConnectivity = 0d;
MetricRepository metricRepository = SARFRunner.xoManager.getRepository(MetricRepository.class);
for (Map.Entry<Long, Set<Long>> component1 : decomposition.entrySet()) {
long[] ids1 = component1.getValue().stream().mapToLong(l -> l).toArray();
int denominator = ids1.length == 1 ? 1 : ((ids1.length * (ids1.length - 1)) / 2);
intraConnectivity += metricRepository.computeCouplingCohesionInComponent(ids1) / denominator;
for (Map.Entry<Long, Set<Long>> component2 : decomposition.entrySet()) {
if (!Objects.equals(component1.getKey(), component2.getKey())) {
long[] ids2 = component2.getValue().stream().mapToLong(l -> l).toArray();
denominator = ((ids1.length + ids2.length) * (ids1.length + ids2.length - 1)) / 2;
interConnectivity += metricRepository.computeCouplingBetweenComponents(ids1, ids2) / denominator;
}
}
}
intraConnectivity /= decomposition.size();
interConnectivity /= (decomposition.size() * (decomposition.size() - 1));
return intraConnectivity - interConnectivity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.buchmais.sarf.SARFRunner;
import com.buchmais.sarf.benchmark.MoJoCalculator;
import com.buchmais.sarf.benchmark.ModularizationQualityCalculator;
import com.buchmais.sarf.repository.MetricRepository;
import com.google.common.collect.Sets;
import org.jenetics.LongChromosome;
Expand Down Expand Up @@ -34,6 +35,8 @@ public abstract class LongObjectiveChromosome extends LongChromosome {

private Double componentRangeObjective = 0d;

private Double mQ = 0d;

protected LongObjectiveChromosome(ISeq<LongGene> genes) {
super(genes);
}
Expand Down Expand Up @@ -73,7 +76,7 @@ private void evaluate() {
}
}
}
this.couplingObjective /= (identifiedComponents.size() * (identifiedComponents.size() - 1)) / 2; // TODO: 22.07.2017 Improve
this.couplingObjective /= (identifiedComponents.size() * (identifiedComponents.size() - 1)) / 2; // TODO: 27.07.2017 Similarity undirected, coupling directed
this.cohesionObjective /= identifiedComponents.size();
//SARFRunner.xoManager.currentTransaction().commit();
// minimize the difference between min and max component size
Expand All @@ -86,6 +89,7 @@ private void evaluate() {
identifiedComponents.size() <= 0.25 * Partitioner.ids.length ?
(identifiedComponents.size() / (Partitioner.ids.length / 4d)) :
(Partitioner.ids.length - identifiedComponents.size()) / (0.75 * Partitioner.ids.length);
this.mQ = computeMQ(identifiedComponents);
if (MoJoCalculator.reference != null) {
writeBenchmarkLine(identifiedComponents);
}
Expand All @@ -97,6 +101,8 @@ private void evaluate() {

abstract Double computeCoupling(MetricRepository mR, long[] ids1, long[] ids2);

abstract Double computeMQ(Map<Long, Set<Long>> decomposition);

protected Double getCohesionObjective() {
if (!this.evaluated) evaluate();
return this.cohesionObjective;
Expand All @@ -122,6 +128,11 @@ protected Double getComponentCountObjective() {
return this.componentCountObjective;
}

protected Double getMQ() {
if (!this.evaluated) evaluate();
return this.mQ;
}

/**
*
* @param chromosome
Expand Down Expand Up @@ -168,6 +179,8 @@ private void writeBenchmarkLine(Map<Long, Set<Long>> identifiedComponents) {
Long mojoPlus = Math.min(mojoPlusCompRef, mojoPlusRefComp);
Double fitness = this.cohesionObjective + this.couplingObjective + this.componentCountObjective +
this.componentRangeObjective + this.componentSizeObjective;
Double mQSim = ModularizationQualityCalculator.computeSimilarityBasedMQ(identifiedComponents);
Double mQCoup = ModularizationQualityCalculator.computeCouplingBasedMQ(identifiedComponents);
try(FileWriter fw = new FileWriter("benchmark.csv", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)) {
Expand All @@ -181,6 +194,8 @@ private void writeBenchmarkLine(Map<Long, Set<Long>> identifiedComponents) {
out.print(mojo + ", ");
out.print(mojoFm + ", ");
out.print(mojoPlus + ", ");
out.print(mQSim + ", ");
out.print(mQCoup + ", ");
out.println(fitness);
} catch (IOException e) {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.buchmais.sarf.classification.criterion.cohesion;

import com.buchmais.sarf.benchmark.ModularizationQualityCalculator;
import com.buchmais.sarf.repository.MetricRepository;
import org.jenetics.LongGene;
import org.jenetics.util.ISeq;
import org.jenetics.util.LongRange;

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

/**
* @author Stephan Pirnbaum
*/
Expand All @@ -24,12 +28,18 @@ public LongObjectiveCouplingChromosome(Long min, Long max) {

@Override
Double computeCohesion(MetricRepository mR, long[] ids) {
return mR.computeCouplingCohesionInComponent(ids) / ids.length;
int denominator = ids.length == 1 ? 1 : ((ids.length * (ids.length - 1)) / 2);
return mR.computeCouplingCohesionInComponent(ids) / denominator;
}

@Override
Double computeCoupling(MetricRepository mR, long[] ids1, long[] ids2) {
return mR.computeCouplingBetweenComponents(ids1, ids2);
return mR.computeCouplingBetweenComponents(ids1, ids2) / ((ids1.length + ids2.length) * (ids1.length + ids2.length - 1) / 2);
}

@Override
Double computeMQ(Map<Long, Set<Long>> decomposition) {
return ModularizationQualityCalculator.computeCouplingBasedMQ(decomposition);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.buchmais.sarf.classification.criterion.cohesion;

import com.buchmais.sarf.benchmark.ModularizationQualityCalculator;
import com.buchmais.sarf.repository.MetricRepository;
import org.jenetics.LongGene;
import org.jenetics.util.ISeq;
import org.jenetics.util.LongRange;

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

/**
* @author Stephan Pirnbaum
*/
Expand All @@ -30,7 +34,12 @@ Double computeCohesion(MetricRepository mR, long[] ids) {

@Override
Double computeCoupling(MetricRepository mR, long[] ids1, long[] ids2) {
return mR.computeSimilarityCouplingBetweenComponents(ids1, ids2);
return mR.computeSimilarityCouplingBetweenComponents(ids1, ids2) / ((ids1.length + ids2.length) * (ids1.length + ids2.length - 1) / 2);
}

@Override
Double computeMQ(Map<Long, Set<Long>> decomposition) {
return ModularizationQualityCalculator.computeSimilarityBasedMQ(decomposition);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ public static Map<Long, Set<Long>> partition(long[] ids, Map<Long, Set<Long>> in
Genotype<LongGene> genotype = createGenotype(initialPartitioning, similarityBased);
final Engine<LongGene, Double> engine = Engine
.builder(Partitioner::computeFitnessValue, genotype)
.offspringFraction(0.7)
.offspringFraction(0.5)
.survivorsSelector(new ParetoFrontierSelector())
.offspringSelector(new ParetoFrontierSelector())
.populationSize(100)
.alterers(
new MultiPointCrossover<>(1),
similarityBased ?
new SimilarityMutator(0.004 * Math.log10(ids.length) / Math.log10(2)) :
new CouplingMutator(0.004 * Math.log10(ids.length) / Math.log10(2)),
new SimilarityMutator(0.008 * Math.log10(ids.length) / Math.log10(2)) :
new CouplingMutator(0.008 * Math.log10(ids.length) / Math.log10(2)),
new GaussianMutator<>(0.004 * Math.log10(ids.length) / Math.log10(2)))
.executor(Runnable::run)
.build();
Expand Down Expand Up @@ -94,7 +94,7 @@ private static Genotype<LongGene> createGenotype(Map<Long, Set<Long>> initialPar

static Double computeFitnessValue(final Genotype<LongGene> prospect) {
LongObjectiveChromosome chromosome = (LongObjectiveChromosome) prospect.getChromosome();
return chromosome.getCohesionObjective() + chromosome.getCouplingObjective() + chromosome.getComponentCountObjective() + chromosome.getComponentRangeObjective() + chromosome.getComponentSizeObjective();
return chromosome.getMQ();
}

private static void update(final EvolutionResult<LongGene, Double> result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ Long countInvokesStatic(@Parameter("t1") Long t1,
"WHERE" +
" ID(e1) IN {ids1} AND ID(e2) IN {ids2} " +
"RETURN" +
" toFloat(SUM(c.coupling) / COUNT(c))")
" toFloat(SUM(c.coupling))")
Double computeCouplingBetweenComponents(@Parameter("ids1") long[] ids1, @Parameter("ids2") long[] ids2);

@ResultOf
Expand Down Expand Up @@ -339,7 +339,7 @@ Long countInvokesStatic(@Parameter("t1") Long t1,
"WHERE" +
" ID(e1) IN {ids1} AND ID(e2) IN {ids2} " +
"RETURN" +
" toFloat(SUM(s.similarity)/(COUNT(s) + 0.00000001))")
" toFloat(SUM(s.similarity))")
Double computeSimilarityCouplingBetweenComponents(@Parameter("ids1") long[] ids1, @Parameter("ids2") long[] ids2);

@ResultOf
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/benchmark3.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<Configuration iteration="1">
<Configuration iteration="1"
decomposition="flat" optimization="similarity">
<Component shape="Component" name="1">
<Rules>
<Name rule="IndexController" weight="100"/>
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/configuration_3.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<Configuration iteration="1">
<Configuration iteration="1"
decomposition="deep">
<Component shape="Layer" name="DataLayer">
<Rules>
<!--Dependency rule="javax\.persistence.*" weight="50"/>
Expand Down

0 comments on commit e02df09

Please sign in to comment.