package happy.research.pgp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class OurMethodPGP extends AbstractPGP
{
@Override
protected Performance firePerformanceTest(final List<PGPNode> nodes)
{
int numNodes = nodes.size();
int coversCount[] = new int[numNodes];
double coverages[] = new double[numNodes];
double accuracies[] = new double[numNodes];
double distances[] = new double[numNodes];
for (int i = 0; i < numNodes; i++)
{
PGPNode entity = nodes.get(i);
Map<PGPNode, Double> tnsAll_positive = new HashMap<>(numNodes * 2);
Map<PGPNode, Double> tnsAll_negative = new HashMap<>(numNodes * 2);
Map<PGPNode, CertificateType> tnsAll_combined = new HashMap<>(numNodes * 2);
Map<PGPNode, Double> tnsAll_confidence = new HashMap<>(numNodes * 2);
// process raw data
for (Entry<PGPNode, TrustType> entry : entity.getTns().entrySet())
{
PGPNode tn = entry.getKey();
TrustType tt = entry.getValue();
if (tn == entity) continue;
// TrustType tt=entry.getValue();
for (Entry<PGPNode, TrustType> tn_entry : tn.getNeighborus().entrySet())
{
PGPNode tn_tn = tn_entry.getKey();
CertificateType tn_ct = tn_tn.getSigners().get(tn);
// Due to some tns directly predefined without signing
// so tn_ct == null is possible
if (tn_ct == null) continue;
if (tnsAll_positive.containsKey(tn_tn))
{
// combine together using majority method
// problem: what if positive no. = negative no.?
if (tn_ct == CertificateType.VALID)
{
tnsAll_positive.put(tn_tn, tnsAll_positive.get(tn_tn).doubleValue()
+ tn_ct.getInherentValue() * tt.getTrustValue());
} else if (tn_ct == CertificateType.INVALID)
{
tnsAll_negative.put(tn_tn, tnsAll_negative.get(tn_tn).doubleValue()
+ tn_ct.getInherentValue() * tt.getTrustValue());
}
} else
{
// make sure positive and negative set have same size
if (tn_ct == CertificateType.VALID)
{
tnsAll_positive.put(tn_tn, tn_ct.getInherentValue() * tt.getTrustValue());
tnsAll_negative.put(tn_tn, 0.0);
} else if (tn_ct == CertificateType.INVALID)
{
tnsAll_positive.put(tn_tn, 0.0);
tnsAll_negative.put(tn_tn, tn_ct.getInherentValue() * tt.getTrustValue());
}
}
}
}
// compute combined vector and confidence
for (Entry<PGPNode, Double> entry_positive : tnsAll_positive.entrySet())
{
PGPNode node = entry_positive.getKey();
double r = Math.abs(entry_positive.getValue().doubleValue());
double s = Math.abs(tnsAll_negative.get(node).doubleValue());
try
{
double confidence = calculateCertainty(r, s);
// logger.info("r = " + r + " , s = " + s + ", confidence = " + confidence);
// only nodes with confidence>threshold will be used latter
if (confidence >= AbstractPGP.CONFIDENCE_THRESHOLD && r > s)
{
tnsAll_combined.put(node, CertificateType.VALID);
tnsAll_confidence.put(node, new Double(confidence));
} else if (confidence >= AbstractPGP.CONFIDENCE_THRESHOLD && r <= s)
{
tnsAll_combined.put(node, CertificateType.INVALID);
tnsAll_confidence.put(node, new Double(confidence));
}
} catch (Exception e)
{
e.printStackTrace();
}
}
// compute the similar nodes
if (tnsAll_combined.size() > 0)
{
entity.getNns().clear();
for (int j = 0; j < numNodes; j++)
{
if (j == i) continue;// self
PGPNode candidate = nodes.get(j);
if (entity.getTns().containsKey(candidate)) continue; // tns
// test if candidate is a candidate
// double sum_rx = 0.0, sum_ry = 0.0;
int size = tnsAll_combined.size();
int[] rxs = new int[size];
int[] rys = new int[size];
int index = 0;
for (Entry<PGPNode, CertificateType> entry : tnsAll_combined.entrySet())
{
PGPNode node = entry.getKey();
if (candidate.getNeighborus().containsKey(node) && node.getSigners().get(candidate) != null)
{
rxs[index] = entry.getValue().getInherentValue();
rys[index] = node.getSigners().get(candidate).getInherentValue();
// sum_rx += rxs[index];
// sum_ry += rys[index];
index++;
}
}
if (index <= size * AbstractPGP.CANDIDATE_VECTOR_RATIO)
{
// not a candidate
continue;
}
// calculate similarity
// double rx = sum_rx / index;
// double ry = sum_ry / index;
// double similarity = evaluatePearsonSimilarity(rx, ry, rxs, rys, index);
double similarity = evaluateCosineSimilarity(rxs, rys, index);
// logger.info("test similarity = " + similarity);
if (similarity >= AbstractPGP.SIMILARITY_THRESHOLD)
{
// nearest neighbour with trust value = similarity
entity.getNns().put(candidate, new Double(similarity));
}
}
}
// evaluate the performance: coverage and distance
int count_coverage = 0, accuracy_count = 0;
for (int j = 0; j < numNodes; j++)
{
if (j == i) continue;
PGPNode target = nodes.get(j);
if (entity.getTns().containsKey(target)) continue;
if (entity.getNns().containsKey(target)) continue;
double positive_sum = 0.0, negative_sum = 0.0;
int count_test = 0;
for (Entry<PGPNode, CertificateType> entry : target.getSigners().entrySet())
{
PGPNode signer = entry.getKey();
CertificateType ct = entry.getValue();
if (signer == target) continue;
if (entity.getTns().containsKey(signer))
{
TrustType tt = entity.getTns().get(signer);
if (ct == CertificateType.VALID)
positive_sum += tt.getTrustValue() * ct.getInherentValue();
else if (ct == CertificateType.INVALID)
negative_sum += tt.getTrustValue() * ct.getInherentValue();
count_test++;
} else if (entity.getNns().containsKey(signer))
{
double similarity = entity.getNns().get(signer);
if (ct == CertificateType.VALID)
positive_sum += similarity * ct.getInherentValue();
else if (ct == CertificateType.INVALID)
negative_sum += similarity * ct.getInherentValue();
count_test++;
}
}
if (count_test > 0)
{
count_coverage++;
double validity = (Math.abs(positive_sum) - Math.abs(negative_sum))
/ (Math.abs(positive_sum) + Math.abs(negative_sum));
double distance = Math.abs(validity - target.getCertificate().getInherentValue());
distances[i] += distance;
if (distance <= ACCURACY_THRESHOLD) accuracy_count++;
}
}
coversCount[i] = count_coverage;
int needsCoverCount = numNodes - 1 - entity.getTns().size() - entity.getNns().size();
// logger.info("no. of entity " + i + " nearest neighbors = " +
// entity.getNns().size());
coverages[i] = (coversCount[i] + 0.0) / needsCoverCount;
accuracies[i] = (accuracy_count + 0.0) / needsCoverCount;
if (coversCount[i] > 0)
distances[i] /= coversCount[i];
}
return calculatePerformance(AbstractPGP.OURMETHOD_PGP, coversCount, coverages, distances, accuracies);
}
}