Beispiel #1
0
        public Solution CalcSolution(Instance instance)
        {
            Solution solution = null;

            // 黒いセルが1つのスタンプを取得
            CombinedStamp single_cell_stamp = null;

            foreach (var combined_stamp in instance.GetCombinedStampObjectList())
            {
                if (combined_stamp.GetBlackCellCoordinate().Count() == 1)
                {
                    single_cell_stamp = combined_stamp;
                    break;
                }
            }
            short single_cell_y = single_cell_stamp.GetBlackCellCoordinate()[0].Item1;
            short single_cell_x = single_cell_stamp.GetBlackCellCoordinate()[0].Item2;

            // ターゲットフィールドの黒い場所にあてがうように黒いセルを配置する
            Field field = instance.GetField();

            foreach (var black_cell_coordinate in field.GetBlackCellCoordinates())
            {
                short target_cell_y = black_cell_coordinate.Item1;
                short target_cell_x = black_cell_coordinate.Item2;

                solution.AddStampAnswer(single_cell_stamp,
                                        (short)(target_cell_x - single_cell_x),
                                        (short)(target_cell_y - single_cell_y));
            }

            return(solution);
        }
Beispiel #2
0
        public Solution CalcSolution(Instance instance)
        {
            Solution solution = new Solution();

            // CpModelに変数を追加
            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>();
            // スタンプ変数

            CombinedStamp cs    = instance.GetCombinedStampObjectList()[0];
            Field         field = new Field();

            field = instance.GetField();

            for (int y = (cs.GetYSize() - 1) * (-1); y < field.GetYSize(); ++y)
            {
                for (int x = (cs.GetXSize() - 1) * (-1); x < 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 < field.GetYSize(); ++y)
            //{
            //    for (int x = 0; x < 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 = 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 = cs.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);
            }

            IntVar        constant_true      = model.NewBoolVar("constant_true");
            List <IntVar> constant_true_list = new List <IntVar>();

            constant_true_list.Add(constant_true);
            model.AddBoolAnd(constant_true_list);

            List <Tuple <short, short> > field_white_cell_coordinates = 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 = cs.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(constant_true);
                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);

            if (status == CpSolverStatus.Feasible)
            {
                for (int y = (cs.GetYSize() - 1) * (-1); y < field.GetYSize(); ++y)
                {
                    for (int x = (cs.GetXSize() - 1) * (-1); x < field.GetXSize(); ++x)
                    {
                        Tuple <int, int> cur_pos = new Tuple <int, int>(y, x);
                        if (solver.Value(stamp_variables[cur_pos]) == 1)
                        {
                            solution.AddStampAnswer(cs, (short)x, (short)y);
                            //field.PressStamp(cs, (short)x, (short)y);
                        }
                        //Tuple<int, int> cur_pos = new Tuple<int, int>(y, x);
                        //if (solver.Value(stamp_variables[cur_pos]) == 1)
                        //{
                        //    field.PressStamp(cs, (short)x, (short)y);
                        //    Console.Write("1");
                        //}
                        //else
                        //{
                        //    Console.Write("0");
                        //}
                    }
                    //Console.WriteLine();
                }

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

            return(solution);

            //    // 解の検証
            //    Console.WriteLine("Pressing stamp is:");
            //if (status == CpSolverStatus.Feasible)
            //{
            //    for (int y = (stamp_size - 1) * (-1); y < field_size; ++y)
            //    {
            //        for (int x = (stamp_size - 1) * (-1); x < field_size; ++x)
            //        {
            //            Tuple<int, int> cur_pos = new Tuple<int, int>(y, x);
            //            if (solver.Value(stamp_variables[cur_pos]) == 1)
            //            {
            //                field.PressStamp(stamp, (short)x, (short)y);
            //                Console.Write("1");
            //            }
            //            else
            //            {
            //                Console.Write("0");
            //            }
            //        }
            //        Console.WriteLine();
            //    }

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