public void CalculateNormativeFit(Context currentContext, Simulation simulation) { int numDimensions = currentContext.relevantCharacteristcs.Count; for (int c = 0; c < clusterMeans.Count; c++) { var clusterMean = clusterMeans[c]; float bestDistance = float.MaxValue; foreach (var socialGroup in knowledgeBase) { bool validGroup = true; float distance = 0.0f; for (int i = 0; i < numDimensions; i++) { float groupValue = 0.0f; if (!socialGroup.characteristics.TryGetValue(currentContext.relevantCharacteristcs[i], out groupValue)) { validGroup = false; break; } float weight = currentContext.relevantCharacteristcs[i].weight; float difference = (clusterMean.mean[i] - groupValue) * weight; distance += difference * difference; } if (!validGroup) { continue; } distance = (float)Math.Sqrt((double)distance); if (distance < bestDistance) { bestDistance = distance; clusterMean.matchedGroup = socialGroup; } } // ad-hoc group if (bestDistance > simulation.normativeMatchDistance * currentContext.GetMaxDistance()) { numAdhocGroups++; SocialGroup adhocGroup = new SocialGroup(); adhocGroup.isAdHoc = true; adhocGroup.characteristics = new Dictionary <Characteristic, float>(); adhocGroup.name = "Group " + numAdhocGroups; for (int i = 0; i < numDimensions; i++) { adhocGroup.characteristics.Add(currentContext.relevantCharacteristcs[i], clusterMean.mean[i]); } adhocGroup.CalculateAccessibility(this); knowledgeBase.Add(adhocGroup); clusterMean.matchedGroup = adhocGroup; } clusterMeans[c] = clusterMean; } }
/* * public void NormalizeAccessibility() * { * float totalAccessibility = 0.0f; * * foreach (var socialGroup in knowledgeBase) * { * totalAccessibility += socialGroup.accessibility; * } * * if (totalAccessibility == 0.0f) * { * foreach (var socialGroup in knowledgeBase) * { * socialGroup.accessibility = 1.0f / knowledgeBase.Count; * } * } * else * { * foreach (var socialGroup in knowledgeBase) * { * socialGroup.accessibility /= totalAccessibility; * } * } * }*/ public void CalculateComparativeFit(Context currentContext, Simulation simulation) { salience = minimalSalienceThreshold; foreach (var socialGroup in knowledgeBase) { float groupComparativeFit; int numDimensions = currentContext.relevantCharacteristcs.Count; int selfCluster = GetSelfCluster(); float meanDistance = 0.0f, meanDispersion = 0.0f; bool validGroup = true; for (int c = 0; c < clusterMeans.Count; c++) { if (c == selfCluster) { continue; } var clusterMean = clusterMeans[c]; float distance = 0.0f; for (int i = 0; i < numDimensions; i++) { // Comparative distance with visible groups or matched groups float groupValue = 0.0f, selfGroupValue = 0.0f; clusterMean.matchedGroup.characteristics.TryGetValue(currentContext.relevantCharacteristcs[i], out groupValue); if (!socialGroup.characteristics.TryGetValue(currentContext.relevantCharacteristcs[i], out selfGroupValue)) { validGroup = false; break; } float weight = currentContext.relevantCharacteristcs[i].weight; float difference = (groupValue - selfGroupValue) * weight; distance += difference * difference; } if (!validGroup) { break; } meanDistance += (float)Math.Sqrt((double)distance) / currentContext.GetMaxDistance(); meanDispersion += clusterMean.dispersion; } if (!validGroup) { continue; } if (clusterMeans.Count > 1) { meanDistance /= clusterMeans.Count - 1; meanDispersion /= clusterMeans.Count - 1; groupComparativeFit = simulation.comparativeFitAlfa * meanDistance + (1.0f - simulation.comparativeFitAlfa) * (simulation.comparativeFitBeta * (1.0f - clusterMeans[selfCluster].dispersion) + (1.0f - simulation.comparativeFitBeta) * meanDispersion); } else { meanDistance = 0.0f; groupComparativeFit = 0.0f; } float groupSalience = groupComparativeFit * socialGroup.accessibility; socialGroup.salience = groupSalience; if (groupSalience > salience) { selfGroup = socialGroup; salience = groupSalience; comparativeFit = groupComparativeFit; groupMeanDistance = meanDistance; } } }