public SentenceGA(string wordListPath, int populationSize, int sentenceLength) { _populationSize = populationSize; _sentenceLength = sentenceLength; _wordList = new WordList(wordListPath); ornateRTN = Parse("C:\\Users\\Tommy\\Desktop\\CS\\rtngeneticalgorithm\\" + "rtngeneticalgorithm\\rtn.xml", "ornate_noun"); fancyRTN = Parse("C:\\Users\\Tommy\\Desktop\\CS\\rtngeneticalgorithm\\" + "rtngeneticalgorithm\\rtn.xml", "fancy_noun"); // Main GA part Generation(); for (int i = 0; i < 100; i++) { Evaluation(); Reproduction(); PrintSentences(); } }
// Misc methods private RTN Parse(string filePath, string networkName) { XmlDocument RTNFile = new XmlDocument(); RTNFile.Load(filePath); RTN newNetwork = new RTN(networkName); foreach (XmlNode network in RTNFile.ChildNodes[1]) { if (network.Attributes[0].Value == networkName) { foreach (XmlNode node in network) { Node newNode; if (node.Attributes[1].Value == "true") { newNode = new Node(node.Attributes[0].Value, true); } else { newNode = new Node(node.Attributes[0].Value, false); } foreach (XmlNode from in node.ChildNodes[0]) { newNode.AddFrom(from.InnerText); } foreach (XmlNode to in node.ChildNodes[1]) { newNode.AddTo(to.InnerText); } newNetwork.AddNode(newNode); } } } return(newNetwork); }
private int GetBackFitness(string[] sentence, RTN network) { int fitness = 0; int currentWord = 0; string currentNode = "end"; while (true) { List <string> currentFrom = network.GetNode(currentNode).GetFrom(); if (currentWord == sentence.Length) { foreach (string from in currentFrom) { if (from == "begin") { return(fitness); } } return(fitness * -1); } else { bool used = false; foreach (string from in currentFrom) { if (from == "begin") { return(fitness); } string generalFrom = ""; if (from == "verb_1" || from == "verb_2") { generalFrom = "verb"; } else { generalFrom = from; } if (_wordList.GetWordType(sentence[currentWord]) == generalFrom) { used = true; fitness += 1; currentWord += 1; currentNode = from; break; } else if (network.GetNode(from)._expand) { used = true; string[] subSentence = new string[sentence.Length - currentWord]; for (int i = currentWord; i < sentence.Length; i++) { subSentence[i - currentWord] = sentence[i]; } int subFitness; if (from == "ornate_noun" || from == "ornate_noun_2") { subFitness = GetBackFitness(subSentence, ornateRTN); } else { subFitness = GetBackFitness(subSentence, fancyRTN); } fitness += Math.Abs(subFitness); if (subFitness <= 0) { return(fitness * -1); } else { currentWord += subFitness; currentNode = from; break; } } else { used = false; } } if (!used) { return(fitness * -1); } } } }
private int GetFrontFitness(string[] sentence, RTN network) { int fitness = 0; int currentWord = 0; string currentNode = "begin"; // While the sentence is deemed fit, keep checking while (true) { // Get the nodes which current node goes to List <string> currentTo = network.GetNode(currentNode).GetTo(); // If reached the end of sentence, check if end of network // If so, deem it fit and return positive fitness // Otherwise return negative fitness if (currentWord == sentence.Length) { foreach (string to in currentTo) { if (to == "end") { return(fitness); } } return(fitness * -1); } else { // Check if the current word is of any significance, such as being an end node, an expand node or a next node // If none, return negative, unfit // Expand nodes will always be checked last - non recursive nodes have priority to prevent unnecessary recursion bool used = false; foreach (string to in currentTo) { if (to == "end") { return(fitness); } // For multiple nodes in a network with the same type, will be more useful with more specific and robust networks string generalTo = ""; if (to == "verb_1" || to == "verb_2") { generalTo = "verb"; } else { generalTo = to; } if (_wordList.GetWordType(sentence[currentWord]) == generalTo) { used = true; fitness += 1; currentWord += 1; currentNode = to; break; } else if (network.GetNode(to)._expand) { used = true; // When expanding the node, take sub sentence as input, starting from current word string[] subSentence = new string[sentence.Length - currentWord]; for (int i = currentWord; i < sentence.Length; i++) { subSentence[i - currentWord] = sentence[i]; } int subFitness; if (to == "ornate_noun") { subFitness = GetFrontFitness(subSentence, ornateRTN); } else { subFitness = GetFrontFitness(subSentence, fancyRTN); } fitness += Math.Abs(subFitness); // If the subsentence was unfit, return negative fitness otherwise keep going if (subFitness <= 0) { return(fitness * -1); } else { currentWord += subFitness; currentNode = to; break; } } else { used = false; } } if (!used) { return(fitness * -1); } } } }