How large is your snake? A CP approach

How large is your snake? A CP approach

I am not sure if it's important or not but sometimes you are curious to know how many items you can fit into your knapsack in the airport or how many queens you can put on the chess board. Today I want to fit the largest possible snake on a maze shape board using constraint programming.

The rules are easy to understand:

  • It can only touch the black cells
  • It can touch the Perimeter black cells only once (find the starting cell)
  • It can not touch itself (red shapes)
  • Snake can move 1 cell at a time (horizontally or vertically)
  • The green shape is an allowed path

two separate boards connected to each other via a narrow path

Let's formulate the problem mathematically:

before you begin, please import your required libraries:

import pandas as pd
!pip install ortools
from ortools.sat.python import cp_model
import matplotlib.pyplot as plt # Data visualization
import random
import numpy as np
import time        

Step 0: Understand the problem's requirements

the informations of each cell should be kept in a dictionary to be used later

dic = {}
counter = 0
N = 17
n = N**2

nr, nc = N, N
for r in range(nr):
  for c in range(nc):
    counter+=1
    dic[counter] = (c,r,1)
    if c==(N-1)/2 and r!=(N-1)/2:
      dic[counter] = (c,r,0)        

Step 1: Code the requirements (Variables)

obviously we need a CP model

    model = cp_model.CpModel()        

create the nodes and variables

nodes = [i for i in dic.keys() if dic[i][2]==1]
x={(i,j):model.NewBoolVar(f"flow_{i}_{j}") for i in nodes for j in nodes if distance(i,j,dic)== 1}
assign = {i: model.NewBoolVar(f"assign_{i}") for i in nodes}
endpoint = {i: model.NewBoolVar(f"end_{i}") for i in nodes if dic[i][1] not in [0,N-1] and dic[i][0] not in [0,N-1]}
startpoint = {i: model.NewBoolVar(f"st_{i}") for i in nodes if dic[i][1] in [0,N-1] or dic[i][0] in [0,N-1]}
linked= {(i,j): model.NewBoolVar(f"linked_{i}_{j}") for i in startpoint for j in endpoint}        

Xij is the boolean variable indicating the move from i to j

assign_i is the boolean variable indicating the cell i is in the path (part of snake's body)

startpoint_i is the boolean variable indicating the cell i is starting point of the path

endpoint_i is the boolean variable indicating the cell i is starting point of the path

Step 2: Code the requirements (Constraints)

Create a close tour of selected nodes (if a node is not selected then a tour containing itself will be created), I use the AddCircuit constraint for this purpose.

    arcs= [ (i,j,v) for (i,j),v in x.items()] + [(i,i,assign[i].Not()) for i in nodes] + [(i,j,v) for (i,j),v in linked.items()]
    model.AddCircuit(arcs)        

Only one cell on the boundary can be selected as the starting point

    boundry_nodes_all = [v for i,v in assign.items() if i in startpoint]
    model.AddExactlyOne(boundry_nodes_all)        

Only one cell on the boundary can be touched (which should be the same as starting point)

boundry_nodes_all = [v for i,v in assign.items() if i in startpoint]
model.AddExactlyOne(boundry_nodes_all)        

Only one cell on the non boundary cells can be selected as the end point

    nonboundry_nodes = [v for v in endpoint.values()]
    model.AddExactlyOne(nonboundry_nodes)        

The start and end point should be connected to each other

for (i,j),v in linked.items():
      model.Add(v <= assign[i])
      model.Add(v <= assign[j])
      model.Add(v >= startpoint[i] + endpoint[j] - 1)
      model.Add(v <= startpoint[i])
      model.Add(v <= endpoint[j])        

Non-touching constraints

If two cells are neighbours but there is no link between them then they can't be both on the path !

    for (i,j),v in x.items():
      if (j,i) in x and i>j:
        model.Add(assign[i]+assign[j]<=  1+ v + x[j,i] )        

The objective function is defined as the total visited cells (to be maximized)

    expressions_of = [v for v in assign.values()]
    model.Maximize(cp_model.LinearExpr.Sum(expressions_of))        

Results

Largest snake path on a 17*17 board

What if there are extra paths between the two sections ?

Conclusion

  • There is no easy/difficult concept in math. The things become easy to understand once you learn them.
  • Largest path is more interesting than shortest path (LP>SP)
  • CP is a powerful tool in supply chain management
  • Follow the newsletter to learn more (https://lnkd.in/eEzkkk_M ).
  • The git repository is in comment section


Manfred Weis

Dipl.Math., Data Scientist at Garmin Würzburg GmbH, Germany

2 周

I finally managed to identify the underlying general mathematical problem (for a snake biting its tail) and RobPratt https://mathoverflow.net/users/141766/robpratt unearthed a paper https://mathoverflow.net/a/482069/31310 that establishes the problem's NP completeness and inapproximability

Manfred Weis

Dipl.Math., Data Scientist at Garmin Würzburg GmbH, Germany

2 周

A very intriguing problem, but after taking a sharper look and exploiting symmetry etc, I came up with the following solution that appears to only "waste" two cells (depicted in red)

  • 该图片无替代文字
Holger Prause

Software Developer

2 周

That is a sensitive question

Prabhakar Dongre

Prof & Head , Dept of Biophysics, University of Mumbai

3 周

Thank you very much?

要查看或添加评论,请登录

Alireza Soroudi, PhD的更多文章

  • Gerrymandering using Constraint Programming

    Gerrymandering using Constraint Programming

    As the U.S.

    11 条评论
  • Last Tango with Math (CP)

    Last Tango with Math (CP)

    The Last Tango is no longer in Paris and it seems to be on Linkedin. After coming across a logic puzzle on LinkedIn, I…

    4 条评论
  • From Solving to Designing Queen Problem using CP

    From Solving to Designing Queen Problem using CP

    In the last thrilling episode of this newsletter, we cracked the LinkedIn Queen Problem! ?? But then it hit me—how does…

    22 条评论
  • How to Cut your Board using CP?

    How to Cut your Board using CP?

    Cutting the shapes has always fascinated mathematicians. In this episode of Optimization in Open Source, we focus on…

    13 条评论
  • Queens game using CP

    Queens game using CP

    This is an exciting installment of our newsletter! I recently came across a fascinating challenge on LinkedIn that…

    20 条评论
  • How Machine Learning can Help Power System Operators ?

    How Machine Learning can Help Power System Operators ?

    Machine Learning has become a buzzword in recent times. Recruiters often label positions as "data scientist" roles…

    10 条评论
  • Optimization in Action: The Train of a Single Color

    Optimization in Action: The Train of a Single Color

    Let's explain the routing wavelength assignment (RWA) problem. The general objective of the RWA problem is to maximize…

    6 条评论
  • Optimal Data-Driven Strategies for Efficient Demining Operations

    Optimal Data-Driven Strategies for Efficient Demining Operations

    Demining involves removing landmines to ensure safety. In military contexts, the goal is to quickly clear paths using…

    6 条评论
  • Solving Large Scale TSP using OR

    Solving Large Scale TSP using OR

    The Traveling Salesman Problem (TSP) might seem tedious initially, but tackling it on a large scale is like embarking…

    12 条评论
  • Optimal Marriage Using OR

    Optimal Marriage Using OR

    While an analytical mind might employ optimization algorithms to find the perfect match, true love often dances to its…

    37 条评论

社区洞察

其他会员也浏览了