Пример #1
0
        public void Build(weka.core.Instances instances)
        {
            WekaUtils.DebugAssert(instances.numClasses() == 3, "instance's numClasses should be 3.");
            m_counts = new int[instances.numClasses()];

            for (int i = 0; i < m_counts.Length; i++)
            {
                m_counts[i] = 0;
            }

            foreach (Instance instance in instances)
            {
                int v = (int)instance.classValue();
                m_counts[v]++;
            }
        }
Пример #2
0
        public void Build(weka.core.Instances instances)
        {
            WekaUtils.DebugAssert(instances.numClasses() == 3, "instance's numClasses should be 3.");
            for (int i = 0; i < m_counts.Length; i++)
            {
                m_counts[i] = 0;
            }

            double c = m_tp / m_sl;
            foreach (weka.core.Instance instance in instances)
            {
                int v = (int)instance.classValue();
                if (v == 2)
                {
                    m_counts[2] += c;
                }
                else if (v == 0)
                {
                    m_counts[0]++;
                }
                else
                {
                    m_counts[1]++;
                }
            }
        }
Пример #3
0
        private static object[,] IncrementTestTrain(bool newjHpTime, Func<weka.classifiers.Classifier> clsCreator, string resultFile, int step,
            weka.core.Instances trainInstances, weka.core.Instances trainInstancesWithDate,
            weka.core.Instances allInstances, weka.core.Instances allInstancesWithDate,
            long maxjHpTime, int maxjHpTimeHp,
            Tuple<int, int> tuple)
        {
            if (!newjHpTime)
                return null;

            int timeAfter = 0;

            object[,] toRet = new object[step, 9];
            for (int j = 0; j < step; ++j)
                toRet[j, 0] = 2;

            var cls = clsCreator();
            bool b = true;
            b = WekaUtils.TrainInstances(cls, trainInstances);
            if (!b)
            {
                WekaUtils.Instance.WriteLog(string.Format("TrainInstance error!"));
                return null;
            }

            long totolCost = 0;
            //var eval = WekaUtils.TestInstances(trainInstances, cls, null);
            //totolCost = (long)eval.totalCost();

            // get hp last time
            long[] maxLastTimes = new long[trainInstances.numClasses()];
            long[] minLastTimes = new long[trainInstances.numClasses()];
            for (int j = 0; j < trainInstances.numClasses(); ++j)
            {
                maxLastTimes[j] = 0;
                minLastTimes[j] = long.MaxValue;
            }
            for (int j = 0; j < trainInstances.numInstances(); ++j)
            {
                DateTime openTime = WekaUtils.GetDateValueFromInstances(trainInstancesWithDate, 0, j);
                DateTime closeTime = WekaUtils.GetDateValueFromInstances(trainInstancesWithDate, 1, j);

                int v = (int)trainInstances.instance(j).classValue();

                long lastTime = (long)(closeTime - openTime).TotalSeconds;
                if (lastTime > maxLastTimes[v])
                    maxLastTimes[v] = lastTime;
                if (lastTime < minLastTimes[v])
                    minLastTimes[v] = lastTime;
            }

            var ai = tuple.Item1;
            DateTime nowDate = WekaUtils.GetDateValueFromInstances(allInstancesWithDate, 0, ai);
            //var i2 = tuple.Item2;
            for (int j = 0; j < step; ++j)
            {
                int idx = ai + timeAfter + j;
                DateTime nextDate = WekaUtils.GetDateValueFromInstances(allInstancesWithDate, 0, idx);

                double d = 2;
                d = cls.classifyInstance(allInstances.instance(idx));
                double[] v = cls.distributionForInstance(allInstances.instance(idx));
                //if (d == 2)
                //{
                //    WekaUtils.Instance.WriteLog(string.Format("{0} classifyInstance result = 2", nowDate.ToString(Parameters.DateTimeFormat)));
                //    continue;
                //}

                //if ((d == 1 && maxjHpTimeHp == 1)
                //    || (d == 0 && maxjHpTimeHp == 0))
                //    d = 2;
                //if ((d == 1 && maxjHpTimeHp == 0)
                //    || (d == 0 && maxjHpTimeHp == 1))
                //    d = 2;

                toRet[j, 0] = (int)d;
                toRet[j, 1] = (int)allInstances.instance(idx).classValue();
                toRet[j, 2] = WekaUtils.GetTimeFromDate(nextDate);
                toRet[j, 3] = WekaUtils.GetTimeFromDate(nowDate);
                toRet[j, 4] = trainInstances.numInstances();
                toRet[j, 5] = totolCost;
                toRet[j, 6] = maxjHpTime;
                toRet[j, 7] = v[(int)d];
                if (d != 2 && (maxLastTimes[(int)d] == 0
                    || maxLastTimes[(int)d] == long.MaxValue))
                {
                    maxLastTimes[(int)d] = maxLastTimes[3];
                }
                toRet[j, 8] = maxLastTimes[(int)d];

                //using (StreamWriter sw = new StreamWriter("d:\\p.txt", true))
                //{
                //    sw.WriteLine(string.Format("{0}", (int)allInstancesNoDate.instance(idx).classValue()));
                //}
            }

            return toRet;
        }
Пример #4
0
        public static string IncrementTest(weka.core.Instances allInstancesWithDate,
            Func<weka.classifiers.Classifier> clsCreator, string removeAttributes, string resultFile, int step)
        {
            //if (!(TestParameters2.UsePartialHpDataM1 || TestParameters2.UsePartialHpData))
            //{
            //    HpData.Instance.Clear();
            //}

            int trainMinutes = TestParameters2.MinTrainPeriod * WekaUtils.GetMinuteofPeriod(TestParameters2.CandidateParameter.MainPeriod);

            string ret = string.Empty;

            string sampleFile = null; // resultFile.Replace("Increment", "sample");
            bool useInstanceWeight = false;
            bool enablePerHour = false;
            bool enableDiffClass = false;
            int sameClassCount = -1;// TestParameters2.MaxTrainSize / 3; // allInstances.numClasses();
            bool enableDiffHpTime = false;
            bool enableRemoveLittle = false;
            bool enableRemoveLargeThanMid = true;
            bool enableFilter = false;

            if (!TestParameters2.RealTimeMode && File.Exists(resultFile))
                File.Delete(resultFile);

            weka.core.Instances allInstances;
            var filter = new weka.filters.MultiFilter();
            //filter.setOptions(weka.core.Utils.splitOptions("-F \"weka.filters.unsupervised.attribute.Remove -R 1,4\" -F \"weka.filters.unsupervised.attribute.Discretize -B 10 -M -1.0 -R first-last\""));
            filter.setOptions(weka.core.Utils.splitOptions(string.Format("-F \"weka.filters.unsupervised.attribute.Remove -R {0} \"", removeAttributes)));
            filter.setInputFormat(allInstancesWithDate);
            allInstances = weka.filters.Filter.useFilter(allInstancesWithDate, filter);

            long[] jHpTimes = new long[allInstancesWithDate.numInstances()];
            DateTime[] jDates = new DateTime[allInstancesWithDate.numInstances()];
            DateTime[] jHpDates = new DateTime[allInstancesWithDate.numInstances()];
            int[] jHps = new int[allInstancesWithDate.numInstances()];

            for (int j = 0; j < jDates.Length; ++j)
            {
                jDates[j] = WekaUtils.GetDateValueFromInstances(allInstancesWithDate, 0, j);
                jHpTimes[j] = WekaUtils.GetTimeValueFromInstances(allInstancesWithDate, 1, j);
                jHpDates[j] = WekaUtils.GetDateFromTime(jHpTimes[j]);
                jHps[j] = (int)allInstances.instance(j).classValue();
            }

            #region "action"
            Func<Tuple<int, int>, Tuple<weka.core.Instances, weka.core.Instances, long, int, int>> action = (tuple) =>
            {
                var ai = tuple.Item1;

                DateTime nowDate = WekaUtils.GetDateValueFromInstances(allInstancesWithDate, 0, ai);
                if (nowDate < TestParameters2.TrainStartTime || nowDate > TestParameters2.TrainEndTime)
                    return null;

                DateTime nowHpDate = WekaUtils.GetDateValueFromInstances(allInstancesWithDate, 1, ai);
                double nowClass = allInstancesWithDate.instance(ai).classValue();
                double preJClass = -1;

                List<weka.core.Instance> listTrainInstances = new List<weka.core.Instance>(ai / 2);
                List<weka.core.Instance> listTrainInstancesWithDate = new List<weka.core.Instance>(ai / 2);

                int[] counts = new int[allInstancesWithDate.numClasses()];

                long maxjHpTime = -1;
                int maxjHpTimeHp = 2;
                int maxjHpTimeCount = 0;
                bool enoughTrainMinutes = false;
                DateTime firstDate = nowDate.AddMinutes(-trainMinutes);
                int classIdxWithDate = allInstancesWithDate.classIndex();
                int classIdx = allInstances.classIndex();
                for (int j = ai - 1; j >= 0; --j)
                {
                    long jHpTime = jHpTimes[j]; // WekaUtils.GetTimeValueFromInstances(allInstancesWithDate, 1, j);
                    DateTime jHpDate = jHpDates[j];// WekaUtils.GetDateFromTime(jHpTime);
                    DateTime jDate = jDates[j];// WekaUtils.GetDateValueFromInstances(allInstancesWithDate, 0, j);
                    int jHp = jHps[j]; // (int)allInstancesWithDate.instance(j).value(classIdxWithDate);

                    if (enablePerHour)
                    {
                        if (nowDate.Hour != jDate.Hour)
                            continue;
                    }

                    weka.core.Instance instInsert = null;
                    weka.core.Instance instInsertWithDate = null;
                    if (jHpDate <= nowDate)
                    {
                        if (jHpTime > maxjHpTime)
                        {
                            maxjHpTime = jHpTime;
                            maxjHpTimeHp = jHp;
                            maxjHpTimeCount = 1;
                        }
                        else if (jHpTime == maxjHpTime)
                        {
                            maxjHpTimeCount++;
                        }

                        instInsert = new weka.core.DenseInstance(allInstances.instance(j));
                        //instInsert.setDataset(trainInstances);

                        instInsertWithDate = new weka.core.DenseInstance(allInstancesWithDate.instance(j));
                        //instInsertWithDate.setDataset(trainInstancesWithDate);
                    }
                    else
                    {
                        if (TestParameters2.UsePartialHpDataM1 || TestParameters2.UsePartialHpData)
                        {
                            Tuple<int, long> hp = null;
                            if (TestParameters2.UsePartialHpDataM1)
                            {
                                hp = HpData.Instance.GetHpSumByM1(TestParameters2.CandidateParameter.MainSymbol, TestParameters2.CandidateParameter.MainPeriod,
                                    WekaUtils.GetTimeFromDate(nowDate), WekaUtils.GetTimeFromDate(jDate));
                                if (hp.Item2 == 0)
                                    hp = null;
                            }
                            else if (TestParameters2.UsePartialHpData)
                            {
                                var hps = HpData.Instance.GetHpSum(TestParameters2.CandidateParameter.MainSymbol, TestParameters2.CandidateParameter.MainPeriod,
                                    WekaUtils.GetTimeFromDate(nowDate), WekaUtils.GetTimeFromDate(jDate));

                                if (hps.ContainsKey(jDate))
                                {
                                    hp = hps[jDate];
                                }
                            }

                            if (hp != null)
                            {
                                if (WekaUtils.GetDateFromTime(hp.Item2) > nowDate)
                                {
                                    throw new AssertException("hpdate should less than now");
                                }
                                jHp = hp.Item1;
                                jHpTime = hp.Item2;

                                if (jHpTime > maxjHpTime)
                                {
                                    maxjHpTime = jHpTime;
                                    maxjHpTimeHp = jHp;
                                    maxjHpTimeCount = 0;
                                }
                                else if (jHpTime == maxjHpTime)
                                {
                                    maxjHpTimeCount++;
                                }

                                instInsert = new weka.core.DenseInstance(allInstances.instance(j));
                                //instInsert.setDataset(trainInstances);
                                //instInsert.setClassValue(jHp);
                                instInsert.setValue(classIdx, jHp);

                                instInsertWithDate = new weka.core.DenseInstance(allInstancesWithDate.instance(j));
                                //instInsertWithDate.setDataset(trainInstancesWithDate);
                                //instInsertWithDate.setClassValue(jHp);
                                instInsertWithDate.setValue(classIdxWithDate, jHp);
                                instInsertWithDate.setValue(1, jHpTime * 1000);
                            }
                        }

                    }
                    if (instInsert == null)
                        continue;

                    double jClass = jHp;
                    if (enableDiffClass && jClass == preJClass)
                        continue;
                    if (sameClassCount > 0)
                    {
                        if (counts[(int)jClass] >= sameClassCount)
                            continue;
                        counts[(int)jClass]++;
                    }
                    if (enableFilter && j > 0 && Filter(jDate, allInstancesWithDate.instance(j), allInstancesWithDate.instance(j - 1)))
                        continue;
                    if (useInstanceWeight)
                        instInsert.setWeight((nowDate - jDate).TotalMinutes);

                    listTrainInstances.Add(instInsert);
                    listTrainInstancesWithDate.Add(instInsertWithDate);

                    preJClass = jClass;

                    if (jDate <= firstDate)
                    {
                        enoughTrainMinutes = true;
                        break;
                    }
                }

                //weka.core.Instances trainInstances2 = new weka.core.Instances(allInstancesNoDate, 0);
                //for (int x = trainInstances.numInstances() - 1; x >= 0; --x)
                //{
                //    weka.core.Instance inst = new weka.core.DenseInstance(trainInstances.instance(x));
                //    trainInstances2.add(inst);
                //}
                //WekaUtils.SaveInstances(trainInstances2, "d:\\a.arff");

                //if (trainInstances.numInstances() >= trainLength)
                //    break;

                if (!enoughTrainMinutes)
                {
                    Console.WriteLine(string.Format("{0}, not enough trainMinutes",
                        nowDate.ToString(Parameters.DateTimeFormat)));
                    return null;
                }
                if (listTrainInstances.Count < TestParameters2.MinTrainSize)
                {
                    Console.WriteLine(string.Format("{0}, numInstances {1} < minTrainSize {2}",
                        nowDate.ToString(Parameters.DateTimeFormat), listTrainInstances.Count, TestParameters2.MinTrainSize));
                    return null;
                }
                //else if (listTrainInstances.Count == 1)
                //{
                //    lock (WekaUtils.Instance)
                //    {
                //        WekaUtils.Instance.WriteLog("trainInstances.numInstances() == 1, nowDate = " + nowDate.ToString());
                //        if (!System.IO.File.Exists("d:\\a.arff"))
                //        {
                //            WekaUtils.SaveInstances(trainInstances, "d:\\a.arff");
                //        }
                //    }
                //}

                weka.core.Instances trainInstances = new weka.core.Instances(allInstances, listTrainInstances.Count);
                weka.core.Instances trainInstancesWithDate = new weka.core.Instances(allInstancesWithDate, listTrainInstancesWithDate.Count);
                WekaUtils.AddInstanceQuickly(trainInstances, listTrainInstances);
                WekaUtils.AddInstanceQuickly(trainInstancesWithDate, listTrainInstancesWithDate);

                if (enableRemoveLittle)
                {
                    double preClass = 2;
                    for (int ii = 0; ii < trainInstances.numInstances(); ++ii)
                    {
                        var iiClass = trainInstances.instance(ii).classValue();
                        if (iiClass == 2)
                            continue;

                        int jj = ii + 1;
                        while (jj < trainInstances.numInstances())
                        {
                            if (trainInstances.instance(jj).classValue() == iiClass)
                                jj++;
                            else
                                break;
                        }
                        int count = jj - ii;
                        if (count < 5)
                        {
                            for (jj = 0; jj < count; ++jj)
                            {
                                trainInstances.instance(ii + jj).setClassValue(preClass);
                            }
                        }
                        else
                        {
                            preClass = iiClass;
                            ii += count;
                        }
                    }
                }

                if (enableDiffHpTime)
                {
                    Dictionary<long, int> jDictHpTimes = new Dictionary<long, int>();

                    int n = trainInstances.numInstances();
                    List<weka.core.Instance> list1 = new List<weka.core.Instance>(n);
                    List<weka.core.Instance> list2 = new List<weka.core.Instance>(n);

                    //java.util.LinkedList deleteList = new java.util.LinkedList();
                    for (int j = 0; j < n; ++j)
                    {
                        long jHpTime = WekaUtils.GetTimeValueFromInstances(trainInstancesWithDate, 1, j);
                        if (jDictHpTimes.ContainsKey(jHpTime))
                        {
                            continue;
                        }
                        else
                        {
                            jDictHpTimes[jHpTime] = list1.Count;
                            list1.Add(trainInstances.instance(j));
                            list2.Add(trainInstancesWithDate.instance(j));
                        }
                    }
                    weka.core.Instances newTrainInstances = new weka.core.Instances(trainInstances, list1.Count);
                    weka.core.Instances newTrainInstancesWithDate = new weka.core.Instances(trainInstancesWithDate, list2.Count);
                    WekaUtils.AddInstanceQuickly(newTrainInstances, list1);
                    WekaUtils.AddInstanceQuickly(newTrainInstancesWithDate, list2);

                    trainInstances = newTrainInstances;
                    trainInstancesWithDate = newTrainInstancesWithDate;
                }

                if (enableRemoveLargeThanMid)
                {
                    int n = trainInstances.numInstances();
                    long[] lastTimes = new long[n];
                    for (int j = 0; j < n; ++j)
                    {
                        long openTime = WekaUtils.GetTimeValueFromInstances(trainInstancesWithDate, 0, j);
                        long closeTime = WekaUtils.GetTimeValueFromInstances(trainInstancesWithDate, 1, j);

                        lastTimes[j] = (long)(closeTime - openTime);
                    }
                    Array.Sort(lastTimes);
                    long midLastTime = lastTimes[lastTimes.Count() / 2];

                    List<weka.core.Instance> list1 = new List<weka.core.Instance>(n);
                    List<weka.core.Instance> list2 = new List<weka.core.Instance>(n);
                    //java.util.LinkedList deleteList = new java.util.LinkedList();
                    for (int j = 0; j < n; ++j)
                    {
                        if (lastTimes[j] > midLastTime)
                        {
                            //deleteList.add(trainInstances.instance(j));
                        }
                        else
                        {
                            list1.Add(trainInstances.instance(j));
                            list2.Add(trainInstancesWithDate.instance(j));
                        }
                    }
                    weka.core.Instances newTrainInstances = new weka.core.Instances(trainInstances, list1.Count);
                    weka.core.Instances newTrainInstancesWithDate = new weka.core.Instances(trainInstancesWithDate, list2.Count);
                    WekaUtils.AddInstanceQuickly(newTrainInstances, list1);
                    WekaUtils.AddInstanceQuickly(newTrainInstancesWithDate, list2);

                    trainInstances = newTrainInstances;
                    trainInstancesWithDate = newTrainInstancesWithDate;
                    //trainInstances.removeAll(deleteList);
                }

                if (!string.IsNullOrEmpty(sampleFile))
                {
                    lock (sampleFile)
                    {
                        if (!System.IO.File.Exists(sampleFile))
                        {
                            WekaUtils.SaveInstances(trainInstancesWithDate, sampleFile);
                        }
                    }
                }

                //using (StreamWriter sw = new StreamWriter("d:\\p.txt", true))
                //{
                //    sw.Write("{0},{1},", nowDate.ToString(Parameters.DateTimeFormat), nowHpDate.ToString(Parameters.DateTimeFormat));
                //}

                return new Tuple<weka.core.Instances, weka.core.Instances, long, int, int>(trainInstances, trainInstancesWithDate, maxjHpTime, maxjHpTimeHp, maxjHpTimeCount);
            };

            #endregion

            //allInstancesNoDate = allInstances;
            if (!TestParameters2.RealTimeMode)
            {
                int tpb = 0, fpb = 0, tps = 0, fps = 0;
                int db = 0, ds = 0, dn = 0;

                int parallelStep = 1;
                if (TestParameters.EnableMultiThread)
                {
                    parallelStep = 100;
                }
                int startIdx = TestParameters2.MinTrainPeriod * 2 / 3;
                for (int i0 = startIdx; i0 < allInstancesWithDate.numInstances() - step; i0 += step * parallelStep)
                {
                    List<Tuple<int, int>> toTest = new List<Tuple<int, int>>();
                    for (int i = i0; i < Math.Min(i0 + step * parallelStep, allInstancesWithDate.numInstances() - step); i += step)
                    {
                        toTest.Add(new Tuple<int, int>(i, toTest.Count));
                    }

                    var toRet0 = new Tuple<weka.core.Instances, weka.core.Instances, long, int, int>[toTest.Count];
                    if (TestParameters.EnableMultiThread)
                    {
                        Parallel.ForEach(toTest, (tuple) =>
                            {
                                int i = tuple.Item1 - i0;
                                toRet0[i] = action(tuple);
                            });
                    }
                    else
                    {
                        for (int i = 0; i < toTest.Count; ++i)
                        {
                            var r = action(toTest[i]);
                            toRet0[i] = r;
                        }
                    }

                    object[, ,] toRet = new object[toTest.Count, step, 9];
                    bool[] toRet1 = new bool[toTest.Count];
                    for (int i = 0; i < toTest.Count; ++i)
                    {
                        for (int j = 0; j < step; ++j)
                            toRet[i, j, 0] = 2;

                        if (toRet0[i] != null)
                        {
                            var maxjHpTime = toRet0[i].Item3;
                            var maxjHpTimeHp = toRet0[i].Item4;
                            var maxjHpTimeCount = toRet0[i].Item5;

                            toRet1[i] = IncrementTestTrainCheck(resultFile, maxjHpTime, maxjHpTimeHp, maxjHpTimeCount, toTest[i]);
                        }
                    }

                    if (TestParameters.EnableMultiThread)
                    {
                        Parallel.ForEach(toTest, (tuple) =>
                            {
                                int i = tuple.Item1 - i0;

                                if (toRet0[i] != null)
                                {
                                    var trainInstances = toRet0[i].Item1;
                                    var trainInstancesWithDate = toRet0[i].Item2;
                                    var maxjHpTime = toRet0[i].Item3;
                                    var maxjHpTimeHp = toRet0[i].Item4;
                                    var r = IncrementTestTrain(toRet1[i], clsCreator, resultFile, step, trainInstances, trainInstancesWithDate, allInstances, allInstancesWithDate,
                                        maxjHpTime, maxjHpTimeHp, toTest[i]);

                                    if (r != null)
                                    {
                                        for (int j = 0; j < toRet.GetLength(1); ++j)
                                            for (int k = 0; k < toRet.GetLength(2); ++k)
                                                toRet[i, j, k] = r[j, k];
                                    }
                                }
                            });
                    }
                    else
                    {
                        for (int i = 0; i < toTest.Count; ++i)
                        {
                            if (toRet0[i] != null)
                            {
                                var trainInstances = toRet0[i].Item1;
                                var trainInstancesWithDate = toRet0[i].Item2;
                                var maxjHpTime = toRet0[i].Item3;
                                var maxjHpTimeHp = toRet0[i].Item4;
                                var r = IncrementTestTrain(toRet1[i], clsCreator, resultFile, step, trainInstances, trainInstancesWithDate, allInstances, allInstancesWithDate,
                                    maxjHpTime, maxjHpTimeHp, toTest[i]);

                                if (r != null)
                                {
                                    for (int j = 0; j < toRet.GetLength(1); ++j)
                                        for (int k = 0; k < toRet.GetLength(2); ++k)
                                            toRet[i, j, k] = r[j, k];
                                }
                            }
                        }
                    }

                    for (int i = 0; i < toTest.Count; ++i)
                    {
                        //action(toTest[i]);
                        for (int j = 0; j < step; ++j)
                        {
                            int d = (int)toRet[i, j, 0];
                            if (d != 0 && d != 1 && d != 2)
                                throw new AssertException("d should be -1, 0, 1 or 2. but it's" + d.ToString());

                            if (toRet[i, j, 6] == null)
                            {
                                //Console.WriteLine("toRet[i, j, 6] == null");
                                continue;
                            }
                            long maxJHpTime = (long)toRet[i, j, 6];
                            //if (lastMaxJHpTime >= (long)toRet[i, j, 6])
                            //    continue;
                            //lastMaxJHpTime = (long)toRet[i, j, 6];

                            if (d == 0)
                                db++;
                            else if (d == 1)
                                ds++;
                            else
                                dn++;

                            int v = (int)toRet[i, j, 1];

                            if (d != 2)
                            {
                                if (v == 3 || d == v)
                                {
                                    if (d == 0)
                                    {
                                        tpb++;
                                    }
                                    else if (d == 1)
                                    {
                                        tps++;
                                    }
                                }
                                else
                                {
                                    if (d == 0)
                                    {
                                        fpb++;
                                    }
                                    else if (d == 1)
                                    {
                                        fps++;
                                    }
                                }
                            }

                            DateTime nowDate = WekaUtils.GetDateFromTime((long)toRet[i, j, 3]);
                            DateTime nextDate = WekaUtils.GetDateFromTime((long)toRet[i, j, 2]);

                            //nextDate = WekaUtils.GetDateFromTime(maxJHpTime);

                            //if (j == 0)
                            {
                                if (tpb + fpb + tps + fps != 0)
                                {
                                    ret = (string.Format("{0}, tn={1},tc={2}, db={3},ds={4},dn={5}, tpb={6},fpb={7},tps={8},fps={9},p={10}",
                                            nextDate.ToString(Parameters.DateTimeFormat), toRet[i, j, 4], toRet[i, j, 5],
                                            db, ds, dn,
                                            tpb, fpb, tps, fps, ((double)(tpb+tps) / (tpb + fpb + tps + fps)).ToString("F2")));
                                }
                                else
                                {
                                    ret = (string.Format("{0}, tn={1},tc={2}, db={3},ds={4},dn={5}, tpb={6},fpb={7},tps={8},fps={9},p={10}",
                                            nextDate.ToString(Parameters.DateTimeFormat), toRet[i, j, 4], toRet[i, j, 5],
                                            db, ds, dn,
                                            tpb, fpb, tps, fps, 0));
                                }
                                WekaUtils.Instance.WriteLog(ret);
                            }

                            //if (d != 2)
                            {
                                using (StreamWriter sw = new StreamWriter(resultFile, true))
                                {
                                    sw.WriteLine(string.Format("{1}, {2}, {6}, {3}, {4}, {5}", nowDate,
                                        nextDate.ToString(Parameters.DateTimeFormat),
                                        d, v, (double)toRet[i, j, 7],
                                        WekaUtils.GetDateFromTime(maxJHpTime).ToString(Parameters.DateTimeFormat),
                                        toRet[i, j, 8]));
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                for (int i0 = allInstancesWithDate.numInstances() - 1; i0 < allInstancesWithDate.numInstances() && i0 >= 0; i0++)
                {
                    List<Tuple<int, int>> toTest = new List<Tuple<int, int>>();
                    toTest.Add(new Tuple<int, int>(i0, toTest.Count));

                    var toRet0 = new Tuple<weka.core.Instances, weka.core.Instances, long, int, int>[toTest.Count];

                    for (int i = 0; i < toTest.Count; ++i)
                    {
                        var r = action(toTest[i]);
                        toRet0[i] = r;
                    }

                    object[, ,] toRet = new object[toTest.Count, step, 9];
                    for (int i = 0; i < toTest.Count; ++i)
                    {
                        for (int j = 0; j < toRet.GetLength(1); ++j)
                            toRet[i, j, 0] = 2;

                        if (toRet0[i] != null)
                        {
                            var trainInstances = toRet0[i].Item1;
                            var trainInstancesWithDate = toRet0[i].Item2;
                            var maxjHpTime = toRet0[i].Item3;
                            var maxjHpTimeHp = toRet0[i].Item4;
                            var maxjHpTimeCount = toRet0[i].Item5;

                            bool b = IncrementTestTrainCheck(resultFile, maxjHpTime, maxjHpTimeHp, maxjHpTimeCount, toTest[i]);
                            var r = IncrementTestTrain(b, clsCreator, resultFile, step, trainInstances, trainInstancesWithDate, allInstances, allInstancesWithDate,
                                maxjHpTime, maxjHpTimeHp, toTest[i]);

                            if (r != null)
                            {
                                for (int j = 0; j < toRet.GetLength(1); ++j)
                                    for (int k = 0; k < toRet.GetLength(2); ++k)
                                        toRet[i, j, k] = r[j, k];
                            }
                        }
                    }

                    for (int j = 0; j < step; ++j)
                    {
                        int d = (int)toRet[0, j, 0];
                        if (d != 0 && d != 1 && d != 2)
                            throw new AssertException("d should be -1, 0, 1 or 2.");

                        if (toRet[0, j, 6] == null)
                            continue;
                        long maxJHpTime = (long)toRet[0, j, 6];
                        //if (lastMaxJHpTime >= (long)toRet[i, j, 6])
                        //    continue;
                        //lastMaxJHpTime = (long)toRet[i, j, 6];

                        int v = (int)toRet[0, j, 1];

                        DateTime nowDate = WekaUtils.GetDateFromTime((long)toRet[0, j, 3]);
                        DateTime nextDate = WekaUtils.GetDateFromTime((long)toRet[0, j, 2]);

                        //nextDate = WekaUtils.GetDateFromTime(maxJHpTime);
                        //if (d != 2)
                        {
                            using (StreamWriter sw = new StreamWriter(resultFile, true))
                            {
                                sw.WriteLine(string.Format("{1}, {2}, {6}, {3}, {4}, {5}", nowDate,
                                    nextDate.ToString(Parameters.DateTimeFormat),
                                    d, v, (double)toRet[0, j, 7],
                                    WekaUtils.GetDateFromTime(maxJHpTime).ToString(Parameters.DateTimeFormat),
                                    toRet[0, j, 8]));
                            }
                        }
                    }
                }
            }

            return ret;
        }