コード例 #1
0
        /// <summary>
        /// </summary>
        /// <param name="before"></param>
        /// <param name="after"></param>
        public VRiscuitRule(IBeforePattern before, IAfterPattern after, ScoreCoefficient sce, bool isDebug = false)
        {
            BeforePattern    = before;
            AfterPattern     = after;
            _coefficient     = sce;
            _beforeObjectSet = BeforePattern.VRiscuitObjects;
            _afterObjectSet  = AfterPattern.ResultObjectSet;
            _genDelTable     = new Dictionary <string, int>(_afterObjectSet.DistributionTable);
            IsDebug          = isDebug;
            foreach (var kvp in _beforeObjectSet.DistributionTable)
            {
                if (_genDelTable.ContainsKey(kvp.Key))
                {
                    _genDelTable[kvp.Key] -= kvp.Value;
                }
                else
                {
                    _genDelTable.Add(kvp.Key, -kvp.Value);
                }
                if (_genDelTable[kvp.Key] != 0)
                {
                    isGenerateOrDeleteObject = true;
                }
            }
            // alphaの値をルールの動き量で決める
            var afterParam = new VRiscuitObjectSet(_afterObjectSet).ToParameters();
            var beforeSet  = new VRiscuitObjectSet(_beforeObjectSet);

            GenerateOrDeleteObject(beforeSet, null);
            var beforeParam = beforeSet.ToParameters();

            _paramLength = TwoArrayDistance(afterParam, beforeParam);
        }
コード例 #2
0
ファイル: Candidate.cs プロジェクト: bouro412/VRiscuit
 public Candidate(IRule rule, IVRiscuitObjectSet table, float score)
 {
     _rule              = rule;
     _table             = table;
     Score              = score;
     NotNormalizedScore = score;
 }
コード例 #3
0
        public static float[] CalcAppliedFieldScore(IVRiscuitObjectSet currentField, IVRiscuitObjectSet beforeField, IVRiscuitObjectSet afterRuleSet, IVRiscuitObjectSet beforeRuleSet, ScoreCoefficient ef)
        {
            var score = 0.0f;
            var max   = 0.0f;
            var beforeRuleSetArray = beforeRuleSet.ObjectArray;
            var afterRuleSetArray  = afterRuleSet.ObjectArray;
            var beforeFieldArray   = beforeField.ObjectArray;
            var currentFieldArray  = currentField.ObjectArray;
            var currentSize        = currentField.Size;
            var beforeSize         = beforeField.Size;

            for (int a = 0; a < currentSize; a++)
            {
                for (int b = 0; b < beforeSize; b++)
                {
                    var f = CalcTwoObjectSimilarity(beforeRuleSetArray[b], afterRuleSetArray[a], beforeFieldArray[b], currentFieldArray[a], ef);
                    score += f[0];
                    max   += f[1];
                }
            }
            var cc = CalcScore(afterRuleSet, currentField, ef);

            score += cc[0];
            max   += cc[1];
            return(new float[] { score, max });
        }
コード例 #4
0
 /// <summary>
 /// オブジェクト集合のコピー
 /// 実体のないcalculateObjectで構成する
 /// </summary>
 /// <param name="source"></param>
 public VRiscuitObjectSet(IVRiscuitObjectSet source)
 {
     _table = new Dictionary <string, List <IVRiscuitObject> >();
     foreach (var kvp in source.TypeTable)
     {
         _table.Add(kvp.Key, kvp.Value.Select(obj => new CalculateObject(obj) as IVRiscuitObject).ToList());
     }
 }
コード例 #5
0
ファイル: Candidate.cs プロジェクト: bouro412/VRiscuit
 public Candidate(IRule rule, IVRiscuitObjectSet table, float[] scores)
 {
     _rule  = rule;
     _table = table;
     // オブジェクト個数で優遇する
     Score = RuleManager.NormalizeScore(scores) * _table.Size;
     NotNormalizedScore = scores[0];
 }
コード例 #6
0
 private void GenerateOrDeleteObject(IVRiscuitObjectSet objset, IVRiscuitObjectSet globalTable)
 {
     if (isGenerateOrDeleteObject == false)
     {
         return;
     }
     foreach (var kvp in _genDelTable)
     {
         var val = kvp.Value;
         if (val < 0)
         {
             var objs = objset.TypeTable[kvp.Key];
             if (objs.Count < -val)
             {
                 Debug.LogError("Error: 必要な数のオブジェクトがありません。");
                 if (globalTable != null)
                 {
                     foreach (var obj in objs)
                     {
                         globalTable.Delete(obj);
                         objset.Delete(obj);
                     }
                 }
                 return;
             }
             for (int i = 0; i < -val; i++)
             {
                 if (globalTable != null)
                 {
                     globalTable.Delete(objs[0]);
                 }
                 objset.Delete(objs[0]);
             }
         }
         else if (val > 0)
         {
             var first     = objset.First();
             var generated = new List <CalculateObject>();
             for (int i = 0; i < val; i++)
             {
                 var pos = new Vector3(first.Position.x + 1, first.Position.y, first.Position.z);
                 var rot = Quaternion.Euler(first.Rotation.eulerAngles.x, first.Rotation.eulerAngles.y, first.Rotation.eulerAngles.z);
                 var o   = new CalculateObject(pos, rot, kvp.Key);
                 objset.Add(o);
                 generated.Add(o);
             }
             _generatedObjects = generated;
         }
     }
 }
コード例 #7
0
        protected IEnumerable <List <IVRiscuitObject> > SameNumberObjectGroupsByType(IVRiscuitObjectSet objectSet, IVRiscuitObjectSet ruleBeforeSet)
        {
            var typesAndObjs = new List <List <List <IVRiscuitObject> > >();

            foreach (var kvp in ruleBeforeSet.TypeTable)
            {
                var currentObjs = CurrentObjectSet.GetByType(kvp.Key);
                if (currentObjs == null || currentObjs.Count < kvp.Value.Count)
                {
                    return(null);
                }
                typesAndObjs.Add(Permutation(currentObjs, kvp.Value.Count()).ToList());
            }
            var choice = Choice(typesAndObjs);
            var c      = choice.ToList();
            var result = choice.Select(Flatten);
            var a      = result.ToList();

            return(result);
        }
コード例 #8
0
        /// <summary>
        /// ルールの適用
        /// </summary>
        /// <param name="objectsTable"></param>
        void IRule.Apply(IVRiscuitObjectSet objectsTable, IVRiscuitObjectSet globalTable)
        {
            var beforeTable = new VRiscuitObjectSet(objectsTable);

            GenerateOrDeleteObject(objectsTable, globalTable);
            DescentMethod(objectsTable, beforeTable, _afterObjectSet, _beforeObjectSet);
            // 追加されたオブジェクトをmanagerのobjectSetに追加
            if (_generatedObjects == null)
            {
                return;
            }
            foreach (var obj in _generatedObjects)
            {
                if (IsDebug)
                {
                    globalTable.Add(obj);
                    continue;
                }
            }
            _generatedObjects = null;
        }
コード例 #9
0
        /// <summary>
        /// Rule上のオブジェクトとフィールドのオブジェクトがどれだけ近い関係にあるかを計算
        /// </summary>
        /// <param name="ruleObjectSet"></param>
        /// <param name="fieldObjectSet"></param>
        /// <param name="ef"></param>
        /// <returns></returns>
        public static float[] CalcScore(IVRiscuitObjectSet ruleObjectSet, IVRiscuitObjectSet fieldObjectSet, ScoreCoefficient ef)
        {
            var score           = 0.0f;
            var max             = 0.0f;
            var ruleObjectList  = ruleObjectSet.ObjectArray;
            var fieldObjectList = fieldObjectSet.ObjectArray;
            var len             = fieldObjectList.Length;

            if (len == 1)
            {
                return(new float[] { 10, 10 });
            }
            for (int i = 0; i < len - 1; i++)
            {
                for (int j = i + 1; j < len; j++)
                {
                    var fs = CalcTwoObjectSimilarity(ruleObjectList[i], ruleObjectList[j],
                                                     fieldObjectList[i], fieldObjectList[j], ef);
                    score += fs[0];
                    max   += fs[1];
                }
            }
            return(new float[] { score, max });
        }
コード例 #10
0
ファイル: BeforePattern.cs プロジェクト: bouro412/VRiscuit
 public BeforePattern(IVRiscuitObjectSet objects)
 {
     _vriscuitObjects = objects;
 }
コード例 #11
0
        /// <summary>
        /// 最急降下法で最適な位置を計算する
        /// </summary>
        /// <param name="currentTable"></param>
        /// <param name="beforeRuleTable"></param>
        /// <param name="afterRuleTable"></param>
        /// <param name="changes"></param>
        private void DescentMethod(IVRiscuitObjectSet currentTable, IVRiscuitObjectSet beforeTable, IVRiscuitObjectSet afterRuleTable, IVRiscuitObjectSet beforeRuleTable)
        {
            var limit       = 100;
            var beforeScore = 0.0f;
            var beforec     = new VRiscuitObjectSet(beforeTable);
            var currentc    = new VRiscuitObjectSet(currentTable);
            var parameters  = currentc.ToParameters();
            var firstParam  = currentc.ToParameters();
            var beforeDelta = new float[parameters.Length];

            Func <float[], float> func = delegate(float[] param)
            {
                (currentc as IVRiscuitObjectSet).SetParameter(param);
                var scores = RuleManager.CalcAppliedFieldScore(currentc, beforec, afterRuleTable, beforeRuleTable, (this as IRule).RuleScoreCoefficient);
                return(scores[0] / scores[1]);
            };
            var alpha = _paramLength;

            var f = 0.001; // scoreの変動がこの値以下になったら終わり

            for (int i = 0; i < limit; i++)
            {
                var score = func(parameters);
                // var message = String.Format("{0}: {1}, {2}, {3}, {5}, {6}, {7} => {4} points", i, parameters[0], parameters[1], parameters[2], score, parameters[3], parameters[4], parameters[5]);
                //Debug.Log(message);
                // Debug.Log("alpha = " + alpha);
                if (Mathf.Abs(beforeScore - score) <= f && i != 0)
                {
                    // 終了
                    break;
                }
                beforeScore = score;
                var delta = Differential(func, parameters);
                delta = NormalizeArray(delta);

                // deltaの中に0の要素があったら、beforeDeltaをもとに前回の変更を半分もとに戻す
                // その場合次のbeforeDeltaは
                // 同時にbeforeDeltaの更新
                for (int di = 0; di < delta.Length; di++)
                {
                    if (delta[di] == 0)
                    {
                        delta[di]        = -(beforeDelta[di] / 2);
                        beforeDelta[di] /= 2;
                    }
                    else
                    {
                        beforeDelta[di] = delta[di];
                    }
                }

                // Debug.Log("delta = " + delta.Skip(1).Aggregate(delta[0].ToString(), (acc, next) => acc + ", " + next.ToString()));
                for (int j = 0; j < parameters.Length; j++)
                {
                    parameters[j] += delta[j] * alpha;
                }
                // Debug.Log("parameter = " + parameters.Skip(1).Aggregate(parameters[0].ToString(), (acc, next) => acc + ", " + next.ToString()));
                alpha *= Mathf.Max((float)Math.Exp(-alpha), 0.1f);
            }
            // オブジェクトの生成、削除がある場合には、1fで動かす
            // そうでない場合には、1秒かけて動かすように調整する
            if (!isGenerateOrDeleteObject)
            {
                var len = firstParam.Length;
                var d   = new float[len];
                for (int i = 0; i < len; i++)
                {
                    var di = parameters[i] - firstParam[i];
                    // 細かい部分を四捨五入, 秒間スピードに変更
                    di            = ((float)Math.Round(di, 1)) * Time.deltaTime;
                    parameters[i] = firstParam[i] + di;
                }
            }
            currentTable.SetParameter(parameters);
        }
コード例 #12
0
ファイル: Candidate.cs プロジェクト: bouro412/VRiscuit
 public void RuleApply(IVRiscuitObjectSet globalTable)
 {
     _rule.Apply(_table, globalTable);
 }
コード例 #13
0
 public RuleManagerTest(IVRiscuitObjectSet objset, IEnumerable <IRule> rules) : base(objset, rules)
 {
 }
コード例 #14
0
 public RuleManager(IVRiscuitObjectSet objects, IEnumerable <IRule> rules)
 {
     VRiscuitPrefavTable = new Dictionary <string, GameObject>();
     CurrentObjectSet    = objects;
     _rules = rules.ToList();
 }
コード例 #15
0
 public AfterPattern(IVRiscuitObjectSet objects)
 {
     _objects = objects;
 }