i National Ribat University Faculty of Graduate Studies & Scientific Research Database Hiding in Tag Web Using Steganography by Genetic Algorithm Thesis Submitted for Fulfilling of the Requirements of Ph.D. in Computer Science By : Fatma Abdalla Mabrouk Supervisor: Prof. Mudawi Mukhtar Elmusharaf 1438-2017
152
Embed
Database Hiding in Tag Web Using Steganography by Genetic Algorithmrepository.ribat.edu.sd/public/uploads/upload/repository... · 2017-04-10 · i National Ribat University Faculty
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
i
National Ribat University
Faculty of Graduate Studies & Scientific Research
Database Hiding in Tag Web Using Steganography by
Genetic Algorithm
Thesis Submitted for Fulfilling of the Requirements of
Ph.D. in Computer Science
By : Fatma Abdalla Mabrouk
Supervisor: Prof. Mudawi Mukhtar Elmusharaf
1438-2017
ii
تهاللـــسا
حم بسم للاه حيم الره ن الره
ان ك ل عل لهمت نق الوا سبح ا ع كيم(ا إنهك أ نت الع ليم م ل ن ا إله م الح )
صدق للا العظيم
(32) سورة البقرة اآلية
iii
DEDICATION
To my big family, and my small family for their continuous support and
encouragement
iv
ACKNOWLEDGEMENTS
First of all, thanks almighty god for blessing me more than I deserve, and
granting me the strength and perseverance to complete this search and present it in such
a satisfactory manner.
I would like to express my sincere gratitude to my supervisor Prof. Dr. Mudawi
Mukhtar Elmusharaf first for accepting the supervision of this thesis and second for his
patience, continuous support, motivation and immense knowledge. His guidance helped
me a lot during research time and writing of this thesis.
Also, the completion of this project could not have been accomplished without
the support of my friends Muna Ahmed Alsadig and Imtesal Ali Yasin.
I would like to thank my family for their love and encouragement: my mother
her continuous prayer has always supported me and gave me the strength to keep on
struggling, and to my brothers especially my brother Osama, for his spiritual support
throughout this thesis and in my life as a whole, and to my sisters especially Amal, the
first person who supported me to complete my proposal, thank you for giving me all this
time. And my uncle Salah Mabrouk without him this thesis couldn’t have seen the light.
A special thanks to my dear husband Amir Osman his patience and support
helped me to complete my work.
Last but not least, to the soul of my dear father who raised inside me the love of
science and always supported me during his life and death, my heartfelt thanks.
v
ABSTRACT
The main goal of this research is to study steganography technique by GA and to
design new system known as (SteganoTag), it is one of the new methods of
steganography information through hiding database within the saved web pages by
using genetic algorithm, without changing the page size, to increase the reliability and
confidentiality of the data base system. A sample of database that is designed in XML
language has been selected.
The main sector of this research is the application of genetic algorithm as a
method of data security, it is applied in the field of evolutionary programming in
artificial intelligence, as the experimental method is used in the analysis of different
types of home pages, these proposed technical HTML tags and its attributes are applied
to hide illogical database using the genetic algorithm. This proposed technique
considers labels as genes and characteristics as chromosomes. Then the architecture has
been detailed and the implementation of the proposed system of hiding information
using the software program C # and the system has been simulated using different
scenarios and a variety of data. The good side of using steganography with a genetic
algorithm has been clarified.
Finally, the most important findings in this research is that the combination
between the science of genetic algorithm and steganography raising the efficiency of the
process of masking data in a web page without changing its parameters, and the
encryption algorithm enhances the complexity of illegal attempts of steganography
removal. Genetic algorithm has the ability to achieve a significant improvement in data
security following the same methodology, this collection can be extended to involve the
development of other security systems to get safer and reliable systems of database
hiding. The high flexibility of HTML can be applied in many other techniques, other
non-public languages can be used in the process of database hiding and exploitation of
the Internet protocols, and the development of this method by introducing
developmental algorithms to increase the efficiency of data hiding. The development of
e-mail data process can also be hidden.
vi
المستخلص
دراسة تقنية إخفاء المعلومات بواسطة الخوارزمية الجينية، ومن ثم الهدف من هذا البحث
إخفاء المعلومات من خالل إخفاء قاعدة كأحد الطرق الجديدة في (SteganoTag)نظام تصميم
بيانات داخل صفحة االنترنت المحفوظة باستخدام الخوارزمية الجينية دون تغيير حجم الصفحة
. XMLلزيادة موثوقية وسرية نظام قاعدة البيانات. سيتم أخذ عينة من قاعدة البيانات المصمم بلغة
الجينية كأسلوب أمن للبيانات، ويتم النطاق الرئيسي في هذا البحث تطبيق الخوارزمية
يستخدم المنهج التجريبي استخدامها في مجال البرمجة التطورية في الذكاء االصطناعي، كما انه
HTMLفي تحليل أنواع مختلفة من الصفحات الرئيسية، تستخدم هذه التقنية المقترحة عالمات
وارزمية الجينية. وتعتبر هذه التقنية باستخدام الخ ةوصفاتها إلخفاء قاعدة بيانات غير منطقي
المقترحة أن أي عالمة تمثل الجينات وتمثل أي صفة كروموسوم.
#Cالهندسة المعمارية وتنفيذ نظام إخفاء المعلومات المقترح باستخدام برنامج تم تصميم
يد من ومحاكاة النظام باستخدام سيناريوهات مختلفة ومجموعة بيانات متنوعة. وتوضح الجانب الج
استخدام إخفاء المعلومات مع الخوارزمية الجينية.
هذا البحث أن الجمع بين علم االخفاء وخوارزمية الجينية يحسن من ئجنتامن اهم أخيرا،
من تعقيد ةعملية اخفاء البيانات في صفحة ويب دون تغيير معالمه، ان خوارزميه التشفير عزز
ا. الخوارزمية الجينية لها القدرة على تحقيق تحسن كبير محاوالت إزالة اإلخفاء الغير مسموح به
متد إلى تطوير أنظمة األمان يس المنهجية، هذا المزيج يمكن أن على أمن البيانات وباتباع نف
استغالل المرونة بها. يمكن يةوموثوق ا إلخفاء قواعد البيانات أكثر آمن األخرى للحصول على أنظمة
ر من التقنيات األخرى، كما يمكن استخدام لغات أخرى غير شائعة في في كثي HTMLالعالية للغة
عملية إخفاء قواعد البيانات. استغالل بروتوكوالت شبكة االنترنت في عملية إخفاء قواعد البيانات،
وتطوير هذه الطريقة بإدخال الخوارزميات التطويرية لزيادة كفاءة إخفاء البيانات. كما يمكن تطوير
بيانات البريد اإللكتروني.االخفاء لل
vii
CONTENT
TITLE PAGE…………….…………………………………………………………. i
ii .....……….……………………………………………………………………استهالل
DEDICATION …………………...………………………………………………… iii
ACKNOWLEDGEMENTS ……...…………………………………….................... iv
ABSTRACT…………………………………………………………....................... v
vi ..................................………………………………………………………المستخلص
CONTENT ………………………………………….….…………………….......... vii
LIST OF TABLES ……………………………….………………………….….…. x
LIST OF FIGURES ………………………………….……………………............. xi
LIST OF ABBREVIATION ………………………….……………………............ xiii
LIST OF SYMBOLS …………………………….……….……………………...... xv
CHAPTER
CHAPTER1: INTRODUCTION……………………………………………….… 1
1.1 Problem Background ………………………………………………………. 1
1.2 Motivation ….…………………………...……………………………….…. 4
1.3 Research Problem…………………………………………………………... 4
1.4 Research Objectives …………………………………….……………....…. 5
1.5 Research Questions ………………………...………………………….…… 6
1.6 Research Scope…...………………………………………………………… 6
1.7 Research Methodology and Activities……………………………………… 6
1.8 Glossary of Research Terms………………………………...…….….….…. 8
1.9 Structure of Thesis…………………………………...……………….….…. 10
1.10 Chapter Summary………………………………………………………. …. 10
CHAPTER 2: LITERATURE REVIEW AND PREVIOUS STUDIES………. 11
2.1 Introduction.………………………………………………………………… 11
2.2 Literature Review.…………………………………………………….….…. 11
2.2.1 The Security On the Internet Environment …….….……………… 11
2.2.2 Security and Steganography………………………………….….... 12
2.2.3 Data Hiding Techniques…………………………………………... 14
2.2.4 Comparative Between Cryptography and Steganography………… 16
viii
2.2.5 The Fundamental Requirements When Hiding Data in Data ….…. 17
2.2.6 Method of Hiding Data……………………………………....….… 17
2.2.7 Steganography in Digital Age………………………………….…. 18
2.2.8 The Steganography Approaches ………………………………...... 19
2.2.9 Types of Steganography…………………………………………... 20
2.2.10 Different Types of Media That Hide Data in Steganographic Techniques 22
2.2.11 Techniques of Steganography On Network…………….….……… 23
%%%%%%%%%%%%%%%%%%%%%%%%%%%% class Encrypt %%%%%%%%%%%%%%%%%% using System; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; namespace creatdatxml { public static class Encrypt { // This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array. private const string initVector = "pemgail9uzpgzl88"; // This constant is used to determine the keysize of the encryption algorithm. private const int keysize = 256; //Encrypt public static string EncryptString(string plainText, string passPhrase) { byte[] initVectorBytes = Encoding.Default.GetBytes(initVector); byte[] plainTextBytes = Encoding.Default.GetBytes(plainText); PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null); byte[] keyBytes = password.GetBytes(keysize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes); MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); byte[] cipherTextBytes = memoryStream.ToArray(); memoryStream.Close(); cryptoStream.Close(); return Convert.ToBase64String(cipherTextBytes); } //Decrypt public static string DecryptString(string cipherText, string passPhrase) { byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] cipherTextBytes = Convert.FromBase64String(cipherText); PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null); byte[] keyBytes = password.GetBytes(keysize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes); MemoryStream memoryStream = new MemoryStream(cipherTextBytes); CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
102
byte[] plainTextBytes = new byte[cipherTextBytes.Length]; int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); memoryStream.Close(); cryptoStream.Close(); return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); } } }
%%%%%%%%%%%%%%%%%%%%%%%%%%% class HtmlUtility %%%%%%%%%%%%%%%%%%
#region Using directives using System; using System.IO; using System.Data; using System.Text; using System.Collections; using System.Collections.Specialized; using System.Runtime.InteropServices; using GeneticAlgorithms; #endregion namespace stegeneticweb { public class HtmlUtility : GeneticAlgorithms.GenomeCollection { public HtmlUtility() { } /// <summary>Counts the key attribute couples in an HTML document</summary> /// <param name="sourceFileName">Path and name of the HTML document</param> /// <param name="keyTable">DataTable with the key attributes</param> /// <returns>Count of bytes that can be hidden in the specified document</returns> public int GetCapacity(String sourceFileName, DataTable keyTable) { int countCarrierCouples = 0; StreamReader reader = new StreamReader(sourceFileName, Encoding.Default); String htmlDocument = reader.ReadToEnd(); reader.Close(); HtmlTagCollection tags = FindTags(htmlDocument); StringBuilder insertTextBuilder = new StringBuilder(); DataRow[] rows; HtmlAttribute secondAttribute; foreach (HtmlTag tag in tags) { foreach (HtmlAttribute attribute in tag.Attributes) { if (!attribute.Handled)
103
{ rows = keyTable.Select("firstAttribute = '" + attribute.Name.Replace("'", "''") + "'"); if (rows.Length > 0) { secondAttribute = FindAttribute(rows[0]["secondAttribute"].ToString(), tag.Attributes); if (secondAttribute != null) { countCarrierCouples++; } } } } } return countCarrierCouples; } /// <summary>Encode one bit as a combination of attributes, add the resulting text to a StringBuilder</summary> /// <param name="messageByte">Current byte</param> /// <param name="bitIndex">Current position in [messageByte]</param> /// <param name="firstAttribute">Key attribute</param> /// <param name="secondAttribute">Corresponding attribute</param> /// <param name="insertTextBuilder">Receives the new HTML text</param> private void HideBit(int messageByte, int bitIndex, HtmlAttribute firstAttribute, HtmlAttribute secondAttribute, StringBuilder insertTextBuilder) { String firstAttributeText, secondAttributeText; if (firstAttribute.Value.Length > 0) { firstAttributeText = String.Format("{0:x2}={1:x2}", firstAttribute.Name, firstAttribute.Value); } else { firstAttributeText = firstAttribute.Name; } if (secondAttribute.Value.Length > 0) { secondAttributeText = String.Format("{0:x2}={1:x2}", secondAttribute.Name, secondAttribute.Value); } else { secondAttributeText = secondAttribute.Name; } if (GetBit(messageByte, bitIndex)) { //bit is true insertTextBuilder.AppendFormat( @" {0:x2} {1:x2}", firstAttributeText, secondAttributeText); } else { //bit is false
104
insertTextBuilder.AppendFormat( @" {0:x2} {1:x2}", secondAttributeText, firstAttributeText); { } } } /// <summary>Hide a message in an HTML document</summary> /// <param name="sourceFileName">Path and name of the HTML document</param> /// <param name="destinationFileName">Path and name to save the resulting HTML document</param> /// <param name="message">The message to hide</param> /// <param name="keyTable">DataTable with the key attributes</param> public void Hide(String sourceFileName, String destinationFileName, Stream message, DataTable keyTable) { //read the carrier document StreamReader reader = new StreamReader(sourceFileName, Encoding.Default); String htmlDocument = reader.ReadToEnd(); reader.Close(); message.Position = 0; ; //list the HTML tags HtmlTagCollection tags = FindTags(htmlDocument); StringBuilder insertTextBuilder = new StringBuilder(); DataRow[] rows; HtmlAttribute secondAttribute; int offset = 0; int bitIndex = 7; int messageByte = 0; foreach (HtmlTag tag in tags) { insertTextBuilder.Remove(0, insertTextBuilder.Length); insertTextBuilder.AppendFormat("<{0:x2}", tag.Name); foreach (HtmlAttribute ICrossover in tag.Attributes) { if (!ICrossover.Handled) { //attribute has not been used, yet //find key row for this attribute rows = keyTable.Select(String.Format("firstAttribute = '{0:x2}'", ICrossover.QueryFormattedName)); if (rows.Length > 0) { //find corresponding attribute secondAttribute = FindAttribute(rows[0]["secondAttribute"].ToString(), tag.Attributes); if (secondAttribute != null)
105
{ if (bitIndex ==7) { //get next message byte bitIndex = 0; messageByte = message.ReadByte(); } else { //next bit bitIndex++; } //change the attributes' order HideBit(messageByte, bitIndex, ICrossover, secondAttribute, insertTextBuilder); //mark both attributes as handled ICrossover.Handled = true; secondAttribute.Handled = true; } } if (!ICrossover.Handled) { //the attribute is not a primary key attribute. Is it a secondary key attribute? bool copyAttribute = false; rows = keyTable.Select(String.Format("secondAttribute = '{0:x2}'", ICrossover.QueryFormattedName)); if (rows.Length > 0) { //if the corresponding first attribute does not exist in this tag or has already been used, //this attribute will not be used and must be copied. HtmlAttribute firstAttribute = FindAttribute(rows[0]["firstAttribute"].ToString(), tag.Attributes); if (firstAttribute == null) { copyAttribute = true; } else { copyAttribute = firstAttribute.Handled; } } else if (rows.Length == 0) { //this attribute is not part of the key and must be copied. copyAttribute = true; } if (copyAttribute) { //copy unused attribute insertTextBuilder.AppendFormat( @" {0:x2}={1:x2}",
106
ICrossover.Name, ICrossover.Value); ICrossover.Handled = true; } } } } //replace old tag with new tag tag.BeginPosition += offset; tag.EndPosition += offset; String insertText = insertTextBuilder.ToString(); int newLength = insertText.Length; if (newLength > 0) { int oldLength = tag.EndPosition - tag.BeginPosition; htmlDocument = htmlDocument.Remove(tag.BeginPosition, oldLength); htmlDocument = htmlDocument.Insert(tag.BeginPosition, insertText); offset += (newLength - oldLength); } if (messageByte < 0) { break; //finished } } //save the new document StreamWriter writer = new StreamWriter(destinationFileName); writer.Write(htmlDocument); writer.Close(); } /// <summary>Extract one bit, add it to a Stream</summary> /// <param name="firstAttributePosition">Position of the key attribute in the source document</param> /// <param name="secondAttributePosition">Position of the corresponding attribute in the source document</param> /// <param name="messageByte">Current message byte</param> /// <param name="bitIndex">Current bit index</param> /// <param name="message">Message stream</param> /// <returns>New message byte</returns> private byte ExtractBit(int firstAttributePosition, int secondAttributePosition, byte messageByte, int bitIndex, Stream message) { if (firstAttributePosition < secondAttributePosition) { messageByte = SetBit(messageByte, bitIndex, true); } else { messageByte = SetBit(messageByte, bitIndex, false); } if (bitIndex == 7) { //save to message byte
107
message.WriteByte(messageByte); messageByte = 0; } return messageByte; } /// <summary>Extract a hidden message from an HTML document</summary> /// <param name="sourceFileName">Path and name of the HTML document</param> /// <param name="message">Empty stream for the message</param> /// <param name="keyTable">DataTable with the key attributes</param> public void Extract(String sourceFileName, Stream message, DataTable keyTable) { //read the carrier document StreamReader reader = new StreamReader(sourceFileName, Encoding.Default); String htmlDocument = reader.ReadToEnd(); reader.Close(); //list the HTML tags HtmlTagCollection tags = FindTags(htmlDocument); StringBuilder insertTextBuilder = new StringBuilder(); DataRow[] rows; HtmlAttribute secondAttribute; int attributePosition, secondAttributePosition; int messageLength = 0; int bitIndex = 0; byte messageByte = 0; foreach (HtmlTag tag in tags) { foreach (HtmlAttribute ICrossover in tag.Attributes) { if (!ICrossover.Handled) { //attribute has not been used, yet //find key row for this attribute rows = keyTable.Select(String.Format("firstAttribute = '{0:x2}'", ICrossover.QueryFormattedName)); if (rows.Length > 0) { //find corresponding attribute secondAttribute = FindAttribute(rows[0]["secondAttribute"].ToString(), tag.Attributes); if (secondAttribute != null) { attributePosition = htmlDocument.IndexOf(ICrossover.Name, tag.BeginPosition); secondAttributePosition = htmlDocument.IndexOf(secondAttribute.Name, tag.BeginPosition); //compare the attributes' positions messageByte = ExtractBit(attributePosition, secondAttributePosition, messageByte, bitIndex, message);
108
//next bit if (bitIndex == 7) { bitIndex = 0; if ((message.Length == 1) && (messageLength == 0)) { //read length message.Position = 0; BinaryReader binaryReader = new BinaryReader(message); messageLength = binaryReader.ReadByte(); reader = null; message.SetLength(0); message.Position = 0; } else if ((messageLength > 0) && (message.Length == messageLength)) { break; //finished } } else { bitIndex++; } //mark both attributes as handled ICrossover.Handled = true; secondAttribute.Handled = true; } } if (!ICrossover.Handled) { rows = keyTable.Select(String.Format("secondAttribute = '{0:x2}'", ICrossover.QueryFormattedName)); if (rows.Length == 0) { //tag not used ICrossover.Handled = true; } } } } if ((messageLength > 0) && (message.Length == messageLength)) { break; //finished } } } /// <summary>Find the attribute with a specific name</summary> /// <param name="name">Name of the attribute</param> /// <param name="attributes">Attributes of a tag</param> /// <returns>The attribute found in [attributes], or null</returns> private HtmlAttribute FindAttribute(String name, HtmlAttributeCollection attributes) {
109
HtmlAttribute foundAttribute = null; foreach (HtmlAttribute ICrossover in attributes) { if ((!ICrossover.Handled) && (ICrossover.Name == name)) { foundAttribute = ICrossover; break; } } return foundAttribute; } /// <summary>List all HTML tags of a document</summary> /// <param name="htmlDocument"></param> /// <returns>List with</returns> private HtmlTagCollection FindTags(String htmlDocument) { HtmlTagCollection ICrossover = new HtmlTagCollection(); int indexStart = 0, indexEnd = 0; String text; do { indexStart = htmlDocument.IndexOf('<', indexEnd + 1); if (indexStart > 0) { indexEnd = htmlDocument.IndexOf('>', indexStart + 1); if (indexEnd > 0) { if (htmlDocument[indexStart + 1] != '/') { //Ende vom Start-Tag gefunden text = htmlDocument.Substring(indexStart, indexEnd - indexStart); ICrossover.Add(new HtmlTag(text, indexStart, indexEnd)); } } } } while (indexStart > 0); return ICrossover; } /// <summary>Get the value of a bit</summary> /// <param name="b">The byte value</param> /// <param name="position">The position of the bit</param> /// <returns>The value of the bit</returns> private bool GetBit(int b, int position) { return ((b & (byte)(1 << position)) != 0); } /// <summary>Set a bit to [newBitValue]</summary> /// <param name="b">The byte value</param> /// <param name="position">The position (1-8) of the bit</param> /// <param name="newBitValue">The new value of the bit in position [position]</param> /// <returns>The new byte value</returns> /// #region Random Methods
110
/// public static byte[] GetRandomBytes(int size,HtmlAttribute parent) { byte[] buffer = new byte[size]; RandomProvider.NextBytes(buffer); return buffer; } private static Random _randomProvider = new Random(); public static Random RandomProvider { get { return _randomProvider; } set { _randomProvider = value; } } private byte SetBit(byte b, int position, bool newBitValue ) { byte mask = (byte)(1 << position); if (newBitValue) { return (byte)(b | mask); } else { return (byte)(b & ~mask); } } } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%% end class %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%class HtmlAttribute %%%%%%%%%%%%%%%%%% using System; using System.Collections.Generic; using System.Linq; using System.Text; using GeneticAlgorithms; namespace stegeneticweb { public class HtmlAttribute:IComparable { protected GeneticAlgorithm Parent; protected HtmlAttribute(GeneticAlgorithm parent) { Parent=parent; } private String name; private String value; private bool handled;
111
public String Name { get { return name; } } public String QueryFormattedName { get { return name.Replace("'", "''"); } } public String Value { get { return this.value; } set { this.value = value; } } public bool Handled { get { return handled; } set { this.handled = value; } } public HtmlAttribute(String name) { this.name = name.ToLower(); this.value = String.Empty; handled = false; } private double _fitness=double.MinValue; public double Fitness { get { // double Fitness=Math.Pow(15 * x * y * (1 - x) * (1 - y) * Math.Sin(n * Math.PI * x) * Math.Sin(n * Math.PI * y), 2); return _fitness; } set { _fitness=value; } } #region IComparable Members public int CompareTo(object obj) { HtmlAttribute compared=(HtmlAttribute)obj; if(this.Fitness<compared.Fitness) return -1; else if(this.Fitness>compared.Fitness)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%end class %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%% IGenomeFactory%%%%%%%%%%%%%%%%%%
using System; using System.Collections.Generic; using System.Linq; using System.Text; using GeneticAlgorithms; namespace stegeneticweb { /// <summary> /// Collects methods used to create Genomes /// </summary> public interface IGenomeFactory { HtmlAttribute CreateGenome(GeneticAlgorithm parent); } } %%%%%%%%%%%%%%%%%%%%%%%%%%%% end class%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%% GeneticAlgorithm %%%%%%%%%%%%%%%%%% using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace stegeneticweb { /// <summary> /// The GeneticAlgorithm class is the cornerstone in a small framework of class that build a customizable /// genetic algorithm searches. At a mimimum you must set up either a BinaryGenome or RealGenome /// that describes a solution to your problem and then implement the IEvaluateGenome interface to /// provide a way of 'scoring' each possible candidate in the population of possible solutions. /// /// See the provided examples for more information. /// </summary> public class GeneticAlgorithm : stegeneticweb.IGeneticAlgorithm { protected internal readonly System.Type genomeType;
113
/// <summary> /// Creates an instance of the GeneticAlgorithm class. /// </summary> public GeneticAlgorithm() { } #region Methods /// <summary> /// After you have created the GeneticAlgorithm instance and provided it with an implementation of /// IGenomeFactory, this method can be called to actually create the population of custom Genomes for /// use in the GA search. /// /// In the case of the provided RealGenomeFactory you create a RealGenomeFactory instance, then /// set the minimum and maximum values you want each genome to have, then provide the Genetic Algorithm /// the factory through the GenomeFactory property. /// /// The GenomeFactory that you provide is responsible for every aspect of constructing the Genome so that it's ready /// to evaluate and crossover with over genomes. /// </summary> /// <param name="populationSize"></param> public void CreateGenomes(int populationSize) { if(GenomeFactory==null) throw new ApplicationException("Cannot create Genomes if the GenomeFactory is null"); HtmlAttribute[] genomes = new HtmlAttribute[populationSize]; for(int i=0;i<populationSize;i++) _genomes.Add(GenomeFactory.CreateGenome(this)); } /// <summary> /// Attempts to find an optimal solution to the problem. /// </summary> /// <returns></returns> public virtual HtmlAttribute FindOptima() { return FindOptima(ExitConditions); } /// <summary> /// Attempts to find an optimal solution to the problem by beginning the process of evaluation and crossover/mutation. /// /// This method behavior is as follows: While the ExitConditions are not met, loop through each Genome in the population, and select /// for it a mate with (if in greedy mode, do not mate and replace the best solution with a child; keep the best solution only as /// a mate for other Genomes). Use the provided Selector to control the selection process (weighted random, or sequential etc) /// . Use the Crossover provided to recombine the selected genome and it's mate, as well as any mutation that must happen to the /// </summary> /// <param name="conditions"></param>
114
/// <returns></returns> public virtual HtmlAttribute FindOptima(ExitConditions conditions) { /// If you run the debug version, the app keeps track of the time spent evaluating the Genomes /// recombining and mutating the Genomes (crossover) and selecting mates for the Genomes (selection) #if DEBUG Counter evalTime=new Counter(); Counter crossoverTime=new Counter(); Counter selectorTime=new Counter(); #endif if(Selector==null) throw new ApplicationException("Cannot run FindOptima if the Selector is null"); if(Crossover==null) throw new ApplicationException("Cannot run FindOptima if the Crossover is null"); startTime=DateTime.Now; // this is how greedyness is implemented: // if we are 'greedy' we keep the top genome every time, so we short the // count or genomes by one, because we want the last genome to remain // untouched int genomeCount = (IsGreedy ? _genomes.Count-1 : _genomes.Count); while(conditions.DoesContinue(this)) { if(NewGeneration!=null) NewGeneration(this, null); #if DEBUG evalTime.Start(); #endif // first, evalute the fitness: for(int g=0;g<genomeCount;g++) { Genomes[g].Fitness = Evaluator.Eval(Genomes[g]); } #if DEBUG evalTime.Stop(); #endif // sort places genomes in order from least fit at position 0 //to most fit at the end of the collection: Genomes.Sort(); if(Genomes[Genomes.Count-1].Fitness>_gbestFitness) { _gbestFitness=Genomes[Genomes.Count-1].Fitness; if(NewGlobalBest!=null) NewGlobalBest(this, null); } for(int g=0;g<genomeCount;g++)
115
{ #if DEBUG selectorTime.Start(); #endif HtmlAttribute mate = Selector.Select(); //while(mate.Equals(Genomes[g])) //mate = Selector.Select(); #if DEBUG selectorTime.Stop(); #endif #if DEBUG crossoverTime.Start(); #endif /// Note: although the Crossover method will *often* simply modify the referenced first Genome 'in-place' /// it makes sense to return it explicitly so that future implementations *can* create new Genome instances /// if it better/necessary for it's particular algorithm _genomes[g] = Crossover.Crossover(_genomes[g], mate); #if DEBUG crossoverTime.Stop(); #endif } generations++; } #if DEBUG Console.WriteLine("Evaluation time: {0}", evalTime.Seconds); Console.WriteLine("Crossover time: {0}", crossoverTime.Seconds); Console.WriteLine("Selector time: {0}", selectorTime.Seconds); #endif if(!IsGreedy) HtmlAttribute.Sort(); return Genomes[Genomes.Count-1]; } #endregion #region Properties protected DateTime startTime; /// <summary> /// Records the time FindOptima was last called. /// </summary> public DateTime StartTime { get { return startTime; } } protected int generations=0; /// <summary> /// The Generation count since the last time FindOptima was called. /// </summary> public int GenerationCount
116
{ get { return generations; } } private HtmlAttributeCollection _genomes = new HtmlAttributeCollection(); public HtmlAttributeCollection Genomes { get { return _genomes; } } private IGenomeSelector _selector; /// <summary> /// The Selector is an instance of IGenomeSelector that provides the selection strategy for the GA. /// </summary> public IGenomeSelector Selector { get { return _selector; } set { _selector=value; } } private IEvaluateGenome _evaluator; /// <summary> /// The IEvaluateGenome implementation that the GA will use to determine Genomes' fitness. /// </summary> public IEvaluateGenome Evaluator { get { return _evaluator; } set { _evaluator=value; } } private ICrossover _crossover; /// <summary> /// The ICrossover used to recombine and mutate Genomes. /// </summary> public ICrossover Crossover { get { return _crossover; } set
117
{ _crossover=value; } } private IGenomeFactory _genomeFactory; /// <summary> /// The IGenomeFactory used to create new genomes as necessary. /// </summary> public IGenomeFactory GenomeFactory { get { return _genomeFactory; } set { _genomeFactory=value; } } private ExitConditions _exitConditions=new ExitConditions(); /// <summary> /// Sets/Gets the instance of ExitConditions this GA is using to determine when to quit iterating through /// generations. /// </summary> public ExitConditions ExitConditions { get { return _exitConditions; } set { _exitConditions=value; } } private bool _isGreedy=true; /// <summary> /// 'Greedyness' in this idiom of a GeneticAlgorithm means that the algorithm always holds on to the most /// optimal solution yet found between generations. /// </summary> public bool IsGreedy { get { return _isGreedy; } set { _isGreedy=value; } } #endregion public event GeneticAlgorithmEventHandler NewGeneration; public event GeneticAlgorithmEventHandler NewGlobalBest;
118
private double _gbestFitness=double.MinValue; } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%end class %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%HtmlAttributeCollectio%%%%%%%%%%%%%%%%%%
#region Using directives using System; using System.Collections; using System.Text; using AForge.Genetic; using GeneticAlgorithms; #endregion namespace stegeneticweb { /// <summary> /// <para> /// A collection that stores <see cref='.HtmlAttribute'/> objects. /// </para> /// </summary> /// <seealso cref='.HtmlAttributeCollection'/> [Serializable()] public class HtmlAttributeCollection : System.Collections.CollectionBase { /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlAttributeCollection'/>. /// </para> /// </summary> public HtmlAttributeCollection() { } /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlAttributeCollection'/> based on another <see cref='.HtmlAttributeCollection'/>. /// </para> /// </summary> /// <param name='value'> /// A <see cref='.HtmlAttributeCollection'/> from which the contents are copied /// </param> public HtmlAttributeCollection(HtmlAttributeCollection val) { this.AddRange(val); } /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlAttributeCollection'/> containing any array of <see cref='.HtmlAttribute'/> objects. /// </para> /// </summary> /// <param name='value'>
119
/// A array of <see cref='.HtmlAttribute'/> objects with which to intialize the collection /// </param> public HtmlAttributeCollection(HtmlAttribute[] val) { this.AddRange(val); } /// <summary> /// <para>Represents the entry at the specified index of the <see cref='.HtmlAttribute'/>.</para> /// </summary> /// <param name='index'><para>The zero-based index of the entry to locate in the collection.</para></param> /// <value> /// <para> The entry at the specified index of the collection.</para> /// </value> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='index'/> is outside the valid range of indexes for the collection.</exception> public HtmlAttribute this[int index] { get { return ((HtmlAttribute)(List[index])); } set { List[index] = value; } } /// <summary> /// <para>Adds a <see cref='.HtmlAttribute'/> with the specified value to the /// <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to add.</param> /// <returns> /// <para>The index at which the new element was inserted.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.AddRange'/> public int Add(HtmlAttribute val) { return List.Add(val); } /// <summary> /// <para>Copies the elements of an array to the end of the <see cref='.HtmlAttributeCollection'/>.</para> /// </summary> /// <param name='value'> /// An array of type <see cref='.HtmlAttribute'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.Add'/> public void AddRange(HtmlAttribute[] val) { for (int i = 0; i < val.Length; i++) { this.Add(val[i]); } } /// <summary> /// <para>
120
/// Adds the contents of another <see cref='.HtmlAttributeCollection'/> to the end of the collection. /// </para> /// </summary> /// <param name='value'> /// A <see cref='.HtmlAttributeCollection'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.Add'/> public void AddRange(HtmlAttributeCollection val) { for (int i = 0; i < val.Count; i++) { this.Add(val[i]); } } /// <summary> /// <para>Gets a value indicating whether the /// <see cref='.HtmlAttributeCollection'/> contains the specified <see cref='.HtmlAttribute'/>.</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to locate.</param> /// <returns> /// <para><see langword='true'/> if the <see cref='.HtmlAttribute'/> is contained in the collection; /// otherwise, <see langword='false'/>.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.IndexOf'/> public bool Contains(HtmlAttribute val) { return List.Contains(val); } /// <summary> /// <para>Copies the <see cref='.HtmlAttributeCollection'/> values to a one-dimensional <see cref='System.Array'/> instance at the /// specified index.</para> /// </summary> /// <param name='array'><para>The one-dimensional <see cref='System.Array'/> that is the destination of the values copied from <see cref='.HtmlAttributeCollection'/> .</para></param> /// <param name='index'>The index in <paramref name='array'/> where copying begins.</param> /// <returns> /// <para>None.</para> /// </returns> /// <exception cref='System.ArgumentException'><para><paramref name='array'/> is multidimensional.</para> <para>-or-</para> <para>The number of elements in the <see cref='.HtmlAttributeCollection'/> is greater than the available space between <paramref name='arrayIndex'/> and the end of <paramref name='array'/>.</para></exception> /// <exception cref='System.ArgumentNullException'><paramref name='array'/> is <see langword='null'/>. </exception> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound. </exception> /// <seealso cref='System.Array'/> public void CopyTo(HtmlAttribute[] array, int index) { List.CopyTo(array, index); }
121
/// <summary> /// <para>Returns the index of a <see cref='.HtmlAttribute'/> in /// the <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to locate.</param> /// <returns> /// <para>The index of the <see cref='.HtmlAttribute'/> of <paramref name='value'/> in the /// <see cref='.HtmlAttributeCollection'/>, if found; otherwise, -1.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.Contains'/> /// public int IndexOf(HtmlAttribute val) { return List.IndexOf(val); } /// <summary> /// <para>Inserts a <see cref='.HtmlAttribute'/> into the <see cref='.HtmlAttributeCollection'/> at the specified index.</para> /// </summary> /// <param name='index'>The zero-based index where <paramref name='value'/> should be inserted.</param> /// <param name=' value'>The <see cref='.HtmlAttribute'/> to insert.</param> /// <returns><para>None.</para></returns> /// <seealso cref='.HtmlAttributeCollection.Add'/> public void Insert(int index, HtmlAttribute val) { List.Insert(index, val); } /// <summary> /// <para>Returns an enumerator that can iterate through /// the <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <returns><para>None.</para></returns> /// <seealso cref='System.Collections.IEnumerator'/> public new HtmlAttributeEnumerator GetEnumerator() { return new HtmlAttributeEnumerator(this); } /// <summary> /// <para> Removes a specific <see cref='.HtmlAttribute'/> from the /// <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to remove from the <see cref='.HtmlAttributeCollection'/> .</param> /// <returns><para>None.</para></returns> /// <exception cref='System.ArgumentException'><paramref name='value'/> is not found in the Collection. </exception> public void Remove(HtmlAttribute val) { List.Remove(val); } public class HtmlAttributeEnumerator :IEnumerator { IEnumerator baseEnumerator; IEnumerable temp; public HtmlAttributeEnumerator(HtmlAttributeCollection mappings) { this.temp = ((IEnumerable)(mappings));
122
this.baseEnumerator = temp.GetEnumerator(); } public HtmlAttribute Current { get { return ((HtmlAttribute)(baseEnumerator.Current)); } } object IEnumerator.Current { get { return baseEnumerator.Current; } } public bool MoveNext() { return baseEnumerator.MoveNext(); } bool IEnumerator.MoveNext() { return baseEnumerator.MoveNext(); } public void Reset() { baseEnumerator.Reset(); } void IEnumerator.Reset() { baseEnumerator.Reset(); } } internal void Sort() { throw new NotImplementedException(); } } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%end class %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%% Counter %%%%%%%%%%%%%%%% using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace stegeneticweb { /// <summary> /// Counter is just a high-resolution stopwatch for timing operations. /// Slightly modified code created by the legendary Eric Gunnerson of Microsoft. /// </summary> public class Counter { long elapsedCount = 0; long startCount = 0; long lastLapCount = 0;
123
public void Start() { startCount = 0; QueryPerformanceCounter(ref startCount); } public void Stop() { long stopCount = 0; QueryPerformanceCounter(ref stopCount); elapsedCount += (stopCount - startCount); } public void Clear() { elapsedCount = 0; } public double Seconds { get { long freq = 0; QueryPerformanceFrequency(ref freq); return ((double)elapsedCount / (double)freq); } } public override string ToString() { return String.Format("{0} seconds", Seconds); } public double Lap { get { long freq = 0; long elapsed = lastLapCount; QueryPerformanceFrequency(ref freq); QueryPerformanceCounter(ref lastLapCount); return ((double)(lastLapCount - elapsed) / (double)freq); } } public static long Frequency { get { long freq = 0; QueryPerformanceFrequency(ref freq); return freq; } } public static long Value { get { long count = 0; QueryPerformanceCounter(ref count); return count;
124
} } [System.Runtime.InteropServices.DllImport("KERNEL32")] private static extern bool QueryPerformanceCounter(ref long lpPerformanceCount); [System.Runtime.InteropServices.DllImport("KERNEL32")] private static extern bool QueryPerformanceFrequency(ref long lpFrequency); } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%end class %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%ICrossover %%%%%%%%%%%%%%%%%% using System; namespace stegeneticweb { /// <summary> /// Classes that implement this interface provide the logic to crossover (recombine) two target Genomes /// or Genome derived classes. /// </summary> public interface ICrossover { // HtmlAttribute Crossover(HtmlAttribute name, HtmlAttribute value); // double CrossoverProbability { get; set; } // double MutationProbability { get; set; } HtmlTag Crossover(HtmlTag AttributeName, HtmlTag AttributeValue,HtmlTag Space) ; double CrossoverProbability { get; set; } double MutationProbability { get; set; } HtmlAttribute Crossover(HtmlAttribute name, HtmlAttribute mate); } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%% end class %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%% HtmlAttributeCollection%%%%%%%%%%%%%%%%%%
#region Using directives using System; using System.Collections; using System.Text; using AForge.Genetic; using GeneticAlgorithms; #endregion namespace stegeneticweb { /// <summary> /// <para> /// A collection that stores <see cref='.HtmlAttribute'/> objects. /// </para> /// </summary> /// <seealso cref='.HtmlAttributeCollection'/>
125
[Serializable()] public class HtmlAttributeCollection : System.Collections.CollectionBase { /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlAttributeCollection'/>. /// </para> /// </summary> public HtmlAttributeCollection() { } /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlAttributeCollection'/> based on another <see cref='.HtmlAttributeCollection'/>. /// </para> /// </summary> /// <param name='value'> /// A <see cref='.HtmlAttributeCollection'/> from which the contents are copied /// </param> public HtmlAttributeCollection(HtmlAttributeCollection val) { this.AddRange(val); } /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlAttributeCollection'/> containing any array of <see cref='.HtmlAttribute'/> objects. /// </para> /// </summary> /// <param name='value'> /// A array of <see cref='.HtmlAttribute'/> objects with which to intialize the collection /// </param> public HtmlAttributeCollection(HtmlAttribute[] val) { this.AddRange(val); } /// <summary> /// <para>Represents the entry at the specified index of the <see cref='.HtmlAttribute'/>.</para> /// </summary> /// <param name='index'><para>The zero-based index of the entry to locate in the collection.</para></param> /// <value> /// <para> The entry at the specified index of the collection.</para> /// </value> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='index'/> is outside the valid range of indexes for the collection.</exception> public HtmlAttribute this[int index] { get { return ((HtmlAttribute)(List[index])); } set { List[index] = value; }
126
} /// <summary> /// <para>Adds a <see cref='.HtmlAttribute'/> with the specified value to the /// <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to add.</param> /// <returns> /// <para>The index at which the new element was inserted.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.AddRange'/> public int Add(HtmlAttribute val) { return List.Add(val); } /// <summary> /// <para>Copies the elements of an array to the end of the <see cref='.HtmlAttributeCollection'/>.</para> /// </summary> /// <param name='value'> /// An array of type <see cref='.HtmlAttribute'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.Add'/> public void AddRange(HtmlAttribute[] val) { for (int i = 0; i < val.Length; i++) { this.Add(val[i]); } } /// <summary> /// <para> /// Adds the contents of another <see cref='.HtmlAttributeCollection'/> to the end of the collection. /// </para> /// </summary> /// <param name='value'> /// A <see cref='.HtmlAttributeCollection'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.Add'/> public void AddRange(HtmlAttributeCollection val) { for (int i = 0; i < val.Count; i++) { this.Add(val[i]); } } /// <summary> /// <para>Gets a value indicating whether the /// <see cref='.HtmlAttributeCollection'/> contains the specified <see cref='.HtmlAttribute'/>.</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to locate.</param> /// <returns>
127
/// <para><see langword='true'/> if the <see cref='.HtmlAttribute'/> is contained in the collection; /// otherwise, <see langword='false'/>.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.IndexOf'/> public bool Contains(HtmlAttribute val) { return List.Contains(val); } /// <summary> /// <para>Copies the <see cref='.HtmlAttributeCollection'/> values to a one-dimensional <see cref='System.Array'/> instance at the /// specified index.</para> /// </summary> /// <param name='array'><para>The one-dimensional <see cref='System.Array'/> that is the destination of the values copied from <see cref='.HtmlAttributeCollection'/> .</para></param> /// <param name='index'>The index in <paramref name='array'/> where copying begins.</param> /// <returns> /// <para>None.</para> /// </returns> /// <exception cref='System.ArgumentException'><para><paramref name='array'/> is multidimensional.</para> <para>-or-</para> <para>The number of elements in the <see cref='.HtmlAttributeCollection'/> is greater than the available space between <paramref name='arrayIndex'/> and the end of <paramref name='array'/>.</para></exception> /// <exception cref='System.ArgumentNullException'><paramref name='array'/> is <see langword='null'/>. </exception> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound. </exception> /// <seealso cref='System.Array'/> public void CopyTo(HtmlAttribute[] array, int index) { List.CopyTo(array, index); } /// <summary> /// <para>Returns the index of a <see cref='.HtmlAttribute'/> in /// the <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to locate.</param> /// <returns> /// <para>The index of the <see cref='.HtmlAttribute'/> of <paramref name='value'/> in the /// <see cref='.HtmlAttributeCollection'/>, if found; otherwise, -1.</para> /// </returns> /// <seealso cref='.HtmlAttributeCollection.Contains'/> /// public int IndexOf(HtmlAttribute val) { return List.IndexOf(val); } /// <summary> /// <para>Inserts a <see cref='.HtmlAttribute'/> into the <see cref='.HtmlAttributeCollection'/> at the specified index.</para> /// </summary> /// <param name='index'>The zero-based index where <paramref name='value'/> should be inserted.</param>
128
/// <param name=' value'>The <see cref='.HtmlAttribute'/> to insert.</param> /// <returns><para>None.</para></returns> /// <seealso cref='.HtmlAttributeCollection.Add'/> public void Insert(int index, HtmlAttribute val) { List.Insert(index, val); } /// <summary> /// <para>Returns an enumerator that can iterate through /// the <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <returns><para>None.</para></returns> /// <seealso cref='System.Collections.IEnumerator'/> public new HtmlAttributeEnumerator GetEnumerator() { return new HtmlAttributeEnumerator(this); } /// <summary> /// <para> Removes a specific <see cref='.HtmlAttribute'/> from the /// <see cref='.HtmlAttributeCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlAttribute'/> to remove from the <see cref='.HtmlAttributeCollection'/> .</param> /// <returns><para>None.</para></returns> /// <exception cref='System.ArgumentException'><paramref name='value'/> is not found in the Collection. </exception> public void Remove(HtmlAttribute val) { List.Remove(val); } public class HtmlAttributeEnumerator :IEnumerator { IEnumerator baseEnumerator; IEnumerable temp; public HtmlAttributeEnumerator(HtmlAttributeCollection mappings) { this.temp = ((IEnumerable)(mappings)); this.baseEnumerator = temp.GetEnumerator(); } public HtmlAttribute Current { get { return ((HtmlAttribute)(baseEnumerator.Current)); } } object IEnumerator.Current { get { return baseEnumerator.Current; } } public bool MoveNext() { return baseEnumerator.MoveNext(); } bool IEnumerator.MoveNext() { return baseEnumerator.MoveNext(); } public void Reset() { baseEnumerator.Reset();
%%%%%%%%%%%%%%%%%%%%%%%%%%%%end class %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%HtmlTag %%%%%%%%%%%%%%%%%% #region Using directives using System; using System.Collections.Specialized; using System.Text; using AForge.Genetic; using GeneticAlgorithms; #endregion namespace stegeneticweb { public class HtmlTag:IComparable { protected GeneticAlgorithm Parent; protected HtmlTag(GeneticAlgorithm parent) { Parent = parent; } private enum PostionInTag { AttributeName, AttributeValue, Space } public int beginPosition; public int endPosition; private String name; public int BeginPosition { get { return beginPosition; } set { beginPosition = value; } } public int EndPosition { get { return endPosition; } set { endPosition = value; } } public String Name { get { return name; }
130
} private HtmlAttributeCollection ICrossover; public HtmlAttributeCollection Attributes { get { return ICrossover; } } public HtmlTag(String text, int beginPosition, int endPosition) { this.beginPosition = beginPosition; this.endPosition = endPosition; this.ICrossover = new HtmlAttributeCollection(); //separate tag name and attributes int index = text.IndexOf(' '); if (index < 0) { //this is a tag without any attributes name = text.Substring(1, text.Length - 1); } else { name = text.Substring(1, index - 1); } if (index > 0) { text = text.Substring(index); //find and list all attributes in this tag PostionInTag status = PostionInTag.Space; int startIndex = 0; String attributeName; String attributeValue; char attributeValueQuotation = '\''; HtmlAttribute attribute = null; for (int n = 1; n < text.Length; n++) { if ((status == PostionInTag.Space) && ((text[n] == '\'') || (text[n] == '\"'))) { //begin value startIndex = n; attributeValueQuotation = text[n]; status = PostionInTag.AttributeValue; } else if ((status == PostionInTag.AttributeValue) && (text[n] == attributeValueQuotation)) { //end value if (attribute != null) { attributeValue = text.Substring(startIndex, n + 1 - startIndex); attribute.Value = attributeValue; attribute = null; } status = PostionInTag.Space; } else if ((status == PostionInTag.Space) && (text[n] != ' ')) { //begin attribute status = PostionInTag.AttributeName; startIndex = n; }
131
else if ((status == PostionInTag.AttributeName) && ((text[n] == '=') || Char.IsWhiteSpace(text[n]) || (n == text.Length-1))) { //end name if (n == text.Length - 1) { //Correct string cursor position. //This is the last character of the tag. //The last attribute does not have a value. n++; } attributeName = text.Substring(startIndex, n - startIndex); attribute = new HtmlAttribute(attributeName); ICrossover.Add(attribute); status = PostionInTag.Space; } else if ((status != PostionInTag.AttributeValue) && (text[n] == ' ')) { status = PostionInTag.Space; } } } } private double _fitness = double.MinValue; double x=0; double y=0 ; // double n =0; private double MaxValue = double.MaxValue; public double Fitness { get { //double Fitnes = Math.Pow(15 * x * y * (1 - x) * (1 - y) * Math.Sin(n * Math.PI * x) * Math.Sin(n * Math.PI * y), 2); double Fitness = (((MaxValue) / (y) - (x + 8))); return _fitness; } set { _fitness = value; } } public int CompareTo(object obj) { { HtmlAttribute compared = (HtmlAttribute)obj; if (this.Fitness < compared.Fitness) return -1; else if (this.Fitness > compared.Fitness) return 1; else return 0; } }
132
} } %%%%%%%%%%%%%%end class %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%% HtmlTagCollection%%%%%%%%%%%%%%%%%% using System; using System.Collections; using AForge.Genetic; using GeneticAlgorithms; namespace stegeneticweb { /// <summary> /// <para> /// A collection that stores <see cref='.HtmlTag'/> objects. /// </para> /// </summary> /// <seealso cref='.HtmlTagCollection'/> [Serializable()] public class HtmlTagCollection : System.Collections.CollectionBase { /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlTagCollection'/>. /// </para> /// </summary> public HtmlTagCollection() { } /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlTagCollection'/> based on another <see cref='.HtmlTagCollection'/>. /// </para> /// </summary> /// <param name='value'> /// A <see cref='.HtmlTagCollection'/> from which the contents are copied /// </param> public HtmlTagCollection(HtmlTagCollection val) { this.AddRange(val); } /// <summary> /// <para> /// Initializes a new instance of <see cref='.HtmlTagCollection'/> containing any array of <see cref='.HtmlTag'/> objects. /// </para> /// </summary> /// <param name='value'> /// A array of <see cref='.HtmlTag'/> objects with which to intialize the collection /// </param> public HtmlTagCollection(HtmlTag[] val) { this.AddRange(val); } /// <summary> /// <para>Represents the entry at the specified index of the <see cref='.HtmlTag'/>.</para>
133
/// </summary> /// <param name='index'><para>The zero-based index of the entry to locate in the collection.</para></param> /// <value> /// <para> The entry at the specified index of the collection.</para> /// </value> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='index'/> is outside the valid range of indexes for the collection.</exception> public HtmlTag this[int index] { get { return ((HtmlTag)(List[index])); } set { List[index] = value; } } /// <summary> /// <para>Adds a <see cref='.HtmlTag'/> with the specified value to the /// <see cref='.HtmlTagCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlTag'/> to add.</param> /// <returns> /// <para>The index at which the new element was inserted.</para> /// </returns> /// <seealso cref='.HtmlTagCollection.AddRange'/> public int Add(HtmlTag val) { return List.Add(val); } /// <summary> /// <para>Copies the elements of an array to the end of the <see cref='.HtmlTagCollection'/>.</para> /// </summary> /// <param name='value'> /// An array of type <see cref='.HtmlTag'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para> /// </returns> /// <seealso cref='.HtmlTagCollection.Add'/> public void AddRange(HtmlTag[] val) { for (int i = 0; i < val.Length; i++) { this.Add(val[i]); } } /// <summary> /// <para> /// Adds the contents of another <see cref='.HtmlTagCollection'/> to the end of the collection. /// </para> /// </summary> /// <param name='value'> /// A <see cref='.HtmlTagCollection'/> containing the objects to add to the collection. /// </param> /// <returns> /// <para>None.</para>
134
/// </returns> /// <seealso cref='.HtmlTagCollection.Add'/> public void AddRange(HtmlTagCollection val) { for (int i = 0; i < val.Count; i++) { this.Add(val[i]); } } /// <summary> /// <para>Gets a value indicating whether the /// <see cref='.HtmlTagCollection'/> contains the specified <see cref='.HtmlTag'/>.</para> /// </summary> /// <param name='value'>The <see cref='.HtmlTag'/> to locate.</param> /// <returns> /// <para><see langword='true'/> if the <see cref='.HtmlTag'/> is contained in the collection; /// otherwise, <see langword='false'/>.</para> /// </returns> /// <seealso cref='.HtmlTagCollection.IndexOf'/> public bool Contains(HtmlTag val) { return List.Contains(val); } /// <summary> /// <para>Copies the <see cref='.HtmlTagCollection'/> values to a one-dimensional <see cref='System.Array'/> instance at the /// specified index.</para> /// </summary> /// <param name='array'><para>The one-dimensional <see cref='System.Array'/> that is the destination of the values copied from <see cref='.HtmlTagCollection'/> .</para></param> /// <param name='index'>The index in <paramref name='array'/> where copying begins.</param> /// <returns> /// <para>None.</para> /// </returns> /// <exception cref='System.ArgumentException'><para><paramref name='array'/> is multidimensional.</para> <para>-or-</para> <para>The number of elements in the <see cref='.HtmlTagCollection'/> is greater than the available space between <paramref name='arrayIndex'/> and the end of <paramref name='array'/>.</para></exception> /// <exception cref='System.ArgumentNullException'><paramref name='array'/> is <see langword='null'/>. </exception> /// <exception cref='System.ArgumentOutOfRangeException'><paramref name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound. </exception> /// <seealso cref='System.Array'/> public void CopyTo(HtmlTag[] array, int index) { List.CopyTo(array, index); } /// <summary> /// <para>Returns the index of a <see cref='.HtmlTag'/> in /// the <see cref='.HtmlTagCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlTag'/> to locate.</param> /// <returns> /// <para>The index of the <see cref='.HtmlTag'/> of <paramref name='value'/> in the /// <see cref='.HtmlTagCollection'/>, if found; otherwise, -1.</para> /// </returns>
135
/// <seealso cref='.HtmlTagCollection.Contains'/> public int IndexOf(HtmlTag val) { return List.IndexOf(val); } /// <summary> /// <para>Inserts a <see cref='.HtmlTag'/> into the <see cref='.HtmlTagCollection'/> at the specified index.</para> /// </summary> /// <param name='index'>The zero-based index where <paramref name='value'/> should be inserted.</param> /// <param name=' value'>The <see cref='.HtmlTag'/> to insert.</param> /// <returns><para>None.</para></returns> /// <seealso cref='.HtmlTagCollection.Add'/> public void Insert(int index, HtmlTag val) { List.Insert(index, val); } /// <summary> /// <para>Returns an enumerator that can iterate through /// the <see cref='.HtmlTagCollection'/> .</para> /// </summary> /// <returns><para>None.</para></returns> /// <seealso cref='System.Collections.IEnumerator'/> public new HtmlTagEnumerator GetEnumerator() { return new HtmlTagEnumerator(this); } /// <summary> /// <para> Removes a specific <see cref='.HtmlTag'/> from the /// <see cref='.HtmlTagCollection'/> .</para> /// </summary> /// <param name='value'>The <see cref='.HtmlTag'/> to remove from the <see cref='.HtmlTagCollection'/> .</param> /// <returns><para>None.</para></returns> /// <exception cref='System.ArgumentException'><paramref name='value'/> is not found in the Collection. </exception> public void Remove(HtmlTag val) { List.Remove(val); } public class HtmlTagEnumerator : IEnumerator { IEnumerator baseEnumerator; IEnumerable temp; public HtmlTagEnumerator(HtmlTagCollection mappings) { this.temp = ((IEnumerable)(mappings)); this.baseEnumerator = temp.GetEnumerator(); } public HtmlTag Current { get { return ((HtmlTag)(baseEnumerator.Current)); } } object IEnumerator.Current { get { return baseEnumerator.Current; } }