Click here to Skip to main content
15,893,564 members
Articles / Programming Languages / C#

Fuzzy Logic Dot Net Fuzzy Collections

Rate me:
Please Sign up or sign in to vote.
4.20/5 (4 votes)
12 Oct 20045 min read 50.5K   2K   27  
Upgrading the collections in the Fuzzy Dot Net Library.
using System;
using System.Xml;
using System.Collections;

namespace Fuzzy_Logic_Library
{
	/// <summary>
	/// This is an experimental class for use in the Pathfinder project
	/// The idea is that the class is developed as a helper to make decisions
	/// Though I'm not sure at the moment how much use it will actually be.
	/// The hope is that as the decisions for the Pathfinder program get more 
	/// complex then this class will evolve along with the program
	/// </summary>
	public class FuzzyDecision : FuzzyBasic
	{
		/// <summary>
		/// a FuzzyDecision automatically starts as invalid until an
		/// assignment or decrement has been made on it
		/// </summary>
		private bool bIsValidNumber;

		public bool IsValid
		{
			get
			{
				return bIsValidNumber;
			}
			set
			{
				bIsValidNumber = value;
			}
		}

		/// <summary>
		/// basic constructor
		/// </summary>
		public FuzzyDecision() : base()
		{
			//
			// TODO: Add constructor logic here
			//
			bIsValidNumber = false;
		}

		/// <summary>
		/// copy constructor
		/// </summary>
		/// <param name="decision"></param>
		private FuzzyDecision( FuzzyDecision decision )
		{
			this.Number = decision.Number;
			this.Name = decision.Name;
			this.bIsValidNumber = decision.IsValid;
		}

		/// <summary>
		/// Constructor taking just the decision name
		/// </summary>
		/// <param name="name"></param>
		public FuzzyDecision( string name )
		{
			bIsValidNumber = false;
			this.Name = name;
		}

		/// <summary>
		/// increment this decision
		/// </summary>
		public void IncrementDecision()
		{
			this.Number++;
		}

		/// <summary>
		/// decrement this decision
		/// </summary>
		public void DecrementDecision()
		{
			this.Number--;
		}

		/// <summary>
		/// add the passed in value to this decision
		/// </summary>
		/// <param name="number"></param>
		public void AddToDecision( int number )
		{
			this.Number += number;
		}

		/// <summary>
		/// subtract the passed in value from this decision
		/// </summary>
		/// <param name="number"></param>
		public void SubtractFromDecision( int number )
		{
			this.Number -= number;
		}

		/// <summary>
		/// set this decision value to zero
		/// </summary>
		public void ZeroNumber()
		{
			this.Number = 0;
		}

		/// <summary>
		/// compare this decision with another returning the winner
		/// </summary>
		/// <param name="decision"></param>
		/// <returns></returns>
		public FuzzyDecision Compare( FuzzyDecision decision )
		{
			if( this.IsValid == false )
				return new FuzzyDecision( decision );
			if( decision == null || decision.IsValid == false )
				return new FuzzyDecision( this );

			if( this.Number > decision.Number )
				return new FuzzyDecision( this );
			else if( this.Number < decision.Number )
				return new FuzzyDecision( decision );
			else if( this.Number == decision.Number )
			{
				Random rand = new Random();
				switch( rand.Next( 3 ) )
				{
					case 1: return new FuzzyDecision( this ); 
					case 2: return new FuzzyDecision( decision );
					default : return new FuzzyDecision( decision );
				}
			}
			else 
				return new FuzzyDecision( this );
		}

		/// <summary>
		/// Save this decision
		/// </summary>
		/// <param name="xmlWriter"></param>
		public override void Save( XmlWriter xmlWriter )
		{
			xmlWriter.WriteStartElement( "FuzzyDecision" );
			xmlWriter.WriteElementString( "IsValid", IsValid.ToString() );
			base.Save( xmlWriter );
			xmlWriter.WriteEndElement();
		}


		/// <summary>
		/// load the values for this decision from an xml file
		/// </summary>
		/// <param name="xmlReader"></param>
		public override void Load( XmlReader xmlReader )
		{
			while( xmlReader.Name != "IsValid" )
			{
				xmlReader.Read();
				if( xmlReader.EOF == true )
					return;
			}

			xmlReader.Read();
			if( xmlReader.Value == "True" )
				IsValid = true;
			else
				IsValid = false;

			base.Load( xmlReader );

		}

		/// Comparison stuff

		public static bool operator ==( FuzzyDecision fuzzyDecisionOne, FuzzyDecision fuzzyDecisionTwo )
		{
			bool bOneIsNull = false;
			bool bBothAreNull = false;
			try
			{
				double nTest = fuzzyDecisionOne.ID;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				bOneIsNull = true;
			}

			try
			{
				double nTest = fuzzyDecisionTwo.ID;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				if( bOneIsNull == true )
					bBothAreNull = true;
				else
					bOneIsNull = true;
			}

			if( bOneIsNull == true && bBothAreNull == false )
				return false;

			if( bBothAreNull == true )
				return true;


			if( fuzzyDecisionOne.IsValid == fuzzyDecisionTwo.IsValid
				&& fuzzyDecisionOne.ID == fuzzyDecisionTwo.ID
				&& fuzzyDecisionOne.Maximum == fuzzyDecisionTwo.Maximum
				&& fuzzyDecisionOne.Membership == fuzzyDecisionTwo.Membership
				&& fuzzyDecisionOne.Minimum == fuzzyDecisionTwo.Minimum
				&& fuzzyDecisionOne.Name == fuzzyDecisionTwo.Name 
				&& fuzzyDecisionOne.Number == fuzzyDecisionTwo.Number )
				return true;
			else
				return false;
		}

		public static bool operator !=( FuzzyDecision fuzzyDecisionOne, FuzzyDecision fuzzyDecisionTwo )
		{
			bool bOneIsNull = false;
			bool bBothAreNull = false;
			try
			{
				double nTest = fuzzyDecisionOne.ID;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strString = nullRefExp.Message;

				bOneIsNull = true;
			}

			try
			{
				double nTest = fuzzyDecisionTwo.ID;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				if( bOneIsNull == true )
					bBothAreNull = true;
				else
					bOneIsNull = true;
			}

			if( bOneIsNull == true && bBothAreNull == false )
				return true;

			if( bBothAreNull == true )
				return false;


			if( fuzzyDecisionOne.IsValid != fuzzyDecisionTwo.IsValid
				|| fuzzyDecisionOne.ID != fuzzyDecisionTwo.ID
				|| fuzzyDecisionOne.Maximum != fuzzyDecisionTwo.Maximum
				|| fuzzyDecisionOne.Membership != fuzzyDecisionTwo.Membership
				|| fuzzyDecisionOne.Minimum != fuzzyDecisionTwo.Minimum
				|| fuzzyDecisionOne.Name != fuzzyDecisionTwo.Name 
				|| fuzzyDecisionOne.Number != fuzzyDecisionTwo.Number )
				return true;
			else
				return false;
		}

		/// required overrides due to the comparison operators
		///

		public override bool Equals(object obj)
		{
			if( obj == null || GetType() != obj.GetType() )
				return false;

			FuzzyDecision temp = ( FuzzyDecision )obj;

			return this == temp;
		}

		public override int GetHashCode()
		{
			return ID.GetHashCode() ^ Maximum.GetHashCode() ^ Membership.GetHashCode() ^ Minimum.GetHashCode() ^ Name.GetHashCode() ^ Number.GetHashCode();
		}

	}

	/// <summary>
	/// use a decision set to store the decisions
	/// </summary>
	public class FuzzyDecisionSet : FuzzySet
	{
		/// <summary>
		/// standard constructor
		/// </summary>
		public FuzzyDecisionSet()
		{
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="strName"></param>
		public FuzzyDecisionSet( string strName ) : base()
		{
			Name = strName;
		}

		public string GetName( int decision )
		{
			if( decision < Count )
			{
				return ( ( FuzzyDecision )this[ decision ] ).Name;
			}

			return null;
		}

		/// <summary>
		/// return the strongest Decision
		/// </summary>
		/// <returns></returns>
		public FuzzyDecision WinningDecision()
		{
			int nWinningNumber = 0;
			for( int i=0; i<Count; i++ )
			{
				if( i+1 < Count )
				{
					if( ( ( FuzzyDecision )this[ i ] ).Number > ( ( FuzzyDecision )this[ i+1 ] ).Number )
					{
						nWinningNumber = i;
					}
				}
			}

			return ( FuzzyDecision )this[ nWinningNumber ];
		}

		/// <summary>
		/// return the weakest decision
		/// </summary>
		/// <returns></returns>
		public FuzzyDecision LosingDecision()
		{
			int nLosingNumber = 0;
			for( int i=0; i<Count; i++ )
			{
				if( i+1 < Count )
				{
					if( ( ( FuzzyDecision )this[ i ] ).Number < ( ( FuzzyDecision )this[ i+1 ] ).Number )
					{
						nLosingNumber = i;
					}
				}
			}

			return ( FuzzyDecision )this[ nLosingNumber ];
		}

		/// <summary>
		/// Add an unnamed Fuzzy Decision to the set
		/// </summary>
		public void AddDecision()
		{
			Add( new FuzzyDecision() );
		}

		/// <summary>
		/// Add a named Fuzzy Decision to the set
		/// </summary>
		/// <param name="name">name of the new decision</param>
		public void AddDecision( string name )
		{
			Add( new FuzzyDecision( name ) );
		}	

		/// <summary>
		/// Add a named Fuzzy Decision to the set and indicate if it is valid
		/// </summary>
		/// <param name="name">name of the new decision</param>
		/// <param name="isValid">is the decision valid?</param>
		public void AddDecision( string name, bool isValid )
		{
			FuzzyDecision temp = new FuzzyDecision( name );
			temp.IsValid = isValid;
			Add( temp );
		}

		/// <summary>
		/// Add a new Fuzzy Decision
		/// </summary>
		/// <param name="decision">Fuzzy Decision to be added</param>
		public void AddDecision( FuzzyDecision decision )
		{
			Add( decision );
		}

		/// <summary>
		/// Increment the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">index of the decision in the array</param>
		/// <returns>true if done ( probably never checked )</returns>
		public bool IncrementAt( int index )
		{
			if( index < Count )
			{
				( ( FuzzyDecision )this[ index ] ).Number++;
				return true;
			}
			else 
				return false;
		}

		/// <summary>
		/// Increment the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision to be incremented</param>
		/// <returns>true if done</returns>
		public bool IncrementByName( string name )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					( ( FuzzyDecision )this[ i ] ).Number++;
					bDone = true;
					i=Count;
				}
			}

			return bDone;
		}

		/// <summary>
		/// decrement the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">the index for the decision</param>
		/// <returns>true if done</returns>
		public bool DecrementAt( int index )
		{
			if( index < Count )
			{
				( ( FuzzyDecision )this[ index ] ).Number--;
				return true;
			}
			else 
				return false;
		}

		/// <summary>
		/// decrement the Fuzzy decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <returns>true if done</returns>
		public bool DecrementByName( string name )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					( ( FuzzyDecision )this[ i ] ).Number--;
					bDone = true;
					i=Count;
				}
			}

			return bDone;
		}

		/// <summary>
		/// Add the number to the Fuzzy Decision at the index
		/// </summary>
		/// <param name="index">index of the decision</param>
		/// <param name="number">number to be added</param>
		/// <returns>true if done</returns>
		public bool AddAt( int index, int number )
		{
			if( index < Count )
			{
				( ( FuzzyDecision )this[ index ] ).Number += number;
				return true;
			}
			else
				return false;
		}

		/// <summary>
		/// Add the number to the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <param name="number">number to be added</param>
		/// <returns>true if done</returns>
		public bool AddByName( string name, int number )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					( ( FuzzyDecision )this[ i ] ).Number += number;
					bDone = true;
					i=Count;
				}
			}

			return bDone;
		}

		/// <summary>
		/// Subtract the number from the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">index of the decision</param>
		/// <param name="number">number to be subtracted</param>
		/// <returns>true if done</returns>
		public bool SubtractAt( int index, int number )
		{
			if( index < Count )
			{
				( ( FuzzyDecision )this[ index ] ).Number -= number;
				return true;
			}
			else
				return false;
		}

		/// <summary>
		/// Subtract the number from the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <param name="number">number to be subtracted</param>
		/// <returns>true if done</returns>
		public bool SubtractByName( string name, int number )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					( ( FuzzyDecision )this[ i ] ).Number -= number;
					bDone = true;
					i=Count;
				}
			}

			return bDone;
		}


		/// <summary>
		/// Zero the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">index of the decision</param>
		/// <returns>true if done</returns>
		public bool ZeroNumberAt( int index )
		{
			if( index < Count )
			{
				( ( FuzzyDecision )this[ index ] ).Number = 0;
				return true;
			}
			else
				return false;
		}

		/// <summary>
		/// Zero the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <returns>true if done</returns>
		public bool ZeroNumberByName( string name )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					( ( FuzzyDecision )this[ i ] ).Number = 0;
					bDone = true;
					i=Count;
				}
			}

			return bDone;
		}

		/// <summary>
		/// Compare the Fuzzy Decisions in the array and return the winner
		/// </summary>
		/// <returns>the decision with the highest value</returns>
		public FuzzyDecision Compare()
		{
			FuzzyDecision decision = null;

			if( Count > 1 )
			{
				for( int i=1; i<Count; i++ )
				{
					if( decision == null )
					{
						decision = ( ( FuzzyDecision )this[ i-1 ] ).Compare( ( FuzzyDecision )this[ i ] );
					}
					else
					{
						decision = decision.Compare( ( FuzzyDecision )this[ i ] );
					}
				}
			}

			return decision;
		}	
		
		/// <summary>
		/// Set the Fuzzy Decision at the given index to valid or not
		/// </summary>
		/// <param name="index">index of the decision</param>
		/// <param name="valid">set true or false</param>
		/// <returns>true if done</returns>
		public bool IsValidAt( int index, bool valid )
		{
			if( index < Count )
			{
				( ( FuzzyDecision )this[ index ] ).IsValid = valid;
				return true;
			}
			else
				return false;
		}

		/// <summary>
		/// Set the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <param name="valid">set true or false</param>
		/// <returns>true if done</returns>
		public bool SetIsValidByName( string name, bool valid )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					( ( FuzzyDecision )this[ i ] ).IsValid = valid;
					bDone = true;
					i=Count;
				}
			}

			return bDone;
		}

		/// <summary>
		/// get the Fuzzy Decision's valid parameter with the given name 
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <returns>true or false</returns>
		public bool IsValidByName( string name )
		{
			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					return ( ( FuzzyDecision )this[ i ] ).IsValid;
				}
			}

			return false;
		}

		/// <summary>
		/// Get the valid status of the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">index of the decision</param>
		/// <returns>true if valid</returns>
		public bool GetValidAt( int index )
		{
			if( index < Count )
			{
				return ( ( FuzzyDecision )this[ index ] ).IsValid;
			}
			else
				return false;
		}

		/// <summary>
		/// Get the valid status of the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <returns>true if valid</returns>
		public bool GetValidByName( string name )
		{
			bool bDone = false;

			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					return ( ( FuzzyDecision )this[ i ] ).IsValid;
				}
			}

			return bDone;
		}

		/// <summary>
		/// Get the number of the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">index of hte decision</param>
		/// <returns>the number of the decision at the index</returns>
		public int GetNumberAt( int index )
		{
			if( index < Count )
			{
				return ( int )( ( FuzzyDecision )this[ index ] ).Number;
			}
			else
				return 0;
		}

		/// <summary>
		/// Get the number of the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <returns>the number of the decision with the given name</returns>
		public int GetNumberByName( string name )
		{
			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					return ( int )( ( FuzzyDecision )this[ i ] ).Number;
				}
			}

			return 0;
		}

		/// <summary>
		/// Gets the Fuzzy Decision at the given index
		/// </summary>
		/// <param name="index">index of the decision</param>
		/// <returns>decision at the given index</returns>
		public FuzzyDecision GetDecisionAt( int index )
		{
			if( index < Count )
			{
				return ( FuzzyDecision )this[ index ];
			}
			else 
				return null;
		}

		/// <summary>
		/// Gets the Fuzzy Decision with the given name
		/// </summary>
		/// <param name="name">name of the decision</param>
		/// <returns>decision with the given name</returns>
		public FuzzyDecision GetDecisionByName( string name )
		{
			for( int i=0; i<Count; i++ )
			{
				if( name == ( ( FuzzyDecision )this[ i ] ).Name )
				{
					return ( FuzzyDecision )this[ i ];
				}
			}

			return null;
		}

		/// Saving and Loading
		/// 

		public virtual void Save( XmlWriter xmlWriter )
		{
			xmlWriter.WriteStartElement( "FuzzyDecisionSet" );
			xmlWriter.WriteElementString( "Name", Name );
			for( int i=0; i<Count; i++ )
			{
				( ( FuzzyDecision )this[ i ] ).Save( xmlWriter );
			}
			xmlWriter.WriteEndElement();
		}


		public virtual void Load( XmlReader xmlReader )
		{
			while( xmlReader.Name != "Name" )
			{
				xmlReader.Read();
				if( xmlReader.EOF == true )
					return;
			}

			xmlReader.Read();
			Name = xmlReader.Value;

			bool bBreak = false;
			for( ;; )
			{
				xmlReader.Read();
				if( xmlReader.EOF == true )
					return;
				switch( xmlReader.NodeType )
				{
					case XmlNodeType.Element:
					{
						switch( xmlReader.Name )
						{
							case "FuzzyDecision":
							{
								FuzzyDecision temp = new FuzzyDecision();
								temp.Load( xmlReader );
								AddDecision( temp );
								break;
							}
							default: bBreak = true; break;
						}
					} break;
					case XmlNodeType.EndElement:
					{
						switch( xmlReader.Name )
						{
							case "FuzzyDecisionSet" : bBreak = true; break;
						}
					} break;
				}

				if( bBreak == true )
					break;
			}
		}

		/// comparison stuff
		/// 

		public static bool operator ==( FuzzyDecisionSet setOne, FuzzyDecisionSet setTwo )
		{
			bool bOneIsNull = false;
			bool bBothAreNull = false;

			try
			{
				int nTemp = setOne.Count;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				bOneIsNull = true;
			}

			try
			{
				int nTemp = setTwo.Count;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				if( bOneIsNull == true )
				{
					bBothAreNull = true;
				}
				else
					bOneIsNull = true;
			}


			if( bOneIsNull == true )
				return false;

			if( bBothAreNull == true )
				return true;

			if( setOne.Name != setTwo.Name )
				return false;

			if( setOne.Count != setTwo.Count )
				return false;

			bool bAllEqual = true;
			for( int i=0; i<setOne.Count; i++ )
			{
				if( ( FuzzyDecision )setOne[ i ] != ( FuzzyDecision )setTwo[ i ] )
					bAllEqual = false;
			}

			if( bAllEqual == true )
				return true;

			return false;
		}

		public static bool operator !=( FuzzyDecisionSet setOne, FuzzyDecisionSet setTwo )
		{
			bool bOneIsNull = false;
			bool bBothAreNull = false;

			try
			{
				int nTemp = setOne.Count;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				bOneIsNull = true;
			}

			try
			{
				int nTemp = setTwo.Count;
			}
			catch( NullReferenceException nullRefExp )
			{
				string strTemp = nullRefExp.Message;

				if( bOneIsNull == true )
				{
					bBothAreNull = true;
				}
				else
					bOneIsNull = true;
			}

			if( bOneIsNull == true )
				return true;
		
			if( bBothAreNull == true )
				return false;

			if( setOne.Name != setTwo.Name )
				return true;

			if( setOne.Count != setTwo.Count )
				return true;

			bool bAllNotEqual = true;
			for( int i=0; i<setOne.Count; i++ )
			{
				if( ( FuzzyDecision )setOne[ i ] == ( FuzzyDecision )setTwo[ i ] )
					bAllNotEqual = false;
			}

			if( bAllNotEqual == true )
				return true;

			return false;
		}

		/// required overrides
		/// 
		
		public override bool Equals(object obj)
		{
			if( obj == null || GetType() != obj.GetType() )
				return false;

			FuzzyDecisionSet temp = ( FuzzyDecisionSet )obj;

			return this == temp;
		}

		public override int GetHashCode()
		{
			return this.GetHashCode() ^ this.Name.GetHashCode();
		}

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions