public code v1

This commit is contained in:
2026-05-22 11:14:29 +02:00
parent 427197ec5a
commit b8141736eb
28859 changed files with 575079 additions and 0 deletions
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>afryca.consensusmodel.rodriguez2018MinimumCostClustering</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
formatter_settings_version=12
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
@@ -0,0 +1,8 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name.0
Bundle-SymbolicName: afryca.consensusmodel.rodriguez2018MinimumCostClustering;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: afryca.consensusmodel
Automatic-Module-Name: afryca.consensusmodel.Rodriguez2017MinimumCostClustering
@@ -0,0 +1,15 @@
#Properties file for afryca.consensusmodel.rodriguez2017
afryca.consensusModel.rodriguez2017MinimumCostClustering.information=Paper: R. Rodríguez. A clustering based consensus reaching process for large scale group decision making using hesitant fuzzy sets. Not published yet.\\n\\nR.Rodríguez.\\n\\nConsensus model to deal with large scale group decision making which uses a clustering process, based on FuzzyCMeans method, to weight experts's sub-groups taking into account its size and cohesion. The expert's sub-groups are modeled using hesitant fuzzy sets to avoid losing of information. Furthermore, an adaptive feedback process is defined in which generates advises depending on the consensus level achieved to reduce the time cost of the consensus reaching process .
afryca.consensusModel.rodriguez2017MinimumCostClustering.mainFeatures = Fuzzy preference relations\\nClustering\\nFeedback process
afryca.consensusModel.rodriguez2017MinimumCostClustering.name=R. Rodriguez et al. (2017) Minimum Cost Clustering
afryca.consensusModel.rodriguez2017MinimumCostClustering.observations = No observations
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.theta.description=Consensus threshold
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.delta.description=Level of consensus for the advice generation
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.beta.description=Modify the cohesion
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.pointA.description=Point A Membership Function
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.pointB.description=Point B Membership Function
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.h_max.description = Maximum number of discussion rounds allowed
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.distance_measure_minkowski.description = Minkowski distance measure
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.cost.description = Experts Costs
Bundle-Name = Rodriguez2017MinimumCostClustering
Bundle-Name.0 = Rodriguez2017MinimumCostClustering
@@ -0,0 +1,14 @@
#Properties file for afryca.consensusmodel.rodriguez2017
afryca.consensusModel.rodriguez2017MinimumCostClustering.information=Paper: R. Rodríguez. Modelo de consenso basado en agrupación de expertos a gran escala para problemas de toma de decisión en grupo usando conjuntos difusos. No publicado aún.\\n\\nR. Rodríguez.\\n\\nModelo de consenso para tratar con problemas de toma de decisión en grupo a gran escala que emplea un proceso de agrupación, basado en el método FuzzyCMean, para ponderar los subgrupos de expertos teniendo en cuenta su tamaño y cohesion. Los subgrupos de los expertos se modelan usando conjuntos difusos. Además se incluye un proceso de generación de recomendaciones adaptativo en el que se generan las recomendaciones dependiendo del nivel de consenso alcanzado, reduciendo así el tiempo de coste del proceso de alcance de consenso.
afryca.consensusModel.rodriguez2017MinimumCostClustering.mainFeatures = Relaciones de preferencias difusas\\nAgrupación\\nGeneración de recomendaciones
afryca.consensusModel.rodriguez2017MinimumCostClustering.name=R. Rodriguez et al. (2017) Mínimo Coste Clustering
afryca.consensusModel.rodriguez2017MinimumCostClustering.observations = Sin observaciones
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.theta.description=Umbral de consenso
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.delta.description=Nivel de consenso para la generación de recomendaciones
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.beta.description=Modifica la cohesion
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.pointA.description=Point A Funcion de pertenencia
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.pointB.description=Point B Funcion de pertenencia
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.h_max.description = Máximo número de rondas de discusión permitidas
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.distance_measure_minkowski.description = Medida de distancia de Minkowski
afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.cost.description = Costes de los expertos
Bundle-Name = Rodriguez2017MinimumCostClustering
@@ -0,0 +1,7 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
OSGI-INF/,\
OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="afryca.consensusmodel">
<ConsensusModel
ConsensusModel="afryca.consensusmodel.Rodriguez2017MinimumCostClustering"
Information="%afryca.consensusModel.rodriguez2017MinimumCostClustering.information"
MainFeatures="%afryca.consensusModel.rodriguez2017MinimumCostClustering.mainFeatures"
Multicriteria="false"
Name="%afryca.consensusModel.rodriguez2017MinimumCostClustering.name"
Observations="%afryca.consensusModel.rodriguez2017MinimumCostClustering.observations"
Structure="afryca.fpr"
WithFeedback="true"
id="Rodriguez2017MinimumCostClustering">
<Variable
default_value="0.85"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.theta.description"
id="theta"
is_array="false"
is_internal="false"
type="Float">
<Restriction
type="lower_limit"
value="0.1">
</Restriction>
<Restriction
type="upper_limit"
value="1">
</Restriction>
</Variable>
<Variable
default_value="0.6"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.delta.description"
id="delta"
is_array="false"
is_internal="false"
type="Float">
<Restriction
type="lower_limit"
value="0.1">
</Restriction>
<Restriction
type="upper_limit"
value="1">
</Restriction>
</Variable>
<Variable
default_value="5"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.h_max.description"
id="max_rounds"
is_array="false"
is_internal="false"
type="Integer">
<Restriction
type="lower_limit"
value="1">
</Restriction>
</Variable>
<Variable
default_value="2"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.distance_measure_minkowski.description"
id="lamda"
is_array="false"
is_internal="false"
type="Integer">
<Restriction
type="lower_limit"
value="1">
</Restriction>
</Variable>
<Variable
default_value="1.8"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.beta.description"
id="beta"
is_array="false"
is_internal="false"
type="Float">
</Variable>
<Variable
default_value="Math.round((experts/alternatives)/3)"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.pointA.description"
id="pointA"
is_array="false"
is_internal="false"
type="Operation">
<Restriction
type="lower_limit"
value="0">
</Restriction>
<Restriction
type="upper_limit"
value="99">
</Restriction>
<Relation
type="lower_than"
variable="pointB">
</Relation>
</Variable>
<Variable
default_value="Math.round(experts/alternatives)"
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.pointB.description"
id="pointB"
is_array="false"
is_internal="false"
type="Operation">
<Relation
type="greater_than"
variable="pointA">
</Relation>
<Restriction
type="lower_limit"
value="2">
</Restriction>
<Restriction
type="upper_limit"
value="100">
</Restriction>
</Variable>
<Variable
description="%afryca.consensusmodel.rodriguez2017MinimumCostClustering.variable.cost.description"
id="cost"
is_array="true"
is_internal="false"
type="Integer">
<Array_relation
type="number_of_elements_equals_to"
variable="experts">
</Array_relation>
</Variable>
</ConsensusModel>
</extension>
</plugin>
@@ -0,0 +1,89 @@
package afryca.consensusmodel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import afryca.cm.CM;
import afryca.consensusmodel.cluster.ClusterFPR;
import afryca.fpr.FPR;
public class GenerateRecommendations {
public static List<Recommendation> recommendationsForGroup(List<ClusterFPR> cluster, FPR collectiveMinimumCost,ArrayList<Double> proximityValues, Float [] consensusAlternatives,
ArrayList<CM> proximityMatrix,double proximityAverage,CM proximityMatrixAverage, Float consensusThreshold){
int numberOfAlternatives=consensusAlternatives.length;
List<Recommendation> recommendations = new LinkedList<Recommendation>();
for (int cl = 0; cl < cluster.size(); cl++) {
if(!cluster.get(cl).getExperts().isEmpty()){
if(Math.round(proximityValues.get(cl)*10000d)/10000d <= Math.round(proximityAverage*10000d)/10000d){
for (int alt = 0; alt < numberOfAlternatives; alt++) {
if(Math.round(consensusAlternatives[alt]*10000d)/10000d <= Math.round(consensusThreshold*10000d)/10000d){
for (int j = 0; j < numberOfAlternatives; j++) {
if( alt!=j && alt<j){
if(Math.round((float)proximityMatrix.get(cl).getValue(alt, j)*10000d)/10000d <= Math.round((float)proximityMatrixAverage.getValue(alt, j)*10000d)/10000d){
for(int key:cluster.get(cl).getPreferences().keySet()){ //Each expert in a cluster
EChangeType direction = computeDirection((float)cluster.get(cl).getPreferences().get(key).getValue(alt,j), (float)collectiveMinimumCost.getValue(alt,j));
Recommendation recommendation = new Recommendation(cluster.get(cl).getId(),alt,j,key,direction);
recommendations.add(recommendation);
}
}
}
}
}
}
}
}
}
return recommendations;
}
public static List<Recommendation> recommendationsIndividual(List<ClusterFPR> cluster, FPR collective,ArrayList<Double> proximityValues, Float [] consensusAlternatives,
ArrayList<CM> proximityMatrix,double proximityAverage,CM proximityMatrixAverage, Float consensusThreshold, Integer lamda){
int numberOfAlternatives=consensusAlternatives.length;
List<Recommendation> recommendations = new LinkedList<Recommendation>();
for (int cl = 0; cl < cluster.size(); cl++) {
if(!cluster.get(cl).getExperts().isEmpty()){
if(Math.round(proximityValues.get(cl)*10000d)/10000d <= Math.round(proximityAverage*10000d)/10000d){
for (int alt = 0; alt < numberOfAlternatives; alt++) {
if(Math.round(consensusAlternatives[alt]*10000d)/10000d <= Math.round(consensusThreshold*10000d)/10000d){
for (int j = 0; j < numberOfAlternatives; j++) {
if( alt!=j && alt<j){
if(Math.round((float)proximityMatrix.get(cl).getValue(alt, j)*10000d)/10000d <= Math.round((float)proximityMatrixAverage.getValue(alt, j)*10000d)/10000d && alt!=j){
for(int key:cluster.get(cl).getPreferences().keySet()){ //Each expert in a cluster
if(1f-ConsensusEngine.distanceMinkowskiValues((float)collective.getValue(alt,j), (float)cluster.get(cl).getPreferences().get(key).getValue(alt,j), lamda)
<= (float)proximityMatrixAverage.getValue(alt, j)){
EChangeType direction = computeDirection(1f,2f);
Recommendation recommendation = new Recommendation(cluster.get(cl).getId(),alt,j,key,direction);
recommendations.add(recommendation);
}
}
}
}
}
}
}
}
}
}
return recommendations;
}
public static EChangeType computeDirection(float value1, float value2){
EChangeType direction = EChangeType.NotChange;
if(value1 < value2){
direction = EChangeType.Increase;
}else{
if (value1 > value2){
direction = EChangeType.Decrease;
}
}
return direction;
}
}
@@ -0,0 +1,93 @@
package afryca.consensusmodel;
/**
*
* @author Rosa M. Rodriguez
*/
public class Recommendation {
private int idCluster;
private int idAlternative1;
private int idAlternative2;
private int idExpert;
private EChangeType direction;
Recommendation(){
idCluster = -1;
idAlternative1 = -1;
idAlternative2 = -1;
idExpert = -1;
direction = EChangeType.NotChange;
}
Recommendation(int idCluster, int idAlternative1, int idAlternative2, int idExpert, EChangeType direction){
this();
setIdCluster(idCluster);
setIdAlternative1(idAlternative1);
setIdAlternative2(idAlternative2);
setIdExpert(idExpert);
setDirection(direction);
}
Recommendation(int idCluster, int idAlternative1, int idAlternative2, EChangeType direction){
this();
setIdCluster(idCluster);
setIdAlternative1(idAlternative1);
setIdAlternative2(idAlternative2);
setIdExpert(-1);
setDirection(direction);
}
public int getIdCluster() {
return idCluster;
}
private void setIdCluster(int idCluster) {
this.idCluster = idCluster;
}
public int getIdAlternative1() {
return idAlternative1;
}
private void setIdAlternative1(int idAlternative1) {
this.idAlternative1 = idAlternative1;
}
public int getIdAlternative2() {
return idAlternative2;
}
private void setIdAlternative2(int idAlternative2) {
this.idAlternative2 = idAlternative2;
}
public int getIdExpert() {
return idExpert;
}
private void setIdExpert(int idExpert) {
this.idExpert = idExpert;
}
public EChangeType getDirection() {
return direction;
}
private void setDirection(EChangeType direction) {
this.direction = direction;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append("\nId cluster: " + idCluster);
result.append("\nExpert: "+ idExpert);
result.append("\n(A1,A2): " + "("+idAlternative1+","+idAlternative2+")");
result.append("\nDirection: " + direction);
result.append("\n");
return result.toString();
}
}
@@ -0,0 +1,630 @@
package afryca.consensusmodel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import afryca.ase.RunnableScript;
import afryca.cm.CM;
import afryca.consensusmodel.cluster.ClusterFPR;
import afryca.consensusmodel.clustering.FuzzyCMeansFPR;
import afryca.consensusmodel.definition.EResultElements;
import afryca.consensusmodel.definition.ERoundResult;
import afryca.domain.fuzzyset.function.types.TrapezoidalFunction;
import afryca.fpr.FPR;
import afryca.pr.PR;
import afryca.consensumodel.addon.E4DIAddon;
import afryca.structure.pair.Pair;
public class Rodriguez2017MinimumCostClustering extends ConsensusModel{
private static final String CONSENSUS_MODEL_NAME = "Rodriguez Minimum Cost Clustering (2017)"; //$NON-NLS-1$
private static final String CONSENSUS_THRESHOLD = "theta"; //$NON-NLS-1$----------------------------------------0.85
private static final String SECOND_FEEDBACK_LEVEL = "delta"; //$NON-NLS-1$--------------------------------------0.7
private static final String MAX_ROUNDS = "max_rounds"; //$NON-NLS-1$--------------------------------------------30
private static final String DISTANCE_MEASURE_MINKOWSKI = "lamda"; //$NON-NLS-1$----------------------------------2
private static final String BETA = "beta"; //$NON-NLS-1$ --------------------------------------------------------1.8
private static final String POINT_A = "pointA"; //$NON-NLS-1$----------------------------------------------------10
private static final String POINT_B = "pointB"; //$NON-NLS-1$----------------------------------------------------20
private static final String COST = "cost"; //$NON-NLS-1$ //
private double consensusDegree;
private Float consensusThreshold;
private Float feedbackLevel;
private Integer maxRounds;
private Integer lamda;
private Float pointA;
private Float pointB;
private Float beta;
Integer [] cost;
private int currentRound;
private FPR[] preferencesWithoutGroup;
private int[] advises;
private CM consensusMatrix;
private ArrayList<Double> weigthsGroup;
private List<ClusterFPR> postClusters = new LinkedList<ClusterFPR>();
private List<ClusterFPR> clustersAfterChanges = new LinkedList<ClusterFPR>();
private Float[] consensusAlternatives;
private boolean groupal;
private ArrayList<FPR> preferencesResult;
private FPR collectiveMinimumCost;
Float [] weightsExperts;
@Override
protected void setModelConfiguration() {}
@Override
protected void obtainConfigurationValues() {
consensusThreshold = (Float) configuration.getValue(CONSENSUS_THRESHOLD);
feedbackLevel = (Float) configuration.getValue(SECOND_FEEDBACK_LEVEL);
maxRounds = (Integer) configuration.getValue(MAX_ROUNDS);
lamda = (Integer) configuration.getValue(DISTANCE_MEASURE_MINKOWSKI);
pointA = (Float) configuration.getValue(POINT_A);
pointB = (Float) configuration.getValue(POINT_B);
beta = (Float) configuration.getValue(BETA);
cost = (Integer[]) configuration.getValue(COST);
currentRound = 0;
consensusDegree = 0f;
groupal=true;
initializePreferencesWithoutGroup();
initializeAdvises();
}
private void initializePreferencesWithoutGroup() {
// Copy preferences except groupal
preferencesWithoutGroup = new FPR[preferences.length - 1];
for (int i = 0; i < preferences.length - 1; i++) {
try {
preferencesWithoutGroup[i] = (FPR) preferences[i].clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
private void initializeAdvises() {
advises = new int[experts.length];
for (int i = 0; i < advises.length; i++) {
advises[i] = 0;
}
}
@Override
protected Float[][][] obtainVisualizeValues() {
Float[][][] preferencesGroupVisualization = new Float[numberOfExperts + 1][numberOfAlternatives][numberOfAlternatives];
for (int k = 0; k < numberOfExperts+1; k++) {
preferencesGroupVisualization[k] = preferences[k].obtainVisualizeValues();
}
return preferencesGroupVisualization;
}
@SuppressWarnings("unchecked")
@Override
protected void preFirstSaveRoundResults() {
postClusters = generateClusters(alternatives, experts, (FPR[]) preferencesWithoutGroup, lamda);
List<ClusterFPR> clNotEmpty=checkEmptyClusters(postClusters);
CM consensusMatrixAux= computeConsensusMatrix(clNotEmpty);
Float [] consensusAlternatives=ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, consensusMatrixAux);
double consensusDegree=ConsensusEngine.consensusBasedOnAlternativesConsensus(numberOfAlternatives, consensusAlternatives);
computeCollective(clNotEmpty);
preferencesResult = (ArrayList<FPR>) ((RunnableScript) E4DIAddon.aseService.createExecutionBuilder()
.setFunction("Rodriguez2017")
.putVariable("epsilon", consensusThreshold)
.putVariable("cost", cost)
.putVariable("weights", weightsExperts)
.putVariable("prefs", preferencesWithoutGroup)
.putVariable("alternatives", numberOfAlternatives)
.execute())
.getResult();
//Rodriguez2017
collectiveMinimumCost=computeCollectiveMinimumCostPreferences(preferencesResult,weightsExperts);
FPR [] pr=new FPR[preferencesResult.size()];
for (int i = 0; i < pr.length; i++) {
pr[i]=preferencesResult.get(i);
}
FPR [] todas=new FPR[preferencesResult.size()];
for (int i = 0; i < preferencesResult.size(); i++) {
todas[i]=preferencesResult.get(i);
}
preSaveRoundResult(1, preferences,obtainVisualizeValues(), (float) consensusDegree);
roundsResults.get(roundsResults.size() - 1).put(ERoundResult.clusters, postClusters);
result.put(EResultElements.initial_consensus_degree, consensusDegree);
result.put(EResultElements.maxround, maxRounds);
result.put(EResultElements.consensus_threshold, consensusThreshold);
result.put(EResultElements.consensus_model, CONSENSUS_MODEL_NAME);
}
@Override
protected void preSaveRoundResults() {
preSaveRoundResult(currentRound + 1, preferences,obtainVisualizeValues(), (float) consensusDegree);
roundsResults.get(roundsResults.size() - 1).put(ERoundResult.clusters, postClusters);
}
@Override
protected void consensusRound() {
List<ClusterFPR> clNotEmpty=checkEmptyClusters(postClusters);
computeCollective(clNotEmpty);
consensusMatrix=computeConsensusMatrix(clNotEmpty);
consensusAlternatives=ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, consensusMatrix);
consensusDegree=ConsensusEngine.consensusBasedOnAlternativesConsensus(numberOfAlternatives, consensusAlternatives);
if(consensusDegree < consensusThreshold){
List<Recommendation> recommendations;
ArrayList<Double> proximityValues=computeProximity((FPR)preferences[numberOfExperts], clNotEmpty);
double proximityAverage=computeProximityAverage(proximityValues);
ArrayList<CM> proximityMatrix=computeProximitiMatrix((FPR) preferences[numberOfExperts],clNotEmpty );
CM proximityMatrixAverage=computeProximityMatrixAverage(proximityMatrix);
initializePreferencesWithoutGroup();
initializeAdvises();
if(consensusDegree < feedbackLevel){ ////Group feedback process
groupal=true;
recommendations= GenerateRecommendations.recommendationsForGroup(clNotEmpty,collectiveMinimumCost,proximityValues,consensusAlternatives,
proximityMatrix,proximityAverage,proximityMatrixAverage, consensusThreshold);
for (Recommendation r : recommendations) {
if (r.getIdExpert() != -1) {
advises[r.getIdExpert()] = 1;
}
}
}else{ ////Individual feedback process
groupal=false;
recommendations=GenerateRecommendations.recommendationsIndividual(clNotEmpty, (FPR) preferences[numberOfExperts], proximityValues,
consensusAlternatives, proximityMatrix, proximityAverage, proximityMatrixAverage, consensusThreshold, lamda);
for (Recommendation r : recommendations) {
if (r.getIdExpert() != -1) {
advises[r.getIdExpert()] = 1;
}
}
}
if (!recommendations.isEmpty()) {
clustersAfterChanges = changePreferencesExperts(postClusters, recommendations,preferencesResult,groupal);
FPR[] preferences = unifyPreferencesClusters(clustersAfterChanges);
postClusters = generateClusters(alternatives, experts, preferences, lamda);
}
currentRound++;
}
}
@Override
protected void posSaveRoundResults() {
List<ClusterFPR> clNotEmpty=checkEmptyClusters(postClusters);
computeCollective(clNotEmpty);
consensusMatrix=computeConsensusMatrix(clNotEmpty);
consensusAlternatives=ConsensusEngine.computeAlternativesConsensus(numberOfAlternatives, consensusMatrix);
consensusDegree=ConsensusEngine.consensusBasedOnAlternativesConsensus(numberOfAlternatives, consensusAlternatives);
posSaveRoundResult(preferences,obtainVisualizeValues(), (float) consensusDegree, advises, preferences[numberOfExperts]);
roundsResults.get(roundsResults.size() - 1).put(ERoundResult.clusters, postClusters);
}
@Override
protected boolean mustBeCarriedOutAnotherRound() {
return (((float) consensusDegree < consensusThreshold) && (currentRound < maxRounds));
}
@Override
protected void saveExecutionResults() {
this.configuration.setValue(PREFERENCES, preferences);
result.put(EResultElements.number_of_rounds_required, currentRound);
result.put(EResultElements.consensus_degree_achieved, consensusDegree);
}
@SuppressWarnings("unchecked")
public List<ClusterFPR> generateClusters(String[] alternatives, String[] experts, FPR[] preferences, int parameter) {
// Do clustering
if (roundsResults.isEmpty()) {
return FuzzyCMeansFPR.doClusteringFuzzyCMeansClusterForEachAlternative(alternatives, experts, preferences, null, parameter);
} else {
return FuzzyCMeansFPR.doClusteringFuzzyCMeansClusterForEachAlternative(alternatives, experts, preferences, (List<ClusterFPR>) roundsResults.get(roundsResults.size() - 1).get(ERoundResult.clusters), parameter);
}
}
@SuppressWarnings("unchecked")
public float calculateCohesion(ClusterFPR cluster){
if(cluster.getExperts().isEmpty()){
return 0f;
}
float cohesion=0;
float area=0;
float gT=1;
float nT= (float) (Math.pow(numberOfAlternatives, 2)-numberOfAlternatives-1);
float T=gT*nT;
HashMap<Pair<Integer,Integer>, Float> maxValues = new HashMap<Pair<Integer,Integer>, Float>();
HashMap<Pair<Integer,Integer>, Float > minValues = new HashMap<Pair<Integer,Integer>, Float>();
for (int i = 0; i < alternatives.length; i++) {
for (int j = 0; j < alternatives.length; j++) {
if(i!=j){
Pair<Pair<Integer,Integer>,Float> maxAuxValue= new Pair<Pair<Integer,Integer>,Float>();
Pair<Pair<Integer,Integer>,Float> minAuxValue= new Pair<Pair<Integer,Integer>,Float>();
maxAuxValue = new Pair<Pair<Integer,Integer>, Float>(new Pair<Integer, Integer>(i,j),(float)
((FPR) cluster.getPreferencesExpert(cluster.getExperts().get(0))).getPreferences()[i][j]);
minAuxValue = new Pair<Pair<Integer,Integer>, Float>(new Pair<Integer, Integer>(i,j),(float)
((FPR) cluster.getPreferencesExpert(cluster.getExperts().get(0))).getPreferences()[i][j]);
for (int k = 0; k < cluster.getExperts().size(); k++) {
if(maxAuxValue.getRight() < (Float) ((FPR) cluster.getPreferencesExpert(cluster.getExperts().get(k))).getPreferences()[i][j]){
maxAuxValue = new Pair<Pair<Integer,Integer>, Float>(new Pair<Integer, Integer>(i,j),
(Float) ((FPR) cluster.getPreferencesExpert(cluster.getExperts().get(k))).getPreferences()[i][j]);
}
if(minAuxValue.getRight() > (Float) ((FPR) cluster.getPreferencesExpert(cluster.getExperts().get(k))).getPreferences()[i][j]){
minAuxValue = new Pair<Pair<Integer,Integer>, Float>(new Pair<Integer, Integer>(i,j),
(Float) ((FPR) cluster.getPreferencesExpert(cluster.getExperts().get(k))).getPreferences()[i][j]);
}
}
maxValues.put(maxAuxValue.getLeft(), maxAuxValue.getRight());
minValues.put(minAuxValue.getLeft(), minAuxValue.getRight());
}
}
}
HashMap<Pair<Integer,Integer>, Float > orderMinValues = sortByValues(minValues);
//Calculate Area
for (int i = 0; i < alternatives.length; i++) {
for (int j = 0; j < alternatives.length; j++) {
if(i!=j){
area+=(maxValues.get(new Pair<Integer, Integer>(i,j))-minValues.get(new Pair<Integer, Integer>(i,j)));
}
}
}
float minAB=orderMinValues.get(orderMinValues.keySet().toArray()[0]);
float maxAB=maxValues.get(orderMinValues.keySet().toArray()[0]);
float minCD=orderMinValues.get(orderMinValues.keySet().toArray()[orderMinValues.keySet().toArray().length-1]);
float maxCD=maxValues.get(orderMinValues.keySet().toArray()[orderMinValues.keySet().toArray().length-1]);
float numerator=((maxAB-minAB)+(maxCD-minCD))/2;
area-=numerator;
cohesion=1-(area/T);
return cohesion;
}
private ArrayList<Double> obtainWeightsGroups(List<ClusterFPR> cluster,double beta,double pointA,double pointB) {
ArrayList<Double> weights=new ArrayList<Double>();
double cohesion,size,degreeSize;
double [] func={pointA,pointB,100f,100f};
TrapezoidalFunction membershipFunctionSize= new TrapezoidalFunction(func);
for(int i=0;i<cluster.size();i++){
cohesion = calculateCohesion(cluster.get(i));
size = cluster.get(i).getExperts().size();
degreeSize = membershipFunctionSize.getMembershipValue(size);
weights.add(powerFunction(cohesion, degreeSize,beta));
}
double sum=0;
for (int n = 0; n < weights.size(); n++) {
sum += weights.get(n);
}
ArrayList<Double> weightsNorm=new ArrayList<Double>();
for (int j = 0; j < weights.size(); j++) {
weightsNorm.add(weights.get(j) / sum);
}
return weightsNorm;
}
private double powerFunction(double valor1,double valor2,double beta) {
double result=0;
result= Math.pow(1+valor2,valor1*beta);
return result;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static HashMap sortByValues(HashMap map) {
List list = new LinkedList(map.entrySet());
// Defined Custom Comparator here
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue())
.compareTo(((Map.Entry) (o2)).getValue());
}
});
// Here I am copying the sorted list in HashMap
// using LinkedHashMap to preserve the insertion order
HashMap sortedHashMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
sortedHashMap.put(entry.getKey(), entry.getValue());
}
return sortedHashMap;
}
private CM computeConsensusMatrix(List<ClusterFPR> cl) {
List<CM> listSimilarityMatrix = calculateSimilarityMatrix(cl);
// Compute consensus matrix
CM consensusFPR = new CM(numberOfAlternatives);
float sum;
float value;
for (int i = 0; i < numberOfAlternatives; i++) {
for (int j = 0; j < numberOfAlternatives; j++) {
sum = 0;
for (CM similarityMatrix : listSimilarityMatrix) {
sum += (float) similarityMatrix.getValue(i, j);
}
value = sum / listSimilarityMatrix.size();
consensusFPR.setValue(i, j, value);
}
}
return consensusFPR;
}
private List<CM> calculateSimilarityMatrix(List<ClusterFPR> cl){
List<CM> listSimilarityMatrix = new LinkedList<CM>();
if(cl.size()==1) listSimilarityMatrix.add(new CM(numberOfAlternatives));
for (int i = 0; i <cl.size()-1; i++) {
for (int j = i+1; j < cl.size(); j++) {
FPR l = (FPR) cl.get(i).getCentroid();
FPR k = (FPR) cl.get(j).getCentroid();
CM similarityMatrix = ConsensusEngine.similarityMatrixDistanceMinkowski(numberOfAlternatives, l, k, lamda);
listSimilarityMatrix.add(similarityMatrix);
}
}
return listSimilarityMatrix;
}
private void computeCollective(List<ClusterFPR> cl){
weigthsGroup=obtainWeightsGroups(cl,beta,pointA,pointB);
weightsExperts=transformWeightsExperts(cl);
FPR collective=new FPR(numberOfAlternatives);
for (int i = 0; i < numberOfAlternatives-1; i++) {
for (int j = i+1; j < numberOfAlternatives; j++) {
float value=0;
for(int l=0;l<cl.size();l++){ //Each cluster
for(int r:cl.get(l).getPreferences().keySet()){ //Each expert in a cluster
double w=weigthsGroup.get(l);
float pIJ=(float) cl.get(l).getPreferences().get(r).getValue(i,j);
value+=(w*pIJ);
}
collective.setValueSymmetrically(i, j, value/numberOfExperts);
}
}
}
preferences[numberOfExperts]= collective;
}
private FPR computeCollectiveMinimumCostPreferences(ArrayList<FPR> preferences,Float [] weigths){
FPR collective=new FPR(numberOfAlternatives);
for (int i = 0; i < numberOfAlternatives-1; i++) {
for (int j = i+1; j < numberOfAlternatives; j++) {
float value=0;
double w=0;
float pIJ=0;
for(int ex=0;ex<preferences.size();ex++){ //Each cluster
w=weigths[ex];
pIJ=(float)preferences.get(ex).getValue(i,j);
value+=(w*pIJ);
}
collective.setValueSymmetrically(i, j, value);
}
}
return collective;
}
private ArrayList<Double> computeProximity(FPR collective,List<ClusterFPR> cl){
ArrayList<Double> proximity=new ArrayList<Double>();
for (int i = 0; i < cl.size(); i++) {
proximity.add(1d-ConsensusEngine.distanceMinkowski(collective, (FPR) cl.get(i).getCentroid(), lamda));
}
return proximity;
}
private double computeProximityAverage(ArrayList<Double> proximity){
double result=0;
for (int i = 0; i < proximity.size(); i++) {
result+=proximity.get(i);
}
return result/proximity.size();
}
private ArrayList<CM> computeProximitiMatrix(FPR collective, List<ClusterFPR> cl){
ArrayList<CM> proximityMatrix=new ArrayList<CM>();
for (int c = 0; c < cl.size(); c++) {
CM prox=new CM(numberOfAlternatives);
for (int i = 0; i < numberOfAlternatives; i++) {
for (int j = 0; j < numberOfAlternatives; j++) {
prox.setValue(i, j, Math.round((1d-ConsensusEngine.distanceMinkowskiValues((float) collective.getValue(i,j),
(float)((FPR) cl.get(c).getCentroid()).getValue(i,j), lamda))*10000f)/10000f);
}
}
proximityMatrix.add(prox);
}
return proximityMatrix;
}
private CM computeProximityMatrixAverage(ArrayList<CM> proximityMatrix){
CM result=new CM(numberOfAlternatives);
for (int i = 0; i < numberOfAlternatives; i++) {
for (int j = 0; j < numberOfAlternatives; j++) {
float value=0;
for (int px = 0; px < proximityMatrix.size(); px++) {
value+=(float)proximityMatrix.get(px).getValue(i, j);
}
value/=proximityMatrix.size();
result.setValue(i, j, value);
}
}
return result;
}
private Float[] transformWeightsExperts(List<ClusterFPR> clusters){
Float [] result=new Float[numberOfExperts];
for(int cl=0;cl<clusters.size();cl++){
for(int r:clusters.get(cl).getPreferences().keySet()){ //Each expert in a cluster
result[r]=weigthsGroup.get(cl).floatValue()/clusters.get(cl).getExperts().size();
}
}
return result;
}
public List<ClusterFPR> changePreferencesExperts(List<ClusterFPR> clusters, List<Recommendation> recommendations, ArrayList<FPR> preferencesMinimumCost, boolean groupal) {
List<ClusterFPR> postClusters = new LinkedList<ClusterFPR>();
for (ClusterFPR cluster : clusters) {
if (!cluster.getExperts().isEmpty()) {
ClusterFPR postCluster = changePreferences(cluster, recommendations,preferencesMinimumCost,groupal);
postClusters.add(postCluster);
}else{
postClusters.add(cluster);
}
}
return postClusters;
}
private ClusterFPR changePreferences(ClusterFPR cluster, List<Recommendation> recommendations,ArrayList<FPR> preferencesMinimumCost, boolean groupal) {
double change = 0;
double [] changes=getNChanges(recommendations.size());
int n=0;
try {
ClusterFPR postCluster = (ClusterFPR) cluster.clone();
// Random random = new Random();//añadido
for (Recommendation recommendation : recommendations) {
int m=0;
if (cluster.getId() == recommendation.getIdCluster()) {
int idAlt1 = recommendation.getIdAlternative1();
int idAlt2 = recommendation.getIdAlternative2();
int idExpert = recommendation.getIdExpert();
if (!groupal) {// change expert' preference
if(changes[n]!=0){
change=(float) preferencesMinimumCost.get(idExpert).getValue(idAlt1,idAlt2);
((FPR) postCluster.getPreferencesExpert(idExpert)).setValueSymmetrically(idAlt1, idAlt2, change);
((FPR) preferences[idExpert]).setValueSymmetrically(idAlt1, idAlt2, change);
}
n++;
} else {// change preferences for all experts
if(changes[m]!=0){
change=changes[m];
float value = (float) ((FPR) cluster.getPreferencesExpert(recommendation.getIdExpert())).getValue(idAlt1, idAlt2);
if (recommendation.getDirection() == EChangeType.Increase) {
value += change;
if (value > 1){
value = 1f;
}else if(value < 0){
value=0f;
}
} else {
if (recommendation.getDirection() == EChangeType.Decrease) {
value -= change;
if (value < 0){
value = 0f;
}else if(value > 1){
value=1f;
}
}
}
((FPR) postCluster.getPreferencesExpert(recommendation.getIdExpert())).setValueSymmetrically(idAlt1, idAlt2,value);
((FPR) preferences[recommendation.getIdExpert()]).setValueSymmetrically(idAlt1, idAlt2, value);
}
m++;
}
}
} // END-FOR
return postCluster;
} catch (Exception e) {
throw new IllegalArgumentException(e.getMessage());
}
}
public FPR[] unifyPreferencesClusters(List<ClusterFPR> clusters) {
Map<Integer, PR> allPreferences = new HashMap<Integer, PR>();
Map<Integer, PR> preferences = null;
FPR[] result;
for (ClusterFPR cluster : clusters) {
if (!cluster.getExperts().isEmpty()) {
preferences = cluster.getPreferences();
allPreferences.putAll(preferences);
}
}
result = new FPR[allPreferences.size()];
Map<Integer, PR> treeMap = new TreeMap<Integer, PR>(allPreferences);
for (Integer str : treeMap.keySet()) {
result[str] = (FPR) treeMap.get(str);
}
return result;
}
private List<ClusterFPR> checkEmptyClusters(List<ClusterFPR> clusters){
List<ClusterFPR> clustersNotEmpty=new LinkedList<ClusterFPR>();
for (int i = 0; i < clusters.size(); i++) {
if(!clusters.get(i).getExperts().isEmpty()){
clustersNotEmpty.add(clusters.get(i));
}
}
return clustersNotEmpty;
}
}
@@ -0,0 +1,11 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name.0
Bundle-SymbolicName: afryca.consensusmodel.rodriguez2018MinimumCostClust
ering;singleton:=true
Bundle-Version: 1.0.0.202101221157
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: afryca.consensusmodel
Automatic-Module-Name: afryca.consensusmodel.Rodriguez2017MinimumCostClu
stering
@@ -0,0 +1,4 @@
#Fri Jan 22 13:01:42 CET 2021
artifact.main=C\:\\Users\\\u00C1lvaro\\Workspaces\\afryca_2020\\afryca\\plugins\\afryca.consensusmodel.rodriguez2018MinimumCostClustering\\target\\afryca.consensusmodel.rodriguez2018MinimumCostClustering-1.0.0-SNAPSHOT.jar
artifact.attached.p2artifacts=C\:\\Users\\\u00C1lvaro\\Workspaces\\afryca_2020\\afryca\\plugins\\afryca.consensusmodel.rodriguez2018MinimumCostClustering\\target\\p2artifacts.xml
artifact.attached.p2metadata=C\:\\Users\\\u00C1lvaro\\Workspaces\\afryca_2020\\afryca\\plugins\\afryca.consensusmodel.rodriguez2018MinimumCostClustering\\target\\p2content.xml
@@ -0,0 +1,3 @@
artifactId=afryca.consensusmodel.rodriguez2018MinimumCostClustering
groupId=afryca.group
version=1.0.0-SNAPSHOT
@@ -0,0 +1,13 @@
<?xml version='1.0' encoding='UTF-8'?>
<?artifactRepository version='1.1.0'?>
<artifacts size='1'>
<artifact classifier='osgi.bundle' id='afryca.consensusmodel.rodriguez2018MinimumCostClustering' version='1.0.0.202101221157'>
<properties size='5'>
<property name='artifact.size' value='20083'/>
<property name='download.size' value='20083'/>
<property name='maven-groupId' value='afryca.group'/>
<property name='maven-artifactId' value='afryca.consensusmodel.rodriguez2018MinimumCostClustering'/>
<property name='maven-version' value='1.0.0-SNAPSHOT'/>
</properties>
</artifact>
</artifacts>
@@ -0,0 +1,43 @@
<?xml version='1.0' encoding='UTF-8'?>
<units size='1'>
<unit id='afryca.consensusmodel.rodriguez2018MinimumCostClustering' version='1.0.0.202101221157' generation='2'>
<update id='afryca.consensusmodel.rodriguez2018MinimumCostClustering' range='[0.0.0,1.0.0.202101221157)' severity='0'/>
<properties size='5'>
<property name='df_LT.Bundle-Name.0' value='Rodriguez2017MinimumCostClustering'/>
<property name='org.eclipse.equinox.p2.name' value='%Bundle-Name.0'/>
<property name='maven-groupId' value='afryca.group'/>
<property name='maven-artifactId' value='afryca.consensusmodel.rodriguez2018MinimumCostClustering'/>
<property name='maven-version' value='1.0.0-SNAPSHOT'/>
</properties>
<provides size='5'>
<provided namespace='org.eclipse.equinox.p2.iu' name='afryca.consensusmodel.rodriguez2018MinimumCostClustering' version='1.0.0.202101221157'/>
<provided namespace='osgi.bundle' name='afryca.consensusmodel.rodriguez2018MinimumCostClustering' version='1.0.0.202101221157'/>
<provided namespace='osgi.identity' name='afryca.consensusmodel.rodriguez2018MinimumCostClustering' version='1.0.0.202101221157'>
<properties size='1'>
<property name='type' value='osgi.bundle'/>
</properties>
</provided>
<provided namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' version='1.0.0'/>
<provided namespace='org.eclipse.equinox.p2.localization' name='df_LT' version='1.0.0'/>
</provides>
<requires size='2'>
<required namespace='osgi.bundle' name='afryca.consensusmodel' range='0.0.0'/>
<requiredProperties namespace='osgi.ee' match='(&amp;(osgi.ee=JavaSE)(version=1.8))'>
<description>
afryca.consensusmodel.rodriguez2018MinimumCostClustering
</description>
</requiredProperties>
</requires>
<artifacts size='1'>
<artifact classifier='osgi.bundle' id='afryca.consensusmodel.rodriguez2018MinimumCostClustering' version='1.0.0.202101221157'/>
</artifacts>
<touchpoint id='org.eclipse.equinox.p2.osgi' version='1.0.0'/>
<touchpointData size='1'>
<instructions size='1'>
<instruction key='manifest'>
Bundle-SymbolicName: afryca.consensusmodel.rodriguez2018MinimumCostClustering;singleton:=true&#xA;Bundle-Version: 1.0.0.202101221157&#xA;
</instruction>
</instructions>
</touchpointData>
</unit>
</units>