|
@@ -1,188 +0,0 @@
|
|
|
-// Author: Orlys
|
|
|
-// Github: https://github.com/Orlys
|
|
|
-
|
|
|
-namespace Yuuna.Contracts.Optimization
|
|
|
-{
|
|
|
- using System;
|
|
|
- using System.Collections.Generic;
|
|
|
- using System.Collections.Immutable;
|
|
|
- using System.Diagnostics.CodeAnalysis;
|
|
|
- using System.Linq;
|
|
|
- using System.Runtime.CompilerServices;
|
|
|
-
|
|
|
- using Yuuna.Contracts.Patterns;
|
|
|
- using Yuuna.Contracts.Plugins;
|
|
|
- using Yuuna.Contracts.Semantics;
|
|
|
-
|
|
|
- public abstract class Plan
|
|
|
- {
|
|
|
- public Plan()
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public void FindBest(IEnumerable<PluginBase> plugins, IImmutableList<string> feed)
|
|
|
- {
|
|
|
- var list = ImmutableArray.CreateBuilder<Match>();
|
|
|
- foreach (var plugin in plugins)
|
|
|
- {
|
|
|
- foreach (var p in plugin.Patterns.ToImmutable())
|
|
|
- {
|
|
|
- var score = this.CalculatePatternMatch(p, feed);
|
|
|
- if (score.HasValue)
|
|
|
- list.Add(score.Value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- var e = this.E(list.ToImmutable());
|
|
|
- }
|
|
|
-
|
|
|
- protected virtual void E(IImmutableList<Match> matches)
|
|
|
- {
|
|
|
- var sta = new SortedList<Match, int>();
|
|
|
- foreach (var j in matches)
|
|
|
- {
|
|
|
- if (!sta.ContainsKey(j))
|
|
|
- sta.Add(j, 1);
|
|
|
- else
|
|
|
- sta[j]++;
|
|
|
- }
|
|
|
-
|
|
|
- var tuple = new List<Tuple<Match, double>>();
|
|
|
- foreach (var s in sta)
|
|
|
- {
|
|
|
- var x = (s.Value) / (double)-(matches.Count * s.Key.SequentialMatches.Count);
|
|
|
- var y = Math.Tanh(Math.Pow(Math.E, x));
|
|
|
- tuple.Add(Tuple.Create(s.Key, y));
|
|
|
- }
|
|
|
-
|
|
|
- foreach (var s in tuple.OrderByDescending(x => x.Item2))
|
|
|
- {
|
|
|
- Console.WriteLine(s);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 評估 <paramref name="pattern"/> 與 <paramref name="feed"/> 的符合程度並給予一個分數,並返回一個 <see cref="Match"/> 物件。
|
|
|
- /// 若回傳 <see langword="null"/> 則此規則將不列入計算。
|
|
|
- /// </summary>
|
|
|
- /// <param name="pattern"></param>
|
|
|
- /// <param name="feed"></param>
|
|
|
- /// <returns></returns>
|
|
|
- protected virtual Match? CalculatePatternMatch(IPattern pattern, IImmutableList<string> feed)
|
|
|
- {
|
|
|
- var matches = ImmutableArray.CreateBuilder<ISynonym>();
|
|
|
-
|
|
|
- using (var iterator = pattern.ToImmutable().GetEnumerator())
|
|
|
- {
|
|
|
- iterator.MoveNext();
|
|
|
- foreach (var word in feed)
|
|
|
- {
|
|
|
- if (iterator.Current.TryGetSynonym(word, out var s))
|
|
|
- {
|
|
|
- matches.Add(s);
|
|
|
- if (!iterator.MoveNext())
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return new Match(pattern, matches.ToImmutable());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public struct Match : IEquatable<Match>
|
|
|
- {
|
|
|
- /// <summary>
|
|
|
- /// 比較的文法。
|
|
|
- /// </summary>
|
|
|
- public IPattern Pattern { get; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 表示缺少的群組物件清單。
|
|
|
- /// </summary>
|
|
|
- public IImmutableList<IGroup> Missing { get; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// </summary>
|
|
|
- public IImmutableList<ISynonym> SequentialMatches { get; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- ///
|
|
|
- /// </summary>
|
|
|
- /// <param name="pattern">比對的目標</param>
|
|
|
- /// <param name="matches">從頭逐一比對後符合的項目</param>
|
|
|
- public Match(IPattern pattern, IImmutableList<ISynonym> matches)
|
|
|
- {
|
|
|
- this.Pattern = pattern;
|
|
|
- this.SequentialMatches = matches;
|
|
|
- this.Missing = pattern.ToImmutable().Except(matches.Select(x => x.Owner)).ToImmutableArray();
|
|
|
- }
|
|
|
-
|
|
|
- public bool Equals(Match other)
|
|
|
- {
|
|
|
- return this.Pattern.Equals(other.Pattern);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public abstract class StrategyBase
|
|
|
- {
|
|
|
- public abstract string Name { get; }
|
|
|
-
|
|
|
- protected abstract IComparer<IScore> Comparer { get; }
|
|
|
-
|
|
|
- protected StrategyBase()
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 評估 <paramref name="plugin"/> 中最佳的
|
|
|
- /// </summary>
|
|
|
- /// <param name="plugin"></param>
|
|
|
- /// <param name="words"></param>
|
|
|
- /// <param name="set"></param>
|
|
|
- /// <returns></returns>
|
|
|
- internal IImmutableList<IScore> Assess(PluginBase plugin, IImmutableList<string> words, IPatternSet set)
|
|
|
- {
|
|
|
- var scores = new List<IScore>();
|
|
|
- var immutable = set.ToImmutable();
|
|
|
- foreach (var pattern in immutable)
|
|
|
- {
|
|
|
- var score = this.Evaluate(plugin, words, pattern);
|
|
|
- if (score.SequentialMatches.Count > 0) // 過濾掉符合為 0 的文法
|
|
|
- scores.Add(score);
|
|
|
- }
|
|
|
- scores.Sort(this.Comparer);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- return scores.ToImmutableArray();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 評估 <paramref name="pattern"/> 與 <paramref name="words"/> 的符合程度,並返回評估後的分數物件
|
|
|
- /// </summary>
|
|
|
- /// <param name="words"></param>
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- private IScore Evaluate(IImmutableList<string> words, IPattern pattern)
|
|
|
- {
|
|
|
- var matches = ImmutableArray.CreateBuilder<IPair>();
|
|
|
-
|
|
|
- using (var iterator = pattern.ToImmutable().GetEnumerator())
|
|
|
- {
|
|
|
- iterator.MoveNext();
|
|
|
- foreach (var word in words)
|
|
|
- {
|
|
|
- if (iterator.Current.TryGetSynonym(word, out var s))
|
|
|
- {
|
|
|
- matches.Add(new Pair(s.Owner.Key, s));
|
|
|
- if (!iterator.MoveNext())
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return new Score(matches.ToImmutable(), pattern);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|