private void achieve(int flag) { if (!(flag == SORTED_BY_INPUT || flag == SORTED_BY_OUTPUT || flag == HAS_HEURISTICS)) { throw new Exception("CHECK_ARG: flag == SORTED_BY_INPUT || flag == SORTED_BY_OUTPUT || flag == HAS_HEURISTICS"); } if (flags > 0 & flag > 0) { return; } if (flag == HAS_HEURISTICS) { AStarUtil.a_star_backwards(m_heuristics, this); return; } for (int node = 0; node < nStates(); node++) { Intarray permutation = new Intarray(); if (flag == OcroFST.SORTED_BY_INPUT) { NarrayUtil.Quicksort(permutation, m_inputs[node]); } else { NarrayUtil.Quicksort(permutation, m_outputs[node]); } NarrayUtil.Permute(m_inputs[node], permutation); NarrayUtil.Permute(m_outputs[node], permutation); NarrayUtil.Permute(m_targets[node], permutation); NarrayUtil.Permute(m_costs[node], permutation); } flags |= flag; }
public override void Arcs(Intarray ids, Intarray targets, Intarray outputs, Floatarray costs, int node) { int n1 = node / l2.nStates(); int n2 = node % l2.nStates(); Intarray ids1 = new Intarray(); Intarray ids2 = new Intarray(); Intarray t1 = new Intarray(); Intarray t2 = new Intarray(); Intarray o1 = new Intarray(); Intarray o2 = new Intarray(); Floatarray c1 = new Floatarray(); Floatarray c2 = new Floatarray(); l1.Arcs(ids1, t1, o1, c1, n1); l2.Arcs(ids2, t2, o2, c2, n2); // sort & permute Intarray p1 = new Intarray(); Intarray p2 = new Intarray(); NarrayUtil.Quicksort(p1, o1); NarrayUtil.Permute(ids1, p1); NarrayUtil.Permute(t1, p1); NarrayUtil.Permute(o1, p1); NarrayUtil.Permute(c1, p1); NarrayUtil.Quicksort(p2, ids2); NarrayUtil.Permute(ids2, p2); NarrayUtil.Permute(t2, p2); NarrayUtil.Permute(o2, p2); NarrayUtil.Permute(c2, p2); int k1, k2; // l1 epsilon moves for (k1 = 0; k1 < o1.Length() && o1.At1d(k1) == 0; k1++) { ids.Push(ids1.At1d(k1)); targets.Push(Combine(t1.At1d(k1), n2)); outputs.Push(0); costs.Push(c1.At1d(k1)); } // l2 epsilon moves for (k2 = 0; k2 < o2.Length() && ids2.At1d(k2) == 0; k2++) { ids.Push(0); targets.Push(Combine(n1, t2.At1d(k2))); outputs.Push(o2.At1d(k2)); costs.Push(c2.At1d(k2)); } // non-epsilon moves while (k1 < o1.Length() && k2 < ids2.Length()) { while (k1 < o1.Length() && o1.At1d(k1) < ids2.At1d(k2)) { k1++; } if (k1 >= o1.Length()) { break; } while (k2 < ids2.Length() && o1.At1d(k1) > ids2.At1d(k2)) { k2++; } while (k1 < o1.Length() && k2 < ids2.Length() && o1.At1d(k1) == ids2.At1d(k2)) { for (int j = k2; j < ids2.Length() && o1.At1d(k1) == ids2.At1d(j); j++) { ids.Push(ids1.At1d(k1)); targets.Push(Combine(t1.At1d(k1), t2.At1d(j))); outputs.Push(o2.At1d(j)); costs.Push(c1.At1d(k1) + c2.At1d(j)); } k1++; } } }