void Simplify()
    {
        var rationAtLevel = 1f;
        var rScale        = 1.0f / scale;

        for (var level = 0; level < recursionLevel; level++)
        {
            rationAtLevel *= ratio;
            var target = (GameObject)Instantiate(prefab);
            target.transform.parent = parent;
            var meshfilters = target.GetComponentsInChildren <MeshFilter>();
            for (var i = 0; i < meshfilters.Length; i++)
            {
                var mesh            = meshfilters[i].mesh;
                var vertices        = mesh.vertices.Select((v) => v * scale).ToArray();
                var simp            = new Simplification(vertices, mesh.triangles);
                var targetFaceCount = (int)(rationAtLevel * mesh.triangles.Length / 3);
                while (targetFaceCount < simp.faceDb.FaceCount)
                {
                    var edge = simp.costs.RemoveFront();
                    simp.CollapseEdge(edge);
                }
                Vector3[] outVertices;
                int[]     outTriangles;
                simp.ToMesh(out outVertices, out outTriangles);
                Debug.Log(string.Format("Simplification step {0}/{1}, face {2}/{3}",
                                        i, meshfilters.Length, outTriangles.Length / 3, mesh.triangles.Length / 3));
                mesh.Clear();
                mesh.vertices  = outVertices.Select((v) => v * rScale).ToArray();
                mesh.triangles = outTriangles;
                mesh.RecalculateNormals();
            }
        }
    }
    IEnumerator Collapse()
    {
        while (enabled) {
            yield return 0;

            lock (this) {
                if (_reductionInProgress)
                    continue;

                if (_sphere.vertexCount < 10) {
                    UpdateSphere();
                    yield return new WaitForSeconds(2f);
                    isoSphere.Reset();
                    _sphere = isoSphere.GetComponent<MeshFilter>().mesh;
                    _simp = new Simplification(_sphere.vertices, _sphere.triangles);
                    _outVertices = null;
                }

                _reductionInProgress = true;
                if (_outVertices != null)
                    UpdateSphere();
                var targetEdgeCount = (int)(bulkReduction * _simp.costs.Count);
                ThreadPool.QueueUserWorkItem(new WaitCallback(Reduction), targetEdgeCount);
            }
        }
    }
    IEnumerator Collapse()
    {
        while (enabled)
        {
            yield return(0);

            lock (this) {
                if (_reductionInProgress)
                {
                    continue;
                }

                if (_sphere.vertexCount < 10)
                {
                    UpdateSphere();
                    yield return(new WaitForSeconds(2f));

                    isoSphere.Reset();
                    _sphere      = isoSphere.GetComponent <MeshFilter>().mesh;
                    _simp        = new Simplification(_sphere.vertices, _sphere.triangles);
                    _outVertices = null;
                }

                _reductionInProgress = true;
                if (_outVertices != null)
                {
                    UpdateSphere();
                }
                var targetEdgeCount = (int)(bulkReduction * _simp.costs.Count);
                ThreadPool.QueueUserWorkItem(new WaitCallback(Reduction), targetEdgeCount);
            }
        }
    }
 void Simplify()
 {
     var rationAtLevel = 1f;
     var rScale = 1.0f / scale;
     for (var level = 0; level < recursionLevel; level++) {
         rationAtLevel *= ratio;
         var target = (GameObject)Instantiate(prefab);
         target.transform.parent = parent;
         var meshfilters = target.GetComponentsInChildren<MeshFilter>();
         for (var i = 0; i < meshfilters.Length; i++) {
             var mesh = meshfilters[i].mesh;
             var vertices = mesh.vertices.Select((v) => v * scale).ToArray();
             var simp = new Simplification(vertices, mesh.triangles);
             var targetFaceCount = (int)(rationAtLevel * mesh.triangles.Length / 3);
             while (targetFaceCount < simp.faceDb.FaceCount) {
                 var edge = simp.costs.RemoveFront();
                 simp.CollapseEdge(edge);
             }
             Vector3[] outVertices;
             int[] outTriangles;
             simp.ToMesh(out outVertices, out outTriangles);
             Debug.Log(string.Format("Simplification step {0}/{1}, face {2}/{3}",
                 i, meshfilters.Length, outTriangles.Length / 3, mesh.triangles.Length / 3));
             mesh.Clear();
             mesh.vertices = outVertices.Select((v) => v * rScale).ToArray();
             mesh.triangles = outTriangles;
             mesh.RecalculateNormals();
         }
     }
 }
    void Start()
    {
        _sphere = isoSphere.GetComponent <MeshFilter>().mesh;
        _simp   = new Simplification(_sphere.vertices, _sphere.triangles);

        StartCoroutine("Collapse");
    }
示例#6
0
        private void btnSimplificar_Click(object sender, EventArgs e)
        {
            btnGerar_Click(null, null);
            simplificao = new Simplification(g);

            lbVazios.Items.Clear();
            lbVazios.Items.AddRange(simplificao.VariablesEmpty.Cast <Object>().ToArray());
            lbRegrasSemVazio.Items.Clear();
            lbRegrasSemVazio.Items.AddRange(simplificao.GrammarNoEmpty.Rules.ToArray());
            lbFecho.Items.Clear();
            lbFecho.Items.AddRange(simplificao.FastenersString.ToArray());

            lbProducoesFechos.Items.Clear();
            lbProducoesFechos.Items.AddRange(simplificao.GrammarNoUnitarianProductions.Rules.ToArray());

            lbVariaveisAcessamTerminais.Items.Clear();
            lbVariaveisAcessamTerminais.Items.AddRange(simplificao.VariablesCallTerminals.Cast <Object>().ToArray());

            lbVariaveisAcessiveis.Items.Clear();
            lbVariaveisAcessiveis.Items.AddRange(simplificao.AcessiblesVariables.Cast <Object>().ToArray());

            lbTerminaisAcessiveis.Items.Clear();
            lbTerminaisAcessiveis.Items.AddRange(simplificao.AcessiblesTerminals.Cast <Object>().ToArray());

            lbProducoesFinais.Items.Clear();
            lbProducoesFinais.Items.AddRange(simplificao.Simplified.Rules.ToArray());
        }
        private IExpressionType doCustomFunc(Function f, FunctionDefenition fd)
        {
            Context        ctx  = Context.getInstance();
            Computator     comp = new Computator();
            Simplification s    = new Simplification();

            // вычисления кастомных функций
            if (f.getOperands().Count != fd.getParams().Count)
            {
                throw new Exception("Not equal number of params");
            }

            ctx.getIn(fd.getContext()); // get into right context

            bool[]            wasBefore   = new bool[fd.getParams().Count];
            IExpressionType[] expressions = new IExpressionType[fd.getParams().Count];

            for (int p = 0; p < fd.getParams().Count; p++) // add params to scope
            {
                if (ctx.exists(fd.getParams()[p].getValue(), ctx.getCurrPath()) == -1)
                {
                    wasBefore[p] = false;
                    ctx.addVariable(fd.getParams()[p].getValue(), ctx.getCurrPath(), f.getOperands()[p]);
                }
                else
                {
                    wasBefore[p]   = true;
                    expressions[p] = ctx.getVariableValue(fd.getParams()[p].getValue(), ctx.getCurrPath());
                    ctx.changeVariable(fd.getParams()[p].getValue(), ctx.getCurrPath(), f.getOperands()[p]);
                }
            }

            List <IExpressionType> nl = new List <IExpressionType>();

            foreach (var op in fd.getOperands())
            {
                nl.Add(op.doOperation(comp));
            }

            for (int p = 0; p < fd.getParams().Count; p++) //remove params from scope
            {
                if (!wasBefore[p])
                {
                    ctx.removeVariable(fd.getParams()[p].getValue(), ctx.getCurrPath());
                }
                else
                {
                    ctx.changeVariable(fd.getParams()[p].getValue(), ctx.getCurrPath(), expressions[p]);
                }
            }

            //OUT
            ctx.getOut();
            IExpressionType n = nl[nl.Count - 1];

            return((IMathExpression)(n.getType() == Types.FuncExpression ? s.simplify((Function)n) : n));
        }
    void Start()
    {
        _mesh = primitive.GetComponent<MeshFilter>().mesh;
        _simp = new Simplification(_mesh.vertices, _mesh.triangles);

        _nextUpdateTime = Time.time + updateInterval;

        if (!interactive)
            StartCoroutine("Collapse");
    }
示例#9
0
    void Start()
    {
        _mesh = planeObj.GetComponent <MeshFilter>().mesh;
        _simp = new Simplification(_mesh.vertices, _mesh.triangles);

        _nextUpdateTime = Time.time + updateInterval;

        if (!interactive)
        {
            StartCoroutine("Collapse");
        }
    }
示例#10
0
        /// <summary>
        /// Attempts to simplify the structure of the automaton, reducing the number of states and transitions.
        /// </summary>
        public bool Simplify()
        {
            var builder        = Builder.FromAutomaton(this);
            var simplification = new Simplification(builder, this.PruneStatesWithLogEndWeightLessThan);

            if (simplification.Simplify())
            {
                this.Data = builder.GetData();
                return(true);
            }

            return(false);
        }
示例#11
0
        /// <summary>
        /// Optimizes the automaton by removing all states which can't reach end states.
        /// </summary>
        public bool RemoveDeadStates()
        {
            var builder        = Builder.FromAutomaton(this);
            var simplification = new Simplification(builder, this.PruneTransitionsWithLogWeightLessThan);

            if (simplification.RemoveDeadStates())
            {
                this.Data = builder.GetData();
                return(true);
            }

            return(false);
        }
示例#12
0
        /// <summary>
        /// Attempts to simplify the structure of the automaton, reducing the number of states and transitions.
        /// </summary>
        /// <param name="result">Result automaton. Simplified automaton, if the operation was successful, current automaton otherwise.</param>
        /// <returns><see langword="true"/> if the simplification was successful, <see langword="false"/> otherwise.</returns>
        public bool Simplify(out TThis result)
        {
            var builder        = Builder.FromAutomaton(this);
            var simplification = new Simplification(builder, this.PruneStatesWithLogEndWeightLessThan);

            if (simplification.Simplify())
            {
                result = WithData(builder.GetData());
                return(true);
            }

            result = (TThis)this;
            return(false);
        }
示例#13
0
        /// <summary>
        /// Optimizes the automaton by removing all states which can't reach end states.
        /// </summary>
        public bool RemoveDeadStates()
        {
            var builder            = Builder.FromAutomaton(this);
            var initialStatesCount = builder.StatesCount;
            var simplification     = new Simplification(builder, this.PruneStatesWithLogEndWeightLessThan);

            simplification.RemoveDeadStates();
            if (builder.StatesCount != initialStatesCount)
            {
                this.Data = builder.GetData();
                return(true);
            }

            return(false);
        }
示例#14
0
        public void HypothesisTest()
        {
            bool[] actual =
            {
                true,  true,  true, true,   // 4
                true,  true,  true, true,   // 8
                true,  true,  true, true,   // 12
                true,  true,  true, true,   // 16
                true,  true,  true, true,   // 20
                true,  true,  true, true,   // 24
                true,  true,  true, true,   // 28
                true,  true,  true, true,   // 32

                false, false, false, false, // 4
                false, false, false, false, // 8
                false, false, false, false, // 12
                false, false, false, false, // 16
                false, false, false, false, // 20
                false, false, false, false, // 24
                false, false, false, false, // 28
                false, false, false, false, // 32
            };

            bool[] expected =
            {
                true,  true,  true, true,   // 4
                true,  true,  true, true,   // 8
                true,  true,  true, true,   // 12
                true,  true,  true, true,   // 16
                false, false, false, false, // 4
                false, false, false, false, // 8
                false, false, false, false, // 12
                false, false, false, false, // 16

                false, false, false, false, // 4
                false, false, false, false, // 8
                false, false, false, false, // 12
                false, false, false, false, // 16
                false, false, false, false, // 20
                true,  true,  true, true,   // 4
                true,  true,  true, true,   // 8
                true,  true,  true, true,   // 12
            };

            Assert.IsTrue(Simplification.CanEliminate(actual, expected, 0.05));
            Assert.IsFalse(Simplification.CanEliminate(expected, expected, 0.05));
            Assert.IsFalse(Simplification.CanEliminate(actual, actual, 0.05));
        }
示例#15
0
        /// <summary>
        /// Optimizes the automaton by removing all states which can't reach end states.
        /// </summary>
        /// <returns>Result automaton. Simplified automaton, if there were states to be removed, current automaton otherwise.</returns>
        public TThis RemoveDeadStates()
        {
            var builder            = Builder.FromAutomaton(this);
            var initialStatesCount = builder.StatesCount;
            var simplification     = new Simplification(builder, this.PruneStatesWithLogEndWeightLessThan);

            simplification.RemoveDeadStates();
            if (builder.StatesCount != initialStatesCount)
            {
                return(WithData(builder.GetData()));
            }
            else
            {
                return((TThis)this);
            }
        }
示例#16
0
    void Start()
    {
        voxels = WorldGenerator.CreateVoxels(65, 0, 1, Vector3.zero);

        data = MarchingCubes.CalculateMeshData(voxels, 1);
        data.CalculateVertexSharing();
        data.CalculateNormals();

        simp = new Simplification(data.vertices, data.triangles);

        mesh = data.CreateMesh();

        go               = SplitManager.GetObject();
        go.mr.material   = mat;
        go.mf.sharedMesh = mesh;
    }
示例#17
0
        public void LargeRunTest()
        {
            double[][]   inputs;
            int[]        outputs;
            DecisionTree tree = createTree(out inputs, out outputs);

            var rules = DecisionSet.FromDecisionTree(tree);

            Simplification simpl = new Simplification(rules);
            double         error = simpl.ComputeError(inputs, outputs);

            Assert.AreEqual(0, error);

            double newError = simpl.Compute(inputs, outputs);

            Assert.AreEqual(0.067515432098765427, newError);
        }
示例#18
0
        public void LargeRunTest2()
        {
            Accord.Math.Random.Generator.Seed = 0;

            int[,] random = Matrix.Random(1000, 10, 0.0, 10.0).ToInt32();

            int[][] samples = random.ToJagged();
            int[]   outputs = new int[1000];

            for (int i = 0; i < samples.Length; i++)
            {
                if (samples[i][0] > 5 || Tools.Random.NextDouble() > 0.85)
                {
                    outputs[i] = 1;
                }
            }

            DecisionVariable[] vars = new DecisionVariable[10];
            for (int i = 0; i < vars.Length; i++)
            {
                vars[i] = new DecisionVariable("x" + i, 10);
            }

            DecisionTree tree = new DecisionTree(vars, 2);

            var teacher = new ID3Learning(tree);

            double error = teacher.Run(samples, outputs);

            Assert.AreEqual(0, error);

            var rules = DecisionSet.FromDecisionTree(tree);

            Simplification simpl = new Simplification(rules)
            {
                Alpha = 0.05
            };

            error = simpl.ComputeError(samples.ToDouble(), outputs);
            Assert.AreEqual(0, error);

            double newError = simpl.Compute(samples.ToDouble(), outputs);

            Assert.AreEqual(0.097, newError);
        }
示例#19
0
    IEnumerator Collapse()
    {
        while (true) {
            yield return 0;

            if (_simp.costs.Count <= 5) {
                UpdateMesh ();
                yield return new WaitForSeconds(2f);
                _mesh = primitive.Reset();
                _simp = new Simplification(_mesh.vertices, _mesh.triangles);
            }

            _simp.CollapseEdge(_simp.costs.RemoveFront());

            if (_nextUpdateTime < Time.time) {
                _nextUpdateTime = Time.time + updateInterval;
                UpdateMesh ();
            }
        }
    }
示例#20
0
    IEnumerator Collapse()
    {
        while (true)
        {
            yield return(0);

            if (_simp.costs.Count <= 5)
            {
                UpdateMesh();
                yield return(new WaitForSeconds(2f));

                _mesh = planeObj.Reset();
                _simp = new Simplification(_mesh.vertices, _mesh.triangles);
            }

            _simp.CollapseEdge(_simp.costs.RemoveFront());

            if (_nextUpdateTime < Time.time)
            {
                _nextUpdateTime = Time.time + updateInterval;
                UpdateMesh();
            }
        }
    }
        private IExpressionType doPredefinedFunc(Function f)
        {
            Computator     comp = new Computator();
            Simplification s    = new Simplification();

            switch (f.getName())
            {
            case "plot":
                MathList mathList = (MathList)f.getOperands()[0];
                Variable var      = (Variable)f.getOperands()[1];
                Interval interval = (Interval)f.getOperands()[2];

                PlotModel plot = new PlotModel(mathList, var, interval);
                plot.drawGraphics();
                return(f);

            case "integrate":
                Integrate       i       = new Integrate((Variable)f.getOperands()[1]);
                IExpressionType operand = f.getOperands()[0].doOperation(comp);
                if (operand.getType() == Types.VarDefinition)
                {
                    return(i.integrate((IMathExpression)operand.getOperands()[1]));
                }
                IExpressionType integrated = i.integrate((IMathExpression)operand);
                return(integrated.doOperation(comp));
            }

            List <IExpressionType> list = new List <IExpressionType>();

            foreach (var op in f.getOperands())
            {
                list.Add(op.doOperation(comp));
            }

            return(s.simplify(new Function(f.getType(), list, f.getName())));
        }
        private void btnSimplificar_Click(object sender, EventArgs e)
        {
            btnGerar_Click(null, null);
            simplificao = new Simplification(g);

            lbVazios.Items.Clear();
            lbVazios.Items.AddRange(simplificao.VariablesEmpty.Cast<Object>().ToArray());
            lbRegrasSemVazio.Items.Clear();
            lbRegrasSemVazio.Items.AddRange(simplificao.GrammarNoEmpty.Rules.ToArray());
            lbFecho.Items.Clear();
            lbFecho.Items.AddRange(simplificao.FastenersString.ToArray());

            lbProducoesFechos.Items.Clear();
            lbProducoesFechos.Items.AddRange(simplificao.GrammarNoUnitarianProductions.Rules.ToArray());

            lbVariaveisAcessamTerminais.Items.Clear();
            lbVariaveisAcessamTerminais.Items.AddRange(simplificao.VariablesCallTerminals.Cast<Object>().ToArray());

            lbVariaveisAcessiveis.Items.Clear();
            lbVariaveisAcessiveis.Items.AddRange(simplificao.AcessiblesVariables.Cast<Object>().ToArray());

            lbTerminaisAcessiveis.Items.Clear();
            lbTerminaisAcessiveis.Items.AddRange(simplificao.AcessiblesTerminals.Cast<Object>().ToArray());

            lbProducoesFinais.Items.Clear();
            lbProducoesFinais.Items.AddRange(simplificao.Simplified.Rules.ToArray());
        }
        /// <summary>
        /// Attempts to determinize the automaton,
        /// i.e. modify it such that for every state and every element there is at most one transition that allows for that element,
        /// and there are no epsilon transitions.
        /// </summary>
        /// <returns>
        /// <see langword="true"/> if the determinization attempt was successful and the automaton is now deterministic,
        /// <see langword="false"/> otherwise.
        /// </returns>
        /// <remarks>See <a href="http://www.cs.nyu.edu/~mohri/pub/hwa.pdf"/> for algorithm details.</remarks>
        public bool TryDeterminize()
        {
            if (this.Data.DeterminizationState != DeterminizationState.Unknown)
            {
                return(this.Data.DeterminizationState == DeterminizationState.IsDeterminized);
            }

            int maxStatesBeforeStop = Math.Min(this.States.Count * 3, MaxStateCount);

            this.MakeEpsilonFree(); // Deterministic automata cannot have epsilon-transitions

            if (this.UsesGroups)
            {
                // Determinization will result in lost of group information, which we cannot allow
                this.Data = this.Data.WithDeterminizationState(DeterminizationState.IsNonDeterminizable);
                return(false);
            }

            // Weighted state set is a set of (stateId, weight) pairs, where state ids correspond to states of the original automaton..
            // Such pairs correspond to states of the resulting automaton.
            var weightedStateSetQueue      = new Queue <Determinization.WeightedStateSet>();
            var weightedStateSetToNewState = new Dictionary <Determinization.WeightedStateSet, int>();
            var builder = new Builder();

            var startWeightedStateSet = new Determinization.WeightedStateSet {
                { this.Start.Index, Weight.One }
            };

            weightedStateSetQueue.Enqueue(startWeightedStateSet);
            weightedStateSetToNewState.Add(startWeightedStateSet, builder.StartStateIndex);
            builder.Start.SetEndWeight(this.Start.EndWeight);

            while (weightedStateSetQueue.Count > 0)
            {
                // Take one unprocessed state of the resulting automaton
                Determinization.WeightedStateSet currentWeightedStateSet = weightedStateSetQueue.Dequeue();
                var currentStateIndex = weightedStateSetToNewState[currentWeightedStateSet];
                var currentState      = builder[currentStateIndex];

                // Find out what transitions we should add for this state
                var outgoingTransitionInfos = this.GetOutgoingTransitionsForDeterminization(currentWeightedStateSet);

                // For each transition to add
                foreach ((TElementDistribution, Weight, Determinization.WeightedStateSet)outgoingTransitionInfo in outgoingTransitionInfos)
                {
                    TElementDistribution elementDistribution = outgoingTransitionInfo.Item1;
                    Weight weight = outgoingTransitionInfo.Item2;
                    Determinization.WeightedStateSet destWeightedStateSet = outgoingTransitionInfo.Item3;

                    int destinationStateIndex;
                    if (!weightedStateSetToNewState.TryGetValue(destWeightedStateSet, out destinationStateIndex))
                    {
                        if (builder.StatesCount == maxStatesBeforeStop)
                        {
                            // Too many states, determinization attempt failed
                            return(false);
                        }

                        // Add new state to the result
                        var destinationState = builder.AddState();
                        weightedStateSetToNewState.Add(destWeightedStateSet, destinationState.Index);
                        weightedStateSetQueue.Enqueue(destWeightedStateSet);

                        // Compute its ending weight
                        destinationState.SetEndWeight(Weight.Zero);
                        foreach (KeyValuePair <int, Weight> stateIdWithWeight in destWeightedStateSet)
                        {
                            var addedWeight = stateIdWithWeight.Value * this.States[stateIdWithWeight.Key].EndWeight;
                            destinationState.SetEndWeight(destinationState.EndWeight + addedWeight);
                        }

                        destinationStateIndex = destinationState.Index;
                    }

                    // Add transition to the destination state
                    currentState.AddTransition(elementDistribution, weight, destinationStateIndex);
                }
            }

            var simplification = new Simplification(builder, this.PruneStatesWithLogEndWeightLessThan);

            simplification.MergeParallelTransitions(); // Determinization produces a separate transition for each segment

            this.Data = builder.GetData().WithDeterminizationState(DeterminizationState.IsDeterminized);
            this.PruneStatesWithLogEndWeightLessThan = this.PruneStatesWithLogEndWeightLessThan;
            this.LogValueOverride = this.LogValueOverride;

            return(true);
        }
示例#24
0
        /// <summary>
        /// Attempts to determinize the automaton,
        /// i.e. modify it such that for every state and every element there is at most one transition that allows for that element,
        /// and there are no epsilon transitions.
        /// </summary>
        /// <returns>
        /// <see langword="true"/> if the determinization attempt was successful and the automaton is now deterministic,
        /// <see langword="false"/> otherwise.
        /// </returns>
        /// <remarks>See <a href="http://www.cs.nyu.edu/~mohri/pub/hwa.pdf"/> for algorithm details.</remarks>
        public bool TryDeterminize()
        {
            if (this.Data.IsDeterminized != null)
            {
                return(this.Data.IsDeterminized == true);
            }

            int maxStatesBeforeStop = Math.Min(this.States.Count * 3, MaxStateCount);

            this.MakeEpsilonFree(); // Deterministic automata cannot have epsilon-transitions

            if (this.UsesGroups)
            {
                // Determinization will result in lost of group information, which we cannot allow
                this.Data = this.Data.With(isDeterminized: false);
                return(false);
            }

            var builder = new Builder();

            builder.Start.SetEndWeight(this.Start.EndWeight);

            var weightedStateSetStack         = new Stack <(bool enter, Determinization.WeightedStateSet set)>();
            var enqueuedWeightedStateSetStack = new Stack <(bool enter, Determinization.WeightedStateSet set)>();
            var weightedStateSetToNewState    = new Dictionary <Determinization.WeightedStateSet, int>();
            // This hash set is used to track sets currently in path from root. If we've found a set of states
            // that we have already seen during current path from root, but weights are different, that means
            // we've found a non-converging loop - infinite number of weighed sets will be generated if
            // we continue traversal and determinization will fail. For performance reasons we want to fail
            // fast if such loop is found.
            var stateSetsInPath = new Dictionary <Determinization.WeightedStateSet, Determinization.WeightedStateSet>(
                Determinization.WeightedStateSetOnlyStateComparer.Instance);

            var startWeightedStateSet = new Determinization.WeightedStateSet(this.Start.Index);

            weightedStateSetStack.Push((true, startWeightedStateSet));
            weightedStateSetToNewState.Add(startWeightedStateSet, builder.StartStateIndex);

            while (weightedStateSetStack.Count > 0)
            {
                // Take one unprocessed state of the resulting automaton
                var(enter, currentWeightedStateSet) = weightedStateSetStack.Pop();

                if (enter)
                {
                    if (currentWeightedStateSet.Count > 1)
                    {
                        // Only sets with more than 1 state can lead to infinite loops with different weights.
                        // Because if there's only 1 state, than it's weight is always Weight.One.
                        if (!stateSetsInPath.ContainsKey(currentWeightedStateSet))
                        {
                            stateSetsInPath.Add(currentWeightedStateSet, currentWeightedStateSet);
                        }

                        weightedStateSetStack.Push((false, currentWeightedStateSet));
                    }

                    if (!EnqueueOutgoingTransitions(currentWeightedStateSet))
                    {
                        this.Data = this.Data.With(isDeterminized: false);
                        return(false);
                    }
                }
                else
                {
                    stateSetsInPath.Remove(currentWeightedStateSet);
                }
            }

            var simplification = new Simplification(builder, this.PruneStatesWithLogEndWeightLessThan);

            simplification.MergeParallelTransitions(); // Determinization produces a separate transition for each segment

            this.Data = builder.GetData().With(isDeterminized: true);
            this.PruneStatesWithLogEndWeightLessThan = this.PruneStatesWithLogEndWeightLessThan;
            this.LogValueOverride = this.LogValueOverride;

            return(true);

            bool EnqueueOutgoingTransitions(Determinization.WeightedStateSet currentWeightedStateSet)
            {
                var currentStateIndex = weightedStateSetToNewState[currentWeightedStateSet];
                var currentState      = builder[currentStateIndex];

                // Common special-case: definitely deterministic transitions from single state.
                // In this case no complicated determinization procedure is needed.
                if (currentWeightedStateSet.Count == 1 &&
                    AllDestinationsAreSame(currentWeightedStateSet[0].Index))
                {
                    Debug.Assert(currentWeightedStateSet[0].Weight == Weight.One);

                    var sourceState = this.States[currentWeightedStateSet[0].Index];
                    foreach (var transition in sourceState.Transitions)
                    {
                        var destinationStates      = new Determinization.WeightedStateSet(transition.DestinationStateIndex);
                        var outgoingTransitionInfo = new Determinization.OutgoingTransition(
                            transition.ElementDistribution.Value, transition.Weight, destinationStates);
                        if (!TryAddTransition(enqueuedWeightedStateSetStack, outgoingTransitionInfo, currentState))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    // Find out what transitions we should add for this state
                    var outgoingTransitions =
                        this.GetOutgoingTransitionsForDeterminization(currentWeightedStateSet);
                    foreach (var outgoingTransition in outgoingTransitions)
                    {
                        if (!TryAddTransition(enqueuedWeightedStateSetStack, outgoingTransition, currentState))
                        {
                            return(false);
                        }
                    }
                }

                while (enqueuedWeightedStateSetStack.Count > 0)
                {
                    weightedStateSetStack.Push(enqueuedWeightedStateSetStack.Pop());
                }

                return(true);
            }

            // Checks that all transitions from state end up in the same destination. This is used
            // as a very fast "is deterministic" check, that doesn't care about distributions.
            // State can have deterministic transitions with different destinations. This case will be
            // handled by slow path.
            bool AllDestinationsAreSame(int stateIndex)
            {
                var transitions = this.States[stateIndex].Transitions;

                if (transitions.Count <= 1)
                {
                    return(true);
                }

                var destination = transitions[0].DestinationStateIndex;

                for (var i = 1; i < transitions.Count; ++i)
                {
                    if (transitions[i].DestinationStateIndex != destination)
                    {
                        return(false);
                    }
                }

                return(true);
            }

            // Adds transition from currentState into state corresponding to weighted state set from
            // outgoingTransitionInfo. If that state does not exist yet it is created and is put into stack
            // for further processing. This function returns false if determinization has failed.
            // That can happen because of 2 ressons:
            // - Too many states were created and its not feasible to continue trying to determinize
            //   automaton further
            // - An infinite loop with not converging weights was found. It leads to infinite number of states.
            //   So determinization is aborted early.
            bool TryAddTransition(
                Stack <(bool enter, Determinization.WeightedStateSet set)> destinationStack,
                Determinization.OutgoingTransition transition,
                Builder.StateBuilder currentState)
            {
                var destinations = transition.Destinations;

                if (!weightedStateSetToNewState.TryGetValue(destinations, out var destinationStateIndex))
                {
                    if (builder.StatesCount == maxStatesBeforeStop)
                    {
                        // Too many states, determinization attempt failed
                        return(false);
                    }

                    var visitedWeightedStateSet = default(Determinization.WeightedStateSet);
                    var sameSetVisited          =
                        destinations.Count > 1 &&
                        stateSetsInPath.TryGetValue(destinations, out visitedWeightedStateSet);

                    if (sameSetVisited && !destinations.Equals(visitedWeightedStateSet))
                    {
                        // We arrived into the same state set as before, but with different weights.
                        // This is an infinite non-converging loop. Determinization has failed
                        return(false);
                    }

                    // Add new state to the result
                    var destinationState = builder.AddState();
                    weightedStateSetToNewState.Add(destinations, destinationState.Index);
                    destinationStack.Push((true, destinations));

                    if (destinations.Count > 1 && !sameSetVisited)
                    {
                        destinationStack.Push((false, destinations));
                    }

                    // Compute its ending weight
                    destinationState.SetEndWeight(Weight.Zero);
                    for (var i = 0; i < destinations.Count; ++i)
                    {
                        var weightedState = destinations[i];
                        var addedWeight   = weightedState.Weight * this.States[weightedState.Index].EndWeight;
                        destinationState.SetEndWeight(destinationState.EndWeight + addedWeight);
                    }

                    destinationStateIndex = destinationState.Index;
                }

                // Add transition to the destination state
                currentState.AddTransition(transition.ElementDistribution, transition.Weight, destinationStateIndex);
                return(true);
            }
        }
示例#25
0
 public void simplify()
 {
     simp = new Simplification();
     _create_dlods();
 }
示例#26
0
        /// <summary>
        /// Attempts to determinize the automaton,
        /// i.e. modify it such that for every state and every element there is at most one transition that allows for that element,
        /// and there are no epsilon transitions.
        /// </summary>
        /// <param name="maxStatesBeforeStop">
        /// The maximum number of states the resulting automaton can have. If the number of states exceeds the value
        /// of this parameter during determinization, the process is aborted.
        /// </param>
        /// <returns>
        /// <see langword="true"/> if the determinization attempt was successful and the automaton is now deterministic,
        /// <see langword="false"/> otherwise.
        /// </returns>
        /// <remarks>See <a href="http://www.cs.nyu.edu/~mohri/pub/hwa.pdf"/> for algorithm details.</remarks>
        public bool TryDeterminize(int maxStatesBeforeStop)
        {
            Argument.CheckIfInRange(
                maxStatesBeforeStop > 0 && maxStatesBeforeStop <= MaxStateCount,
                "maxStatesBeforeStop",
                "The maximum number of states must be positive and not greater than the maximum number of states allowed in an automaton.");

            this.MakeEpsilonFree(); // Deterministic automata cannot have epsilon-transitions

            if (this.UsesGroups())
            {
                // Determinization will result in lost of group information, which we cannot allow
                return(false);
            }

            // Weighted state set is a set of (stateId, weight) pairs, where state ids correspond to states of the original automaton..
            // Such pairs correspond to states of the resulting automaton.
            var weightedStateSetQueue      = new Queue <Determinization.WeightedStateSet>();
            var weightedStateSetToNewState = new Dictionary <Determinization.WeightedStateSet, int>();
            var builder = new Builder();

            var startWeightedStateSet = new Determinization.WeightedStateSet {
                { this.Start.Index, Weight.One }
            };

            weightedStateSetQueue.Enqueue(startWeightedStateSet);
            weightedStateSetToNewState.Add(startWeightedStateSet, builder.StartStateIndex);
            builder.Start.SetEndWeight(this.Start.EndWeight);

            while (weightedStateSetQueue.Count > 0)
            {
                // Take one unprocessed state of the resulting automaton
                Determinization.WeightedStateSet currentWeightedStateSet = weightedStateSetQueue.Dequeue();
                var currentStateIndex = weightedStateSetToNewState[currentWeightedStateSet];
                var currentState      = builder[currentStateIndex];

                // Find out what transitions we should add for this state
                var outgoingTransitionInfos = this.GetOutgoingTransitionsForDeterminization(currentWeightedStateSet);

                // For each transition to add
                foreach ((TElementDistribution, Weight, Determinization.WeightedStateSet)outgoingTransitionInfo in outgoingTransitionInfos)
                {
                    TElementDistribution elementDistribution = outgoingTransitionInfo.Item1;
                    Weight weight = outgoingTransitionInfo.Item2;
                    Determinization.WeightedStateSet destWeightedStateSet = outgoingTransitionInfo.Item3;

                    int destinationStateIndex;
                    if (!weightedStateSetToNewState.TryGetValue(destWeightedStateSet, out destinationStateIndex))
                    {
                        if (builder.StatesCount == maxStatesBeforeStop)
                        {
                            // Too many states, determinization attempt failed
                            return(false);
                        }

                        // Add new state to the result
                        var destinationState = builder.AddState();
                        weightedStateSetToNewState.Add(destWeightedStateSet, destinationState.Index);
                        weightedStateSetQueue.Enqueue(destWeightedStateSet);

                        // Compute its ending weight
                        destinationState.SetEndWeight(Weight.Zero);
                        foreach (KeyValuePair <int, Weight> stateIdWithWeight in destWeightedStateSet)
                        {
                            destinationState.SetEndWeight(Weight.Sum(
                                                              destinationState.EndWeight,
                                                              Weight.Product(stateIdWithWeight.Value, this.States[stateIdWithWeight.Key].EndWeight)));
                        }

                        destinationStateIndex = destinationState.Index;
                    }

                    // Add transition to the destination state
                    currentState.AddTransition(elementDistribution, weight, destinationStateIndex);
                }
            }

            var simplification = new Simplification(builder, this.PruneTransitionsWithLogWeightLessThan);

            simplification.MergeParallelTransitions(); // Determinization produces a separate transition for each segment

            var result = builder.GetAutomaton();

            result.PruneTransitionsWithLogWeightLessThan = this.PruneTransitionsWithLogWeightLessThan;
            result.LogValueOverride = this.LogValueOverride;
            this.SwapWith(result);

            return(true);
        }
    void Start()
    {
        _sphere = isoSphere.GetComponent<MeshFilter>().mesh;
        _simp = new Simplification(_sphere.vertices, _sphere.triangles);

        StartCoroutine("Collapse");
    }