Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / C#

Fuzzy Logic Vs Adaline Neural Network

Rate me:
Please Sign up or sign in to vote.
4.30/5 (8 votes)
29 Oct 20038 min read 91.7K   1.6K   33  
An experiment to see if it possible to duplicate the behavior of the Adaline Network using Fuzzy Logic.
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;
			}
		}

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

		private FuzzyDecision( FuzzyDecision decision )
		{
			this.Number = decision.Number;
			this.Name = decision.Name;
			this.bIsValidNumber = decision.IsValid;
		}

		public FuzzyDecision( string strName )
		{
			bIsValidNumber = false;
			this.Name = strName;
		}

		public void IncrementDecision()
		{
			this.Number++;
		}

		public void DecrementDecision()
		{
			this.Number--;
		}

		public void AddToDecision( int nNumber )
		{
			this.Number += nNumber;
		}

		public void SubtractFromDecision( int nNumber )
		{
			this.Number -= nNumber;
		}

		public FuzzyDecision Compare( 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 )
			{
				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( decision );
		}
	}


	/// <summary>
	/// FuzzyDecider class helps in the decision making process and remembers 
	/// previous decisions which are stored in an xml file which has the format
	/// </summary>
	/* <decision>
	 *  <Decision> ... </Decision>
	 *  <NumberOfTimesDecided> ... </NumberOfTimesDecided>
	 *  <NumberOfTimesThisDecisionReached> ... </NumberOfTimeThisDecisionReached>
	 *	<PossibleDecisions>
	 *		<Decision1> 
	 *			<DecisionName> ... </DecisionName>
	 *			<NumberOfTimesDecisionReached> ... </NumberOfTimesDecisionReached>
	 *			<IsAValidDecision> ... </IsAValidDecision>
	 *		</Decision1>
	 *		<Decision2> 
	 *			...
	 *		</Decision2>
	 *		...
	 *	</PossibleDecisions>
	 * 
	 *	Subject to change
	 */
	public class FuzzyDecider : FuzzyBasic
	{
		private class DecisionData
		{
			private string strDecisionName;
			private int nNumberOfTimesDecisionReached;
			private bool bIsValidDecision;
			private bool bIsThisDecision;

			public string DecisionName
			{
				get
				{
					return strDecisionName;
				}
				set
				{
					strDecisionName = value;
				}
			}

			public int NumberOfTimesDecisionReached
			{
				get
				{
					return nNumberOfTimesDecisionReached;
				}
				set
				{
					nNumberOfTimesDecisionReached = value;
				}
			}

			public bool IsValidDecision
			{
				get
				{
					return bIsValidDecision;
				}
				set
				{
					bIsValidDecision = value;
				}
			}

			public bool IsThisDecision
			{
				get
				{
					return bIsThisDecision;
				}
				set
				{
					bIsThisDecision = value;
				}
			}

			public DecisionData()
			{
				strDecisionName = "";
				nNumberOfTimesDecisionReached = 0;
				bIsValidDecision = false;
				bIsThisDecision = false;
			}
		}

		/// <summary>
		/// the name of the decider ie "BasicAntAlgorythmDecisions"
		/// </summary>
		private string strDeciderName;
		/// <summary>
		/// name of the last decision
		/// </summary>
		private string strDecidedName;
		private int nNumberOfTimesDecided;
		private bool bisValidDecision;
		private int nNumberOfTimesDecisionReached;
		private ArrayList decisionsArray; 
		private string strError;
		private bool bIsError;
		private bool bHasDecided;

		public string DeciderName
		{
			get
			{
				return strDeciderName;
			}
			set
			{
				strDeciderName = value;
			}
		}

		public string DecidedName
		{
			get
			{
				return strDecidedName;
			}
			set
			{
				strDecidedName = value;
			}
		}

		public string Error
		{
			get
			{
				return strError;
			}
			set
			{
				strError = value;
			}
		}

		public bool IsError
		{
			get
			{
				return bIsError;
			}
		}

		public bool HasDecided
		{
			get
			{
				return bHasDecided;
			}
			set
			{
				bHasDecided = value;
			}
		}



		public FuzzyDecider( string deciderName )
		{
			strDeciderName = deciderName;
			decisionsArray = new ArrayList();
			nNumberOfTimesDecided = 0;

			decisionsArray = new ArrayList();

		    strDecidedName = "";
			bisValidDecision = false;
			nNumberOfTimesDecisionReached = 0;
			bHasDecided = true;
		}


		/// <summary>
		/// read the xml file into the reader and set up the array
		/// </summary>
		/// <returns></returns>
		private bool ReadXmlFile()
		{
			bIsError = false;
			string strValue;
			FuzzyDeciderReaderWriter reader = new FuzzyDeciderReaderWriter( DeciderName );
			if( reader.IsError == true )
				bIsError = true;

			if( bIsError == false )
			{
				/// this will throw an exception if the file doesn't exist
				/// that will be caught by the function and set bIsError to true
				bIsError = reader.OpenFileForReading();
			}

			if( bIsError == false )
			{
				bIsError = reader.ReadXmlElement( "Decision", out strValue );
				this.strDecidedName = strValue;
			}

			if( bIsError == false )
			{
				bIsError = reader.ReadXmlElement( "NumberOfTimesDecided", out strValue );
				try
				{
					this.nNumberOfTimesDecided = Int32.Parse( strValue );
				}
				catch( ArgumentNullException argNullExp )
				{
					strError = "Error Argument Null Exception thrown converting the answer for NumberOfTimesDecided, reason :- " + argNullExp.Message;
					bIsError = true;
				}
				catch( FormatException formExp )
				{
					strError = "Error Format Exception thrown converting the answer for NumberOfTimesDecided, reason :- " + formExp.Message;
					bIsError = true;
				}
				catch( OverflowException overFExp )
				{
					strError = "Error Over Flow Exception thrown converting the answer for NumberOfTimesDecided, reason :- " + overFExp.Message;
					bIsError = true;
				}
			}

			if( bIsError == false )
			{
				bIsError = reader.ReadXmlElement( "NumberOfTimesThisDecisionReached", out strValue );
				try
				{
					this.nNumberOfTimesDecisionReached = Int32.Parse( strValue );
				}
				catch( ArgumentNullException argNullExp )
				{
					strError = "Error Argument Null Exception thrown converting the answer for NumberOfTimesDecisionReached, reason :- " + argNullExp.Message;
					bIsError = true;
				}
				catch( FormatException formExp )
				{
					strError = "Error Format Exception thrown converting the answer for NumberOfTimesDecisionReached, reason :- " + formExp.Message;
					bIsError = true;
				}
				catch( OverflowException overFExp )
				{
					strError = "Error Over Flow Exception thrown converting the answer for NumberOfTimesDecisionReached, reason :- " + overFExp.Message;
					bIsError = true;
				}
			}

			int nCount = 0;
			if( bIsError == false )
			{
				bIsError = reader.GetDecisionCount( out nCount );
			}

			for( int i=0; i<nCount; i++ )
			{
				DecisionData data = new DecisionData();

				if( bIsError == false )
				{
					bIsError = reader.ReadXmlElement( "DecisionName", out strValue );
					data.DecisionName = strValue;
				}

				if( bIsError == false )
				{
					bIsError = reader.ReadXmlElement( "NumberOfTimesDecisionReached", out strValue );
					try
					{
						data.NumberOfTimesDecisionReached = Int32.Parse( strValue );
					}
					catch( ArgumentNullException argNullExp )
					{
						strError = "Error Argument Null Exception thrown converting the answer for NumberOfTimesDecisionReached, reason :- " + argNullExp.Message;
						bIsError = true;
					}
					catch( FormatException formExp )
					{
						strError = "Error Format Exception thrown converting the answer for NumberOfTimesDecisionReached, reason :- " + formExp.Message;
						bIsError = true;
					}
					catch( OverflowException overFExp )
					{
						strError = "Error Over Flow Exception thrown converting the answer for NumberOfTimesDecisionReached, reason :- " + overFExp.Message;
						bIsError = true;
					}
				}

				if( bIsError == false )
				{
					bIsError = reader.ReadXmlElement( "IsValidDecision", out strValue );
					if( strValue == null || strValue.Length == 0 && bIsError == false )
						bIsError = true;

					if( bIsError == false )
					{
						if( strValue == "true" )
							data.IsValidDecision = true;
						else
							data.IsValidDecision = false;
					}
				}

				decisionsArray.Add( data );
			}

			if( bIsError == false )
				reader.CloseReader();

			if( bIsError == true )
			{
				strError = reader.Error;
			}


			return bIsError == false? true: false;
		}


		/// <summary>
		/// make a slightly more informed decision about something
		/// </summary>
		/// <param name="decisions"></param>
		/// <returns>A FuzzyDecision or null which will have iserror set to true and error string returnable by error</returns>
		public FuzzyDecision Decide( ArrayList decisions )
		{
			bool bDoesFileExist = false;
			FuzzyDecision returnDecision = null;

			if( decisions == null || decisions.Count == 0 )
				return null;

			/// load the decisions array if any
			/// if the file exists the decisions array is filled from the file
			if( ReadXmlFile() == true )
			{
				/// do nothing for now
				bDoesFileExist = true;
			}

			/// if it's the first time making this decision just decide normally
			if( bDoesFileExist == false )
			{
				for( int i=0; i<decisions.Count; i++ )
				{
					DecisionData data = new DecisionData();

					data.DecisionName = ( ( FuzzyDecision )decisions[ i ] ).Name;
					data.IsValidDecision = ( ( FuzzyDecision )decisions[ i ] ).IsValid;

					decisionsArray.Add( data );
				}


				/// just returns the last valid one as the decision
				for( int i=0; i<decisions.Count; i++ )
				{
					if( ( ( FuzzyDecision )decisions[ i ] ).IsValid == true )
					{
						returnDecision = ( FuzzyDecision )decisions[ i ];
					}
				}

				/// write out the file
				
				FuzzyDeciderReaderWriter writer = new FuzzyDeciderReaderWriter( strDeciderName );

				/// false is no error
				if( writer.OpenFileForWriting( false ) == false )
				{
					bool bError = false;
			///		bError = writer.StartXmlDocument();

					if( bError == false )
					{
						bError = writer.StartXmlSection( strDeciderName );
					}

					if( bError == false )
					{
						bError = writer.WriteXmlElement( "Decision", returnDecision.Name );
					}

					if( bError == false )
					{
						bError = writer.WriteXmlElement( "NumberOfTimesDecided", "1" );
					}

					if( bError == false )
					{
						bError = writer.WriteXmlElement( "NumberOfTimesThisDecisionReached", "1" );
					}

					if( bError == false )
					{
						bError = writer.StartXmlSection( "PossibleDecisions" );
					}

					for( int i=0; i<decisionsArray.Count; i++ )
					{

						if( bError == false )
						{
							bError = writer.StartXmlSection( ( ( DecisionData )decisionsArray[ i ] ).DecisionName );
						}


						if( bError == false )
						{
							bError = writer.WriteXmlElement( "DecisionName", ( ( DecisionData )decisionsArray[ i ] ).DecisionName );
						}

						if( bError == false )
						{
							if( returnDecision.Name == ( ( DecisionData )decisionsArray[ i ] ).DecisionName )
							{
								bError = writer.WriteXmlElement( "NumberOfTimesDecisionReached", "1" );
							}
							else
							{
								bError = writer.WriteXmlElement( "NumberOfTimesDecisionReached", "0" );
							}
						}

						if( bError == false )
						{
							if( ( ( DecisionData )decisionsArray[ i ] ).IsValidDecision == true )
							{
								bError = writer.WriteXmlElement( "IsValidDecision", "true" );
							}
							else
							{
								bError = writer.WriteXmlElement( "IsValidDecision", "false" );
							}
						}

						if( bError == false )
						{
							bError = writer.EndXmlSection();
						}

					}

					if( bError == false )
					{
						bError = writer.EndXmlSection();
					}

					if( bError == false )
					{
						bError = writer.EndXmlDocument();
					}

					if( bError == true )
					{
						strError = writer.Error;
						bIsError = writer.IsError;
						returnDecision = null;
					}

					writer.CloseWriter();

				}
				else 
				{
					strError = writer.Error;
					bIsError = writer.IsError;
					return returnDecision;
				}
				
			}
			else
			{
				/// work out which it's going to be
				for( int i=0; i<decisions.Count; i++ )
				{
					if( ( ( FuzzyDecision )decisions[ i ] ).IsValid == true )
					{
						/// see if the decision was chosen last time this option was decided on
						/// and don't allow it for this time
						for( int n=0; n<decisionsArray.Count; n++ )
						{
							if( ( ( DecisionData )decisionsArray[ n ] ).DecisionName == ( ( FuzzyDecision )decisions[ i ] ).Name )
							{
								if( DecidedName == ( ( FuzzyDecision )decisions[ i ] ).Name )
								{
									( ( DecisionData )decisionsArray[ n ] ).IsValidDecision = false;
								}
								else /// if a decision is valid in the decision array make it valid here
								{
									( ( DecisionData )decisionsArray[ n ] ).IsValidDecision = true;
								}
							} 

						}
					}
				}

				/// there still could be more than one decision to choose from so for
				/// now choose the less chosen decision
				
				for( int n=0; n<decisionsArray.Count; n++ )
				{
					/// only check valid decisions
					if( ( ( DecisionData )decisionsArray[ n ] ).IsValidDecision == true )
					{
						/// loop through the decisions
						for( int j=0; j<decisionsArray.Count; j++ )
						{
							/// find a different decision that is valid and not the same decision
							if( ( ( DecisionData )decisionsArray[ j ] ).IsValidDecision == true )
							{
								/// if the current decision has been reached more than the comparing decision
								/// use the comparing decision as the final decision
								/// or alternatively in english choose the least chosen decision
								if( ( ( DecisionData )decisionsArray[ n ] ).NumberOfTimesDecisionReached >= ( ( DecisionData )decisionsArray[ j ] ).NumberOfTimesDecisionReached )
								{
									/// now find the decision to be returned and save it as the return decision
									for( int k=0; k<decisions.Count; k++ )
									{
										if( ( ( FuzzyDecision )decisions[ k ] ).Name == ( ( DecisionData )decisionsArray[ n ] ).DecisionName )
										{
											returnDecision = ( FuzzyDecision )decisions[ k ];

											/// save the data for the file
											DecidedName = ( ( FuzzyDecision )decisions[ k ] ).Name;
											this.nNumberOfTimesDecisionReached = ( ( DecisionData )decisionsArray[ n ] ).NumberOfTimesDecisionReached + 1;
											this.bisValidDecision = true;
											this.nNumberOfTimesDecided++;

										}
									}
								}
							}
						}
					}
				}

				/// save the decision data 
				FuzzyDeciderReaderWriter writer = new FuzzyDeciderReaderWriter( strDeciderName );

				if( writer.OpenFileForWriting( false ) == false )
				{
					bool bError = false;
					///					bError = writer.StartXmlDocument();

					if( bError == false )
					{
						bError = writer.StartXmlSection( strDeciderName );
					}

					if( bError == false )
					{
						bError = writer.WriteXmlElement( "DecisionName", DecidedName );
					}

					if( bError == false )
					{
						bError = writer.WriteXmlElement( "NumberOfTimesDecided", ( ( Int32 )this.nNumberOfTimesDecided + 1 ).ToString() );
					}

					if( bError == false )
					{
						bError = writer.WriteXmlElement( "NumberOfTimesThisDecisionReached", this.nNumberOfTimesDecisionReached.ToString() );
					}

					if( bError == false )
					{
						bError = writer.StartXmlSection( "PossibleDecisions" );
					}

					for( int j=0; j<decisionsArray.Count; j++ )
					{

						if( bError == false )
						{
							bError = writer.StartXmlSection( ( ( DecisionData )decisionsArray[ j ] ).DecisionName );
						}

						if( bError == false )
						{
							bError = writer.WriteXmlElement( "Decision", ( ( DecisionData )decisionsArray[ j ] ).DecisionName );
						}

						if( bError == false )
						{
							if( DecidedName == ( ( DecisionData )decisionsArray[ j ] ).DecisionName )
							{
								int nTemp = ( ( DecisionData )decisionsArray[ j ] ).NumberOfTimesDecisionReached + 1;
								bError = writer.WriteXmlElement( "NumberOfTimesDecisionReached", nTemp.ToString() );
							}
							else
								bError = writer.WriteXmlElement( "NumberOfTimesDecisionReached", ( ( DecisionData )decisionsArray[ j ] ).NumberOfTimesDecisionReached.ToString() );
						}

						if( bError == false )
						{
							bError = writer.WriteXmlElement( "IsValidDecision", ( ( DecisionData )decisionsArray[ j ] ).IsValidDecision.ToString() );
						}

						if( bError == false )
						{
							bError = writer.EndXmlSection();
						}

					}


					if( bError == false )
					{
						bError = writer.EndXmlSection();
					}

					if( bError == false )
					{
						bError = writer.EndXmlDocument();
					}

					if( bError == true )
					{
						strError = writer.Error;
						bIsError = writer.IsError;
						return null;
					}

					HasDecided = true;
					writer.CloseWriter();	
				}

			}

			return returnDecision;
		}

	}
}

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