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"); }
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"); }
void Start() { _mesh = planeObj.GetComponent <MeshFilter>().mesh; _simp = new Simplification(_mesh.vertices, _mesh.triangles); _nextUpdateTime = Time.time + updateInterval; if (!interactive) { StartCoroutine("Collapse"); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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)); }
/// <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); } }
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; }
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); }
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); }
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 (); } } }
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); }
/// <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); } }
public void simplify() { simp = new Simplification(); _create_dlods(); }
/// <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"); }