Esempio n. 1
0
        public List<State> Solve (List<Measure> measures, ICostFactory cost_factory, OnProgressDelegate on_progress) {
            List<NodeCollection> node_collections = NodeCollection.CalculateNodes(measures);
            List<List<NodeCollection>> sections = NodeCollection.CalculateSections(node_collections, m_DesiredSectionSize);
            State initial = SolverHelper.GenerateInitialNode(measures[0].beats[0].notes.Count == 10, cost_factory);

            OnProgressArg on_progress_arg = new OnProgressArg();
            on_progress_arg.second_max = node_collections[node_collections.Count - 1].items[0].second;
            on_progress_arg.depth_max = node_collections.Count - 1;
            on_progress_arg.depth_cur = 0;
            foreach (List<NodeCollection> path in sections) {
                State nxt = null;
                while (nxt == null) {
                    Calculate(path, initial, cost_factory, on_progress, on_progress_arg, ref nxt);

                    on_progress(on_progress_arg);
                    if (!on_progress_arg.carry_on) {
                        return SolverHelper.GeneratePlay(nxt == null ? initial : nxt);
                    }
                }
                on_progress_arg.prv_iter_opened_total = on_progress_arg.opened_total;
                on_progress_arg.prv_iter_discarded = on_progress_arg.discarded;

                initial = nxt;
                on_progress_arg.depth_cur += path.Count;
            }
            return SolverHelper.GeneratePlay(initial);
        }
Esempio n. 2
0
        public List<State> Solve (List<Measure> measures, ICostFactory cost_factory, OnProgressDelegate on_progress) {
            List<NodeCollection> node_collections = NodeCollection.CalculateNodes(measures);
            List<List<NodeCollection>> sections = NodeCollection.CalculateSections(node_collections, m_DesiredSectionSize);
            State initial = SolverHelper.GenerateInitialNode(measures[0].beats[0].notes.Count == 10, cost_factory);

            OnProgressArg on_progress_arg = new OnProgressArg();
            on_progress_arg.second_max = node_collections[node_collections.Count - 1].items[0].second;
            on_progress_arg.depth_max = node_collections.Count - 1;
            foreach (List<NodeCollection> path in sections) {
                State nxt = null;
                float storage_ratio = (float)path.Count / 30.0f;
                if (storage_ratio < 1.0f) {
                    storage_ratio = 1.0f;
                }
                int storage_limit = (int)((float)m_ItemLimit * storage_ratio);
                while (nxt == null) {
                    if (storage_limit > 100000) { //Arbitrary limit
                        throw new Exception("Storage limit reached without a solution");
                    }
                    nxt = Calculate(initial, path, storage_limit, cost_factory, on_progress, on_progress_arg);
                    storage_limit += m_ItemLimit;

                    on_progress(on_progress_arg);
                    if (!on_progress_arg.carry_on) {
                        return SolverHelper.GeneratePlay(nxt == null ? initial : nxt);
                    }
                }
                on_progress_arg.prv_iter_opened_total = on_progress_arg.opened_total;
                on_progress_arg.prv_iter_discarded = on_progress_arg.discarded;

                initial = nxt;
            }
            return SolverHelper.GeneratePlay(initial);
        }
Esempio n. 3
0
        private void Calculate (List<NodeCollection> node_collections, State cur, ICostFactory cost_factory, OnProgressDelegate on_progress, OnProgressArg on_progress_arg, ref State best) {
            on_progress_arg.progress_cur = (int)(
                (
                    (float)(cur.distance_from_start + 1) /
                    (float)(on_progress_arg.depth_max)
                ) * 100.0f
            );
            on_progress(on_progress_arg);

            if (cur.distance_from_start == node_collections.Count - 1) {
                //This is a completed play
                if (best == null) {
                    best = cur;
                } else if (cur.cost.GetTotalCost() < best.cost.GetTotalCost()) {
                    best = cur;
                }
                return;
            }
            if (!on_progress_arg.carry_on) {
                return;
            }
            int index = cur.distance_from_start + 1;
            NodeCollection collection = node_collections[index];
            Beat beat = collection.beat;

            List<State> nxt_list = new List<State>();
            foreach (Node node in collection.items) {
                List<Analyzer.State.Limb[]> neighbours = new List<Analyzer.State.Limb[]>();
                ArcCalculator.Calculate(cur, node, neighbours);
                foreach (Analyzer.State.Limb[] n in neighbours) {
                    State nxt = ArcCalculator.TransitionTo(cur, n, collection.beat.second, index, beat, cost_factory);
                    if (nxt == null) {
                        continue;
                    }
                    if (best == null || nxt.cost.GetTotalCost() < best.cost.GetTotalCost()) {
                        nxt_list.Add(nxt);
                    }
                }
            }
            nxt_list.Sort((State a, State b) => {
                return a.cost.GetTotalCost().CompareTo(b.cost.GetTotalCost());
            });
            foreach (State n in nxt_list) {
                Calculate(node_collections, n, cost_factory, on_progress, on_progress_arg, ref best);
            }
        }
Esempio n. 4
0
        public static State Calculate (
            State initial, List<NodeCollection> path,
            int storage_limit, ICostFactory cost_factory,
            OnProgressDelegate on_progress, OnProgressArg arg
        ) {
            int path_offset = initial.distance_from_start + 1;

            OpenedStateCollection opened = new OpenedStateCollection(storage_limit, 1000/*magic number*/, new StateComparer(0.2f/*magic number*/));
            opened.Add(initial);
            State prv_opened = null;
            State result = null;

            List<State> tmp = new List<State>();
            while (opened.Commit()) {
                State cur = opened.First();
                int nxt_distance_from_start = cur.distance_from_start + 1;
                int path_index = nxt_distance_from_start - path_offset;
                if (path_index == path.Count) {
                    if (result == null || result.cost.GetTotalCost() > cur.cost.GetTotalCost()) {
                        result = cur;
                    }
                    continue;
                }
                prv_opened = cur;
                Beat beat = path[path_index].beat;
                List<Node> neighbours = path[path_index].items;

                if (on_progress != null) {
                    arg.progress_cur = (int)((float)nxt_distance_from_start / (float)arg.depth_max * 100.0f);
                    arg.depth_cur = nxt_distance_from_start;
                    arg.second_cur = cur.second;

                    ++arg.closed;

                    arg.opened_cur = opened.Count();
                    arg.opened_total = arg.prv_iter_opened_total + opened.GetTotalAdded();
                    arg.discarded = arg.prv_iter_discarded + opened.GetTotalDiscarded();

                    on_progress(arg);
                    if (!arg.carry_on) {
                        return result;
                    }
                }
                if (neighbours.Count == 0) {
                    throw new ExecutionEngineException();
                } else {
                    //tmp.Clear();
                    foreach (Node n in neighbours) {
                        if (!ArcCalculator.IsArcValid(cur, n)) {
                            continue;
                        }
                        List<Analyzer.State.Limb[]> possibilities = new List<Analyzer.State.Limb[]>();
                        ArcCalculator.Calculate(cur, n, possibilities);
                        foreach (Analyzer.State.Limb[] p in possibilities) {
                            State nxt = ArcCalculator.TransitionTo(cur, p, n.second, n.distance_from_start, beat, cost_factory);
                            if (nxt != null) {
                                //tmp.Add(nxt);
                                opened.Add(nxt);
                            }
                        }
                    }
                }
            }
            return result;
        }