Пример #1
0
        /// <summary>
        /// Combinedスタンプから構成される解をOriginalスタンプの解に変換する
        /// </summary>
        /// <param name="combined_solution">Combinedスタンプから成る解</param>
        /// <returns>Originalスタンプから構成される解</returns>
        public Solution CombinedSolutionToOriginalSolution(Solution combined_solution)
        {
            // combined_stampをオリジナルスタンプに分解してtmp_origin_solutionに追加
            Solution tmp_origin_solution = new Solution();
            {
                List <Tuple <Stamp, short, short> > combined_answer_list = combined_solution.GetStampAnswerList();
                foreach (var combined_answer in combined_answer_list)
                {
                    CombinedStamp combined_stamp = (CombinedStamp)combined_answer.Item1;
                    List <Tuple <short, short, short> > origin_stamp_config_list = combined_stamp.GetOriginStampConfigList();
                    short combined_stamp_slide_x = combined_answer.Item2;
                    short combined_stamp_slide_y = combined_answer.Item3;

                    foreach (var origin_stamp_config in origin_stamp_config_list)
                    {
                        short origin_stamp_idx     = origin_stamp_config.Item1;
                        short origin_stamp_slide_x = origin_stamp_config.Item2;
                        short origin_stamp_slide_y = origin_stamp_config.Item3;
                        Stamp origin_stamp_object  = this.origin_stamp_object_list[origin_stamp_idx];
                        tmp_origin_solution.AddStampAnswer(origin_stamp_object,
                                                           (short)(origin_stamp_slide_x + combined_stamp_slide_x),
                                                           (short)(origin_stamp_slide_y + combined_stamp_slide_y));
                    }
                }
            }

            // 枠外にはみ出たオリジナルスタンプ以外をorigin_solutionに追加
            Solution origin_solution = new Solution();

            {
                List <Tuple <Stamp, short, short> > origin_stamp_answer_list = tmp_origin_solution.GetStampAnswerList();

                foreach (var origin_stamp_answer in origin_stamp_answer_list)
                {
                    Stamp stamp   = origin_stamp_answer.Item1;
                    short slide_x = origin_stamp_answer.Item2;
                    short slide_y = origin_stamp_answer.Item3;

                    // x方向チェック
                    if (stamp.GetXSize() + slide_x <= 0 || slide_x >= field.GetXSize())
                    {
                        continue;
                    }

                    // y方向チェック
                    if (stamp.GetYSize() + slide_y <= 0 || slide_y >= field.GetYSize())
                    {
                        continue;
                    }

                    origin_solution.AddStampAnswer(stamp, slide_x, slide_y);
                }
            }

            return(origin_solution);
        }
Пример #2
0
        private void AddCombinedStamp(Instance instance, CombinedStamp combined_stamp, short slide_x, short slide_y)
        {
            var origin_stamp_list = instance.GetOriginalStampObjectList();

            foreach (var origin_stamp_config in combined_stamp.GetOriginStampConfigList())
            {
                Stamp origin_stamp = origin_stamp_list[origin_stamp_config.Item1];
                short origin_x     = origin_stamp_config.Item2;
                short origin_y     = origin_stamp_config.Item3;
                AddOriginalStamp(origin_stamp, (short)(origin_x + slide_x), (short)(origin_y + slide_y));
            }
        }
Пример #3
0
        /// <summary>
        /// できるだけ面積の小さい combined stamp を構築する。
        /// </summary>
        public void MakeCombinedStampList()
        {
            int           max_count = 640 * 480;
            CombinedStamp candidate_combined_stamp = new CombinedStamp();

            // combined_stamp_listに追加
            foreach (var origin_stamp in this.origin_stamp_object_list)
            {
                CombinedStamp cs = new CombinedStamp();
                cs.AddStamp(this, origin_stamp, 0, 0);
                cs.AddStamp(this, origin_stamp, 0, 1);
                this.combined_stamp_object_list.Add(cs);
            }


            // combined_stamp_listの中から黒いセルが一番少ないスタンプを抽出する
            foreach (var combined_stamp in this.combined_stamp_object_list)
            {
                if (max_count > combined_stamp.GetBlackCellCoordinate().Count())
                {
                    max_count = combined_stamp.GetBlackCellCoordinate().Count();
                    candidate_combined_stamp = combined_stamp;
                }
            }

            this.combined_stamp_object_list.Clear();
            this.combined_stamp_object_list.Add(candidate_combined_stamp);
            return;


            //#region OrTools
            //Field single_cell_field = new Field();
            //short parameter_field_size = 80;
            //short M = parameter_field_size;
            //short N = parameter_field_size;
            //// ここで、single_cell_fieldの各種メンバ変数を初期化
            //single_cell_field.SetYSize(M);
            //single_cell_field.SetXSize(N);
            //for (short y = 0; y < M; y++)
            //{
            //    for (short x = 0; x < N; x++)
            //    {
            //        if ((y == (short)(M/2)) && (x == (short)(N/2)))
            //        {
            //            single_cell_field.AddBlackCellCoordinates(y, x);
            //        }
            //        else
            //        {
            //            single_cell_field.AddWhiteCellCoordinates(y, x);
            //        }
            //    }
            //}

            //// Creates the model.
            //CpModel model = new CpModel();
            //Dictionary<Tuple<int, int>, IntVar> stamp_variables = new Dictionary<Tuple<int, int>, IntVar>();
            //Dictionary<Tuple<int, int>, IntVar> field_variables = new Dictionary<Tuple<int, int>, IntVar>();
            //// スタンプ変数
            //for (int y = (candidate_combined_stamp.GetYSize() - 1) * (-1); y < single_cell_field.GetYSize(); ++y)
            //{
            //    for (int x = (candidate_combined_stamp.GetXSize() - 1) * (-1); x < single_cell_field.GetXSize(); ++x)
            //    {
            //        string name = "stamp_" + y.ToString() + "_" + x.ToString();
            //        stamp_variables[new Tuple<int, int>(y, x)] = model.NewBoolVar(name);
            //    }
            //}
            //// フィールド変数
            //for (int y = 0; y < single_cell_field.GetYSize(); ++y)
            //{
            //    for (int x = 0; x < single_cell_field.GetXSize(); ++x)
            //    {
            //        string name = "field" + y.ToString() + "_" + x.ToString();
            //        field_variables[new Tuple<int, int>(y, x)] = model.NewBoolVar(name);
            //    }
            //}


            //List<Tuple<short, short>> field_black_cell_coordinates = single_cell_field.GetBlackCellCoordinates();
            //foreach (var field_cell in field_black_cell_coordinates)
            //{
            //    List<IntVar> var_take_xors = new List<IntVar>();
            //    List<Tuple<short, short>> stamp_black_cell_coordinates = candidate_combined_stamp.GetBlackCellCoordinate();
            //    foreach (var stamp_cell in stamp_black_cell_coordinates)
            //    {
            //        int y_ind = field_cell.Item1 - stamp_cell.Item1;
            //        int x_ind = field_cell.Item2 - stamp_cell.Item2;
            //        var_take_xors.Add(stamp_variables[new Tuple<int, int>(y_ind, x_ind)]);
            //    }
            //    model.AddBoolXor(var_take_xors);
            //}

            //List<Tuple<short, short>> field_white_cell_coordinates = single_cell_field.GetWhiteCellCoordinates();
            //foreach (var field_cell in field_white_cell_coordinates)
            //{
            //    List<IntVar> var_take_xors = new List<IntVar>();
            //    List<Tuple<short, short>> stamp_black_cell_coordinates = candidate_combined_stamp.GetBlackCellCoordinate();
            //    foreach (var stamp_cell in stamp_black_cell_coordinates)
            //    {
            //        int y_ind = field_cell.Item1 - stamp_cell.Item1;
            //        int x_ind = field_cell.Item2 - stamp_cell.Item2;
            //        var_take_xors.Add(stamp_variables[new Tuple<int, int>(y_ind, x_ind)]);

            //    }

            //    // target fieldの情報を制約に追加.
            //    List<IntVar> field_variable = new List<IntVar>();
            //    field_variable.Add(field_variables[new Tuple<int, int>(field_cell.Item1, field_cell.Item2)]);
            //    model.AddBoolAnd(field_variable);

            //    var_take_xors.Add(field_variables[new Tuple<int, int>(field_cell.Item1, field_cell.Item2)]);
            //    model.AddBoolXor(var_take_xors);
            //}

            //// 求解
            //CpSolver solver = new CpSolver();
            //solver.StringParameters = "max_time_in_seconds:5.0";
            ////Console.WriteLine("start!!\n");
            //CpSolverStatus status = solver.Solve(model);

            //// --

            //// 解の検証
            ////Console.WriteLine("Pressing stamp is:");
            //Field dummy_field = new Field();
            //// ここで、single_cell_fieldの各種メンバ変数を初期化
            //dummy_field.SetYSize(M);
            //dummy_field.SetXSize(N);
            //dummy_field.InitMyField();

            //if (status == CpSolverStatus.Feasible)
            //{
            //    for (int y = (candidate_combined_stamp.GetYSize() - 1) * (-1); y < dummy_field.GetYSize(); ++y)
            //    {
            //        for (int x = (candidate_combined_stamp.GetXSize() - 1) * (-1); x < dummy_field.GetXSize(); ++x)
            //        {
            //            Tuple<int, int> cur_pos = new Tuple<int, int>(y, x);
            //            if (solver.Value(stamp_variables[cur_pos]) == 1)
            //            {


            //                dummy_field.PressStamp(candidate_combined_stamp, (short)x, (short)y);
            //                Console.Write("1");
            //            }
            //            else
            //            {
            //                Console.Write("0");
            //            }
            //        }
            //        Console.WriteLine();
            //    }

            //    Console.WriteLine("\nmy_field is :");
            //    dummy_field.PrintMyself();
            //    Console.WriteLine("\ntarget_field is :");
            //    single_cell_field.PrintTargetField();
            //}

            //#endregion
            //foreach (var combined_stamp_object in this.combined_stamp_object_list)
            //{
            //    combined_stamp_object.Print();
            //}
        }