|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.