Exemple #1
0
    /**
     *
     * Traffic lights problem.
     *
     * CSPLib problem 16
     * http://www.cs.st-andrews.ac.uk/~ianm/CSPLib/prob/prob016/index.html
     * """
     * Specification:
     * Consider a four way traffic junction with eight traffic lights. Four of the traffic
     * lights are for the vehicles and can be represented by the variables V1 to V4 with domains
     * {r,ry,g,y} (for red, red-yellow, green and yellow). The other four traffic lights are
     * for the pedestrians and can be represented by the variables P1 to P4 with domains {r,g}.
     *
     * The constraints on these variables can be modelled by quaternary constraints on
     * (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just the tuples
     * {(r,r,g,g), (ry,r,y,r), (g,g,r,r), (y,r,ry,r)}.
     *
     * It would be interesting to consider other types of junction (e.g. five roads
     * intersecting) as well as modelling the evolution over time of the traffic light sequence.
     * ...
     *
     * Results
     * Only 2^2 out of the 2^12 possible assignments are solutions.
     *
     * (V1,P1,V2,P2,V3,P3,V4,P4) =
     * {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r), (y,r,ry,r,y,r,ry,r)}
     * [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1, 2,1)}
     * The problem has relative few constraints, but each is very
     * tight. Local propagation appears to be rather ineffective on this
     * problem.
     *
     * """
     * Note: In this model we use only the constraint
     *  solver.AllowedAssignments().
     *
     *
     * See http://www.hakank.org/or-tools/traffic_lights.py
     *
     */
    private static void Solve()
    {
        Solver solver = new Solver("TrafficLights");

        //
        // data
        //
        int n = 4;

        int r  = 0;
        int ry = 1;
        int g  = 2;
        int y  = 3;

        string[] lights = { "r", "ry", "g", "y" };

        // The allowed combinations
        IntTupleSet allowed = new IntTupleSet(4);

        allowed.InsertAll(new int[, ] {
            { r, r, g, g },
            { ry, r, y, r },
            { g, g, r, r },
            { y, r, ry, r }
        });
        //
        // Decision variables
        //
        IntVar[] V = solver.MakeIntVarArray(n, 0, n - 1, "V");
        IntVar[] P = solver.MakeIntVarArray(n, 0, n - 1, "P");

        // for search
        IntVar[] VP = new IntVar[2 * n];
        for (int i = 0; i < n; i++)
        {
            VP[i]     = V[i];
            VP[i + n] = P[i];
        }

        //
        // Constraints
        //
        for (int i = 0; i < n; i++)
        {
            int      j   = (1 + i) % n;
            IntVar[] tmp = new IntVar[] { V[i], P[i], V[j], P[j] };
            solver.Add(tmp.AllowedAssignments(allowed));
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(VP,
                                              Solver.CHOOSE_FIRST_UNBOUND,
                                              Solver.ASSIGN_MIN_VALUE);


        solver.NewSearch(db);

        while (solver.NextSolution())
        {
            for (int i = 0; i < n; i++)
            {
                Console.Write("{0,2} {1,2} ",
                              lights[V[i].Value()],
                              lights[P[i].Value()]);
            }
            Console.WriteLine();
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }
Exemple #2
0
    /**
     *
     * Hidato puzzle in Google CP Solver.
     *
     * http://www.hidato.com/
     * """
     * Puzzles start semi-filled with numbered tiles.
     * The first and last numbers are circled.
     * Connect the numbers together to win. Consecutive
     * number must touch horizontally, vertically, or
     * diagonally.
     * """
     *
     * This is a port of the Python model hidato_table.py
     * made by Laurent Perron (using AllowedAssignments),
     * based on my (much slower) model hidato.py.
     *
     */
    private static void Solve(int model = 1)
    {
        Solver solver = new Solver("HidatoTable");

        //
        // models, a 0 indicates an open cell which number is not yet known.
        //

        int[,] puzzle = null;
        if (model == 1)
        {
            // Simple problem

            // Solution 1:
            // 6  7  9
            // 5  2  8
            // 1  4  3
            int[,] puzzle1 = { { 6, 0, 9 }, { 0, 2, 8 }, { 1, 0, 0 } };
            puzzle         = puzzle1;
        }
        else if (model == 2)
        {
            int[,] puzzle2 = { { 0, 44, 41,  0,  0, 0,  0 }, {  0, 43, 0, 28, 29, 0, 0 }, { 0,  1, 0, 0,  0, 33, 0 },
                               { 0,  2, 25,  4, 34, 0, 36 }, { 49, 16, 0, 23,  0, 0, 0 }, { 0, 19, 0, 0, 12,  7, 0 },
                               { 0,  0,  0, 14,  0, 0,  0 } };
            puzzle = puzzle2;
        }
        else if (model == 3)
        {
            // Problems from the book:
            // Gyora Bededek: "Hidato: 2000 Pure Logic Puzzles"
            // Problem 1 (Practice)
            int[,] puzzle3 =
            {
                { 0, 0, 20, 0, 0 }, { 0, 0, 0, 16, 18 }, { 22, 0, 15, 0, 0 }, { 23, 0, 1, 14, 11 }, { 0, 25, 0, 0, 12 }
            };
            puzzle = puzzle3;
        }
        else if (model == 4)
        {
            // problem 2 (Practice)
            int[,] puzzle4 =
            {
                { 0, 0, 0, 0, 14 }, { 0, 18, 12, 0, 0 }, { 0, 0, 17, 4, 5 }, { 0, 0, 7, 0, 0 }, { 9, 8, 25, 1, 0 }
            };
            puzzle = puzzle4;
        }
        else if (model == 5)
        {
            // problem 3 (Beginner)
            int[,] puzzle5 = { { 0, 26, 0, 0,  0, 18 }, { 0, 0, 27, 0, 0, 19 }, { 31, 23, 0,  0, 14, 0 },
                               { 0, 33, 8, 0, 15,  1 }, { 0, 0,  0, 5, 0,  0 }, { 35, 36, 0, 10,  0, 0 } };
            puzzle = puzzle5;
        }
        else if (model == 6)
        {
            // Problem 15 (Intermediate)
            int[,] puzzle6 = { { 64, 0, 0,  0,  0, 0,  0,  0 }, {  1, 63,  0, 59, 15, 57, 53,  0 },
                               {  0, 4, 0, 14,  0, 0,  0,  0 }, {  3,  0, 11,  0, 20, 19,  0, 50 },
                               {  0, 0, 0,  0, 22, 0, 48, 40 }, {  9,  0,  0, 32, 23,  0,  0, 41 },
                               { 27, 0, 0,  0, 36, 0, 46,  0 }, { 28, 30,  0, 35,  0,  0,  0,  0 } };
            puzzle = puzzle6;
        }

        int r = puzzle.GetLength(0);
        int c = puzzle.GetLength(1);

        Console.WriteLine();
        Console.WriteLine("----- Solving problem {0} -----", model);
        Console.WriteLine();

        PrintMatrix(puzzle);

        //
        // Decision variables
        //
        IntVar[] positions = solver.MakeIntVarArray(r * c, 0, r * c - 1, "p");

        //
        // Constraints
        //
        solver.Add(positions.AllDifferent());

        //
        // Fill in the clues
        //
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                if (puzzle[i, j] > 0)
                {
                    solver.Add(positions[puzzle[i, j] - 1] == i * c + j);
                }
            }
        }

        // Consecutive numbers much touch each other in the grid.
        // We use an allowed assignment constraint to model it.
        IntTupleSet close_tuples = BuildPairs(r, c);

        for (int k = 1; k < r * c - 1; k++)
        {
            IntVar[] tmp = new IntVar[] { positions[k], positions[k + 1] };
            solver.Add(tmp.AllowedAssignments(close_tuples));
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(positions, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);

        int num_solution = 0;

        while (solver.NextSolution())
        {
            num_solution++;
            PrintOneSolution(positions, r, c, num_solution);
        }

        Console.WriteLine("\nSolutions: " + solver.Solutions());
        Console.WriteLine("WallTime: " + solver.WallTime() + "ms ");
        Console.WriteLine("Failures: " + solver.Failures());
        Console.WriteLine("Branches: " + solver.Branches());

        solver.EndSearch();
    }
Exemple #3
0
  /**
   *
   * Hidato puzzle in Google CP Solver.
   *
   * http://www.hidato.com/
   * """
   * Puzzles start semi-filled with numbered tiles.
   * The first and last numbers are circled.
   * Connect the numbers together to win. Consecutive
   * number must touch horizontally, vertically, or
   * diagonally.
   * """
   *
   * This is a port of the Python model hidato_table.py
   * made by Laurent Perron (using AllowedAssignments),
   * based on my (much slower) model hidato.py.
   *
   */
  private static void Solve(int model = 1)
  {
    Solver solver = new Solver("HidatoTable");

    //
    // models, a 0 indicates an open cell which number is not yet known.
    //

    int[,] puzzle = null;
    if (model == 1) {

      // Simple problem

      // Solution 1:
      // 6  7  9
      // 5  2  8
      // 1  4  3
      int[,] puzzle1 = {{6, 0, 9},
                        {0, 2, 8},
                        {1, 0, 0}};
      puzzle = puzzle1;

    } else if (model == 2) {

      int[,] puzzle2 = {{0, 44, 41, 0, 0, 0, 0},
                        {0, 43, 0, 28, 29, 0, 0},
                        {0, 1, 0, 0, 0, 33, 0},
                        {0, 2, 25, 4, 34, 0, 36},
                        {49, 16, 0, 23, 0, 0, 0},
                        {0, 19, 0, 0, 12, 7, 0},
                        {0, 0, 0, 14, 0, 0, 0}};
      puzzle = puzzle2;

    } else if (model == 3) {
      // Problems from the book:
      // Gyora Bededek: "Hidato: 2000 Pure Logic Puzzles"
      // Problem 1 (Practice)
      int[,] puzzle3 = {{0, 0, 20, 0, 0},
                        {0, 0, 0, 16, 18},
                        {22, 0, 15, 0, 0},
                        {23, 0, 1, 14, 11},
                        {0, 25, 0, 0, 12}};
      puzzle = puzzle3;

    } else if (model == 4) {
      // problem 2 (Practice)
      int[,] puzzle4 = {{0, 0, 0, 0, 14},
                        {0, 18, 12, 0, 0},
                        {0, 0, 17, 4, 5},
                        {0, 0, 7, 0, 0},
                        {9, 8, 25, 1, 0}};
      puzzle = puzzle4;

    } else if (model == 5) {
      // problem 3 (Beginner)
      int[,] puzzle5 = {{0, 26, 0, 0, 0, 18},
                        {0, 0, 27, 0, 0, 19},
                        {31, 23, 0, 0, 14, 0},
                        {0, 33, 8, 0, 15, 1},
                        {0, 0, 0, 5, 0, 0},
                        {35, 36, 0, 10, 0, 0}};
      puzzle = puzzle5;

    } else if (model == 6) {
      // Problem 15 (Intermediate)
      int[,] puzzle6 = {{64, 0, 0, 0, 0, 0, 0, 0},
                        {1, 63, 0, 59, 15, 57, 53, 0},
                        {0, 4, 0, 14, 0, 0, 0, 0},
                        {3, 0, 11, 0, 20, 19, 0, 50},
                        {0, 0, 0, 0, 22, 0, 48, 40},
                        {9, 0, 0, 32, 23, 0, 0, 41},
                        {27, 0, 0, 0, 36, 0, 46, 0},
                        {28, 30, 0, 35, 0, 0, 0, 0}};
      puzzle = puzzle6;
    }

    int r = puzzle.GetLength(0);
    int c = puzzle.GetLength(1);

    Console.WriteLine();
    Console.WriteLine("----- Solving problem {0} -----", model);
    Console.WriteLine();

    PrintMatrix(puzzle);

    //
    // Decision variables
    //
    IntVar[] positions = solver.MakeIntVarArray(r*c, 0, r * c - 1, "p");


    //
    // Constraints
    //
    solver.Add(positions.AllDifferent());

    //
    // Fill in the clues
    //
    for(int i = 0; i < r; i++) {
      for(int j = 0; j < c; j++) {
        if (puzzle[i,j] > 0) {
          solver.Add(positions[puzzle[i,j] - 1] == i * c + j);
        }
      }
    }

    // Consecutive numbers much touch each other in the grid.
    // We use an allowed assignment constraint to model it.
    IntTupleSet close_tuples = BuildPairs(r, c);
    for(int k = 1; k < r * c - 1; k++) {
      IntVar[] tmp = new IntVar[] {positions[k], positions[k + 1]};
      solver.Add(tmp.AllowedAssignments(close_tuples));
    }


    //
    // Search
    //
    DecisionBuilder db = solver.MakePhase(positions,
                                          Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
                                          Solver.ASSIGN_MIN_VALUE);

    solver.NewSearch(db);

    int num_solution = 0;
    while (solver.NextSolution()) {
      num_solution++;
      PrintOneSolution(positions, r, c, num_solution);
    }

    Console.WriteLine("\nSolutions: " + solver.Solutions());
    Console.WriteLine("WallTime: " + solver.WallTime() + "ms ");
    Console.WriteLine("Failures: " + solver.Failures());
    Console.WriteLine("Branches: " + solver.Branches());

    solver.EndSearch();

  }
    /**
       *
       * Traffic lights problem.
       *
       * CSPLib problem 16
       * http://www.csplib.org/Problems/prob016
       * """
       * Specification:
       * Consider a four way traffic junction with eight traffic lights. Four of the traffic
       * lights are for the vehicles and can be represented by the variables V1 to V4 with domains
       * {r,ry,g,y} (for red, red-yellow, green and yellow). The other four traffic lights are
       * for the pedestrians and can be represented by the variables P1 to P4 with domains {r,g}.
       *
       * The constraints on these variables can be modelled by quaternary constraints on
       * (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just the tuples
       * {(r,r,g,g), (ry,r,y,r), (g,g,r,r), (y,r,ry,r)}.
       *
       * It would be interesting to consider other types of junction (e.g. five roads
       * intersecting) as well as modelling the evolution over time of the traffic light sequence.
       * ...
       *
       * Results
       * Only 2^2 out of the 2^12 possible assignments are solutions.
       *
       * (V1,P1,V2,P2,V3,P3,V4,P4) =
       * {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r), (y,r,ry,r,y,r,ry,r)}
       * [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1, 2,1)}
       * The problem has relative few constraints, but each is very
       * tight. Local propagation appears to be rather ineffective on this
       * problem.
       *
       * """
       * Note: In this model we use only the constraint
       *  solver.AllowedAssignments().
       *
       *
       * See http://www.hakank.org/or-tools/traffic_lights.py
       *
       */
    private static void Solve()
    {
        Solver solver = new Solver("TrafficLights");

        //
        // data
        //
        int n = 4;

        int r = 0;
        int ry = 1;
        int g = 2;
        int y = 3;

        string[] lights = {"r", "ry", "g", "y"};

        // The allowed combinations
        IntTupleSet allowed = new IntTupleSet(4);
        allowed.InsertAll(new int[,] {{r,r,g,g},
                                  {ry,r,y,r},
                                  {g,g,r,r},
                                  {y,r,ry,r}});
        //
        // Decision variables
        //
        IntVar[] V = solver.MakeIntVarArray(n, 0, n-1, "V");
        IntVar[] P = solver.MakeIntVarArray(n, 0, n-1, "P");

        // for search
        IntVar[] VP = new IntVar[2 * n];
        for(int i = 0; i < n; i++) {
          VP[i] = V[i];
          VP[i+n] = P[i];
        }

        //
        // Constraints
        //
        for(int i = 0; i < n; i++) {
          int j = (1+i) % n;
          IntVar[] tmp = new IntVar[] {V[i],P[i],V[j],P[j]};
          solver.Add(tmp.AllowedAssignments(allowed));
        }

        //
        // Search
        //
        DecisionBuilder db = solver.MakePhase(VP,
                                          Solver.CHOOSE_FIRST_UNBOUND,
                                          Solver.ASSIGN_MIN_VALUE);

        solver.NewSearch(db);

        while (solver.NextSolution()) {
          for(int i = 0; i < n; i++) {
        Console.Write("{0,2} {1,2} ",
                      lights[V[i].Value()],
                      lights[P[i].Value()]);
          }
          Console.WriteLine();
        }

        Console.WriteLine("\nSolutions: {0}", solver.Solutions());
        Console.WriteLine("WallTime: {0}ms", solver.WallTime());
        Console.WriteLine("Failures: {0}", solver.Failures());
        Console.WriteLine("Branches: {0} ", solver.Branches());

        solver.EndSearch();
    }