private MiniMaxNode MiniMax(BeamNode node) { if (node.Children.Count == 0) { return(new MiniMaxNode(node.Evaluation)); } var best = new MiniMaxNode(node.State.PlayerToMove == Player.One ? int.MinValue : int.MaxValue); foreach (var child in node.Children) { var test = MiniMax(child); if (node.State.PlayerToMove == Player.One) { if (test.Evaluation > best.Evaluation) { best.Move = child.Move; best.Evaluation = test.Evaluation; } } else { if (test.Evaluation < best.Evaluation) { best.Move = child.Move; best.Evaluation = test.Evaluation; } } } return(best); }
internal override IEnumerable <string> GenerateFeatures(BeamNode node) { var targetActivationEvent = BeamGenerator.GetInstanceActivationRequest(PropertySet.Subject, node); var sourceActivationEvent = BeamGenerator.GetInstanceActivationRequest(PropertySet.Value, node); if (targetActivationEvent == null || sourceActivationEvent == null) { yield break; } var ngramLimitCount = 2; var targetSufixes = new InputPhraseEvent[0];//BeamGenerator.GetSufixPhrases(targetActivationEvent.ActivationPhrase, ngramLimitCount, node); var targetPrefixes = BeamGenerator.GetPrefixPhrases(targetActivationEvent.ActivationPhrases.FirstOrDefault(), ngramLimitCount, node); var featureId = "* --" + PropertySet.Property.Name + "--> $1"; var targetId = "$1"; for (var i = 0; i < ngramLimitCount; ++i) { if (targetSufixes.Length > i) { yield return(targetId + " " + ngramFeature(targetSufixes, i) + " | " + featureId); } if (targetPrefixes.Length > i) { yield return(ngramFeature(targetPrefixes, i) + " " + targetId + " | " + featureId); } } }
private void voteForExportedEvents(BeamNode turnStart, BeamNode turnEnd) { var currentNode = turnEnd; while (currentNode != null) { if (currentNode == turnStart) { break; } try { if (!(currentNode.Evt is V4.Events.ExportEvent export)) { continue; } var exportRepresentation = export.ExportedEvent.ToString(); if (_exportedKnowledge.Add(exportRepresentation)) { //in case new information for this dialogue is given, log it LogMessage(exportRepresentation); _knowledge.Vote(export.ExportedEvent); } } finally { currentNode = currentNode.ParentNode; } } }
internal override double GetDefaultScore(BeamNode node) { var descriptions = BeamGenerator.GetDescriptions(Concept, node); var composedPhrase = getComposedPhrase(); return(getSimilarity(composedPhrase, Concept.Name, descriptions)); //TODO solve the descriptions }
public BeamNode(Move move, BeamNode parent, IState state, int depth, int evaluation) { Move = move; Parent = parent; Children = new List <BeamNode>(); State = state; Depth = depth; Evaluation = evaluation; }
internal string GenerateResponse(BeamNode node) { _processedNode = node; _processedEvents = getTurnEvents(node); _completedEvents = new HashSet <EventBase>(); return(generateResponse()); }
private void GetPrevTAndPrevTwoTags(BeamNode <IdValuePair <double> > beamNode, int beamDepth, out int prevT_f, out int prevTwoTags_f) { // Find the feature: prevT={t-1} string prevT_name = beamDepth - 1 < 0 ? "BOS" : classToClassId[beamNode.Item.Id]; string prevT_featureName = string.Format("prevT={0}", prevT_name); prevT_f = featureToFeatureId[prevT_featureName]; // Find the feature: prevTwoTags={t-2}+{t-1}: string prevTwoTags_name = beamDepth - 2 < 0 ? "BOS" : classToClassId[beamNode.PreviousNode.Item.Id]; string prevTwoTags_featureName = string.Format("prevTwoTags={0}+{1}", prevTwoTags_name, prevT_name); prevTwoTags_f = featureToFeatureId[prevTwoTags_featureName]; }
/// <summary><para> /// Calculates the probability of a <c>vector</c>, given a particular class <c>c_i</c>. /// </para><para> /// The features for prevT and prevTwoTags are added to the vector's features, dynamically, /// based on values in the <c>BeamSearch</c> structure. /// </para></summary> private double CalculateProbability_v_c(FeatureVector vector, int c_i, BeamNode <IdValuePair <double> > beamNode, int beamDepth) { int prevT_f, prevTwoTags_f; GetPrevTAndPrevTwoTags(beamNode, beamDepth, out prevT_f, out prevTwoTags_f); // Sum the feature values. double logProb = classifier._lambda_c[c_i]; logProb += classifier.CalculateLogProb_c_f(c_i, prevT_f); logProb += classifier.CalculateLogProb_c_f(c_i, prevTwoTags_f); for (int u_i = 0; u_i < vector.UsedFeatures.Length; u_i++) { int f_i = vector.UsedFeatures[u_i]; logProb += classifier.CalculateLogProb_c_f(c_i, f_i); } return(logProb); }
private EventBase[] getTurnEvents(BeamNode node) { var turnEvents = new List <EventBase>(); var currentNode = node; while (currentNode != null) { if (currentNode.Evt is TurnStartEvent) { break; } turnEvents.Add(currentNode.Evt); currentNode = currentNode.ParentNode; } return(turnEvents.ToArray()); }
internal string Input(string originalSentence) { Log.DialogUtterance("U: " + originalSentence); var words = Phrase.AsWords(originalSentence.ToLower()); string response; if (words.Length > 10) { response = "I'm sorry, the sentence is too long. Try to use simpler sentences please."; } else { _beam.PushToAll(new TurnStartEvent()); foreach (var word in words) { if (_irrelevantWords.Contains(word)) { //TODO for computational efficiency skip non important words continue; } _beam.LimitBeam(500); _beam.PushInput(word); } _beam.PushToAll(new TurnEndEvent()); Log.States(_beam, 1); _beam.LimitBeam(1); var nlg = new EventBasedNLG(); response = nlg.GenerateResponse(_beam.GetBestNode()); } Log.DialogUtterance("S: " + response); LastOutput = response; LastBestNode = _beam.GetBestNode(); return(response); }
internal override double GetDefaultScore(BeamNode node) { return(Score); }
internal abstract IEnumerable <string> GenerateFeatures(BeamNode node);
internal abstract double GetDefaultScore(BeamNode node);
internal static void State(BeamNode node) { var events = new List <EventBase>(); var currentNode = node; while (currentNode != null && currentNode.Evt != null) { events.Add(currentNode.Evt); currentNode = currentNode.ParentNode; } events.Reverse(); foreach (var evt in events) { var color = ItemColor; if (evt is TurnStartEvent || evt is TurnEndEvent || evt is FrameEvent) { color = PolicyColor; } if (evt is InstanceOutputEvent || evt is ExportEvent) { color = ExecutedCommandColor; } if (evt is InputPhraseEvent || evt is OutputEvent) { color = UtteranceColor; } if (evt is ConceptDescriptionEvent || evt is ConceptDefinedEvent) { color = ConsoleColor.Yellow; } if (evt is TurnEndEvent) { Dedent(); } if (evt is TracedScoreEventBase) { var scoreEvt = evt as TracedScoreEventBase; var score = BeamGenerator.GetScore(scoreEvt, node); var scoreText = score.ToString("0.00"); if (score >= 0) { scoreText = "+" + scoreText; } Writeln($"[{scoreText}]", color); continue; } Writeln(evt.ToString(), color); if (evt is TurnStartEvent) { Indent(); } } }
internal override IEnumerable <string> GenerateFeatures(BeamNode node) { yield break; }
internal override double GetDefaultScore(BeamNode node) { return(Configuration.ParameterSubstitutionScore / (1 + _distancePenalty)); }
private Move GetBestMove(IState start) { var root = new BeamNode(null, null, start, 0, 0); var set = new List <BeamNode>(); var beam = new List <BeamNode>(); beam.Add(root); var startingPlayer = start.PlayerToMove; var terminateSearch = false; while (beam.Count != 0 && !terminateSearch) { set.Clear(); var playerToMove = Player.None; if (beam.Count > 0) { playerToMove = beam[0].State.PlayerToMove; } for (int i = 0; i < beam.Count; i++) { _visitedNodes++; var node = beam[i]; if (cancel.Cancelled) { terminateSearch = true; break; } var moves = node.State.GetAllMoves(); foreach (var move in moves) { var copy = node.State.Clone(); copy.MakeMove(move); var eval = copy.Evaluate(node.Depth + 1); var winner = copy.GetWinner(); if (winner == startingPlayer && winner == playerToMove) { terminateSearch = true; } var child = new BeamNode(move, node, copy, node.Depth + 1, eval); node.Children.Add(child); set.Add(child); } } beam.Clear(); if (playerToMove == Player.One) { beam.AddRange(set.OrderByDescending(x => x.Evaluation).Take(_beamWidth)); } else { beam.AddRange(set.OrderBy(x => x.Evaluation).Take(_beamWidth)); } } // Perform a full minimax search, but only on the tree built out by a depth-first search return(MiniMax(root).Move); }