public PCMSolution(FCMSolution init, MethodInputResponse input, int clustersCount) : base(input, clustersCount) { eta = new double[clustersNumber]; D = new double[clustersNumber, methodInput.InputObjects.Count]; // initialize cluster prototypes (as a result of FCM): for (int i = 0; i < clustersNumber; i++) { clusterPrototypes[i] = new InputObject(""); clusterPrototypes[i].Dimensions = init.ClusterPrototypes[i].Dimensions; } // initialize primary memberships (the same way): for (int i = 0; i < methodInput.InputObjects.Count; i++) for (int j = 0; j < clustersNumber; j++) primaryMemberships[j, i] = init.PrimaryMemberships[j, i]; setD(); setTarget(); }
public void Run() { MethodInputResponse inputParams = GetInput(); //get offsets for output int afterPcmOffset = inputParams.InputObjects.Count + inputParams.dimensionsLowerBounds.Count + 10; for( int clustersNumber = 3; clustersNumber <= MAX_CLUSTERS_NUMBER; clustersNumber++) { ShowIndicesTitles(afterPcmOffset * 2, clustersNumber); //run FCM to tune initial clusters centers and type-1 memberships FCMSolution FCM = new FCMSolution(inputParams, clustersNumber); FCM.DegreeOfFuzziness = 1.5; int fcmIterationsCounter = 0; double oldFcmTarget = double.PositiveInfinity; // start FCM iterations while (oldFcmTarget > FCM.Target) { FCM.UpdateClusterPrototypes(); oldFcmTarget = FCM.Target; FCM.UpdatePrimaryMemberships(); fcmIterationsCounter++; Application.DoEvents(); } //have some output after FCM //ShowResults(FCM, clustersNumber, inputParams, fcmIterationsCounter, 0, "Best FCM with m = " + FCM.DegreeOfFuzziness); //run PCM now, using the FCM output PCMSolution PCM = new PCMSolution(FCM, inputParams, clustersNumber); PCM.estimateEta(); // iterate m: PCM.DegreeOfFuzziness = MIN_M_VALUE; int finalIterationsCounter = 0; ValidityIndex kwonIndex = new ValidityIndex(IndexType.Kwon); ValidityIndex partitionIndex = new ValidityIndex(IndexType.PartitionIndex); ValidityIndex xieBeniIndex = new ValidityIndex(IndexType.XieBeni); ValidityIndex xieBeni2Index = new ValidityIndex(IndexType.XieBeni2); kwonIndex.SetCurrentValue(PCM.GetKwonIndex(), PCM.DegreeOfFuzziness); partitionIndex.SetCurrentValue(PCM.GetPartitionIndex(), PCM.DegreeOfFuzziness); xieBeniIndex.SetCurrentValue(PCM.GetXieBeniIndex(), PCM.DegreeOfFuzziness); xieBeni2Index.SetCurrentValue(PCM.GetXieBeni2Index(), PCM.DegreeOfFuzziness); while (PCM.DegreeOfFuzziness < MAX_M_VALUE) { RunPcm(PCM, ref finalIterationsCounter); kwonIndex.SetCurrentValue(PCM.GetKwonIndex(), PCM.DegreeOfFuzziness); partitionIndex.SetCurrentValue(PCM.GetPartitionIndex(), PCM.DegreeOfFuzziness); xieBeniIndex.SetCurrentValue(PCM.GetXieBeniIndex(), PCM.DegreeOfFuzziness); xieBeni2Index.SetCurrentValue(PCM.GetXieBeni2Index(), PCM.DegreeOfFuzziness); ShowIndex(afterPcmOffset*2, clustersNumber, 1, PCM.DegreeOfFuzziness, PCM.DegreeOfFuzziness);//m ShowIndex(afterPcmOffset*2, clustersNumber, (int)kwonIndex.IndexType, kwonIndex.CurrentValue, PCM.DegreeOfFuzziness); //ShowIndex(afterPcmOffset, clustersNumber, (int)IndexType.PartitionCoefficient, PCM.GetPartitionCoefficient(), PCM.DegreeOfFuzziness); ShowIndex(afterPcmOffset*2, clustersNumber, (int)partitionIndex.IndexType, partitionIndex.CurrentValue, PCM.DegreeOfFuzziness); ShowIndex(afterPcmOffset*2, clustersNumber, (int)xieBeniIndex.IndexType, xieBeniIndex.CurrentValue, PCM.DegreeOfFuzziness); //ShowIndex(afterPcmOffset, clustersNumber, (int)IndexType.ExtendedXieBeni, PCM.GetExtendedXBIndex(), PCM.DegreeOfFuzziness); //ShowIndex(afterPcmOffset, clustersNumber, (int)IndexType.ExtendedKwon, PCM.GetExtendedKwonIndex(), PCM.DegreeOfFuzziness); ShowIndex(afterPcmOffset*2, clustersNumber, (int)xieBeni2Index.IndexType, xieBeni2Index.CurrentValue, PCM.DegreeOfFuzziness); PCM.DegreeOfFuzziness += DEGREE_OF_FUZZINESS_STEP; } kwonIndex.SummarizeBounds(); xieBeniIndex.SummarizeBounds(); partitionIndex.SummarizeBounds(); //get upper and lower bounds //double ultimateUpper = Math.Min(Math.Min(kwonIndex.UpperBound, xieBeniIndex.UpperBound), partitionIndex.UpperBound); // double ultimateLower = Math.Max(Math.Max(kwonIndex.LowerBound, xieBeniIndex.LowerBound), partitionIndex.LowerBound); double ultimateUpper = Math.Max(Math.Max(kwonIndex.UpperBound, xieBeniIndex.UpperBound), partitionIndex.UpperBound); double ultimateLower = Math.Min(Math.Min(kwonIndex.LowerBound, xieBeniIndex.LowerBound), partitionIndex.LowerBound); //display the bounds of m: ShowBounds(clustersNumber, xieBeniIndex, kwonIndex, partitionIndex, ultimateLower, ultimateUpper); //boundary solutions: // left: PCMSolution leftSolution = new PCMSolution(FCM, inputParams, clustersNumber); leftSolution.estimateEta(); leftSolution.DegreeOfFuzziness = ultimateLower; RunPcm(leftSolution, ref finalIterationsCounter); // right: PCMSolution rightSolution = new PCMSolution(FCM, inputParams, clustersNumber); rightSolution.estimateEta(); rightSolution.DegreeOfFuzziness = ultimateUpper; RunPcm(rightSolution, ref finalIterationsCounter); double avgUZoneArea = 0; int baseOffset = (int) Math.Round(afterPcmOffset * 2 + Enum.GetNames(typeof(IndexType)).Count() + (MAX_M_VALUE - MIN_M_VALUE)/DEGREE_OF_FUZZINESS_STEP); for (int currentCluster = 0; currentCluster < clustersNumber; currentCluster++) { double uZoneArea = PCMSolution.GetUZoneArea(leftSolution.PrimaryMemberships, rightSolution.PrimaryMemberships, currentCluster); ShowUZoneArea(baseOffset + currentCluster, currentCluster.ToString(), clustersNumber, uZoneArea); avgUZoneArea += uZoneArea; } ShowUZoneArea(baseOffset + clustersNumber, "avg", clustersNumber, avgUZoneArea / clustersNumber); ShowResults(leftSolution, clustersNumber, inputParams, Enum.GetValues(typeof(IndexType)).Length, "Left bound. m = " + leftSolution.DegreeOfFuzziness); ShowResults(rightSolution, clustersNumber, inputParams, afterPcmOffset + Enum.GetValues(typeof(IndexType)).Length, "Right bound. m = " + rightSolution.DegreeOfFuzziness); } ReleaseExcelStuff(); }