/// <summary>
        /// Get similarity ranking of model answer
        /// </summary>
        /// <param name="answers"></param>
        /// <param name="modelAnswer"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<AnswerSheet> ModelAnswerExtraction(List<AnswerSheet> answers, AnswerSheet modelAnswer, string name)
        {
            this.name = name;
            List<AnswerSheet> sortedAnswers = SortAnswerByModelAnswerSimilarity(answers, modelAnswer);

            return sortedAnswers;
        }
        /// <summary>
        /// Sort answer sheet by model answer similarity
        /// </summary>
        /// <param name="answers"></param>
        /// <param name="modelAnswer"></param>
        /// <returns></returns>
        private List<AnswerSheet> SortAnswerByModelAnswerSimilarity(List<AnswerSheet> answers, AnswerSheet modelAnswer)
        {
            // calc distance scores
            List<AnswerStep> modelAnsStepList = GroupAnswerStep(modelAnswer.Strokes);
            for (int i = 0, ilen = answers.Count; i < ilen; i++)
            {
                List<AnswerStep> ansStepList = GroupAnswerStep(answers[i].Strokes);
                DPMatchingResult result = CalcAnswerProcessSimilarity(modelAnsStepList, ansStepList);

                answers[i].ModelAnswerDistance = result.Distance;
            }

            // sort
            List<AnswerSheet> ranking = new List<AnswerSheet>(answers.OrderBy(s => s.ModelAnswerDistance));

            return ranking;
        }
        /// <summary>
        /// Get answer sheet object by loading writing data file
        /// </summary>
        /// <param name="path">ファイルパス</param>
        /// <returns></returns>
        public AnswerSheet LoadAnswerSheetFromFile(string path, int id = 0)
        {
            AnswerSheet ans = new AnswerSheet(id);
            ans.FilePath = path;
            ans.Name = System.IO.Path.GetFileNameWithoutExtension(path);
            ans.Strokes = LoadStrokesFromFile(path);

            return ans;
        }
        /// <summary>
        /// Initialization with answer information
        /// </summary>
        /// <param name="ans"></param>
        /// <param name="controller"></param>
        /// <param name="w"></param>
        public AnswerSheetItemData(AnswerSheet ans, AnswerSheetVisualizer v, AnswerGroupWindow w)
        {
            this.parentWindow = w;
            this.answerData = ans;
            this.visualizer = v;
            this.strokes = new StrokeCollection();
            foreach (AnalysisPenStroke s in ans.Strokes)
            {
                this.strokes.Add(s.GetStrokeObject(Config.OutputThumbnailCanvasWidth, Config.OutputThumbnailCanvasHeight));
            }
            this.NameLabel = ans.Name;
            this.timeLabel = "Time: " + ((double)ans.AnswerTime / 1000.0).ToString("f3") + "(sec)";

            double writingRatio = ans.WritingRatio;
            this.writingTime = new GridLength(MaxWritingTime * writingRatio * 2.5);
            this.writingTimeLabel = (writingRatio * 100.0).ToString("F2") + "%";

            double speedAvg = ans.WritingSpeedAvg;
            this.writingSpeedAvg = new GridLength(MaxWritingTime * (speedAvg - 0.5));
            this.writingSpeedAvgLabel = speedAvg.ToString("F4");

            double speedVar = ans.WritingSpeedVar;
            this.writingSpeedVar = new GridLength(MaxWritingTime * speedVar);
            this.writingSpeedVarLabel = speedVar.ToString("F4");
        }