{"id":30195341,"url":"https://github.com/dpbm/qnqueens","last_synced_at":"2025-10-05T18:59:03.207Z","repository":{"id":299875776,"uuid":"1003836396","full_name":"Dpbm/qnqueens","owner":"Dpbm","description":"Solving NQueens using Quantum computing","archived":false,"fork":false,"pushed_at":"2025-07-24T17:53:55.000Z","size":14371,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-25T15:18:30.967Z","etag":null,"topics":["circuit","dimod","dwave","dwave-ocean-sdk","ibm","nqueens","optimization-problem","qaoa","qiskit","quantum-algorithm","quanutm-computing","qubo"],"latest_commit_sha":null,"homepage":"https://dpbm.github.io/qnqueens/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dpbm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-17T18:35:12.000Z","updated_at":"2025-07-24T17:53:59.000Z","dependencies_parsed_at":"2025-06-18T19:27:41.247Z","dependency_job_id":"06d14ab0-f32e-4d53-a285-440e39256dcd","html_url":"https://github.com/Dpbm/qnqueens","commit_stats":null,"previous_names":["dpbm/qnqueens"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Dpbm/qnqueens","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqnqueens","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqnqueens/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqnqueens/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqnqueens/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dpbm","download_url":"https://codeload.github.com/Dpbm/qnqueens/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dpbm%2Fqnqueens/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278503204,"owners_count":25997718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["circuit","dimod","dwave","dwave-ocean-sdk","ibm","nqueens","optimization-problem","qaoa","qiskit","quantum-algorithm","quanutm-computing","qubo"],"created_at":"2025-08-13T04:11:25.185Z","updated_at":"2025-10-05T18:59:03.184Z","avatar_url":"https://github.com/Dpbm.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quantum NQueens\n\n## Solving NQueens using quantum computing \n\nAfter becoming obsessed with this problem as I implemented a solution [here](https://github.com/Dpbm/n-rainhas) and [here](https://github.com/Dpbm/faculdade/tree/master/quarto-ano/python/my-nqueens) for my AI class at college. I decided to put an end in this story and implement the final version using quantum computing.\n\nAt first, I implemented 2 versions one using `Qubo` and the other `QAOA`. Even thought the `QAOA` approach was kinda trick to get good results, I put a lot of effort on that. \n\nDuring the implementation of this code, I came across [this paper](https://arxiv.org/pdf/2312.16312), proposing an specific quantum circuit for solving NQueens. I really liked the idea so I decided to create another version by my own.\n\n## Using the code\n\nTo ease the process of setting up this code, you can use it at:\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Dpbm/qnqueens/HEAD)\n\n[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Dpbm/qnqueens/)\n\nBut you can also run it on your local machine. To do that, first install [uv](https://github.com/astral-sh/uv) and then run:\n\n```bash\nuv sync\njupyter lab\n```\n\n## Versions\n\n### QUBO\n\nThe qubo version, [which you can find here](./qubo.ipynb), was the simplest one to implement.\n\nTo do that, I employed the Dwave's Ocean SDK to generate and sample the Qubo formula.\n\nThe formula itself is the following:\n\n$$\\sum_{ij}\\sum_{a}x_{ij}x_{a} + P(\\sum_{ij}x_{ij} - n)^2 = 0$$\n\nBeing $ij$ a combination of $row,column$, $a$ a combination of $ij$ for each possible attack at $ij$, $P$ the Lagrange term for penalty and $n$ the board side.\n\nThis equation, express that, the combination of each attack should be zero and in total only $n$ queens must appear ($n$ ones).\n\nAfter executing this using two different samplers we got this:\n\n![Solution 1 Exact Solver](./Qubo%20Solution%201%20Exact%20Solver.png)\n![Solution 2 Exact Solver](./Qubo%20Solution%202%20Exact%20Solver.png)\n![Solution 1 Tabu Search](./Qubo%20Solution%201%20Tabu%20Search.png)\n\n### QAOA\n\nBased on the Qubo formulation, we can easily map a binary problem into an ising problem. To do that, we need to manipulate every ising variable to behave as the binary version.\n\n$$x_{i} = {(1-z_{i})\\over{2}}$$\n\nSo, our qubo becomes:\n\n\n$$\\sum_{ij}\\sum_{a}{(1-z_{ij})\\over{2}}{(1-z_{a})\\over{2}} + P(\\sum_{ij}{(1-z_{ij})\\over{2}} - n)^2 = 0$$\n\nWe could rewrite this as:\n\n$$\\sum_{ij}\\sum_{a}{1\\over{4}}{(1-z_{ij})}{(1-z_{a})} + P(\\sum_{ij}{1\\over{2}}{(1-z_{ij})} - n)^2 = 0$$\n\n$${1\\over{4}}\\sum_{ij}\\sum_{a}{(1-z_{ij})}{(1-z_{a})} + P({1\\over{2}}\\sum_{ij}{(1-z_{ij})} - n)^2 = 0$$\n\n$${1\\over{4}}\\sum_{ij}\\sum_{a}{(1 - z_{a} - z_{ij} + z_{ij}z_{a} )} + P({1\\over{2}}{|ij|} - n -\\sum_{ij}{z_{ij}})^2 = 0$$\n\n$${1\\over{4}}{|ij||a|}\\sum_{ij}\\sum_{a}{(- z_{a} - z_{ij} + z_{ij}z_{a} )} + P(({1\\over{2}}{|ij|} - n) -\\sum_{ij}{z_{ij}})^2 = 0$$\n\nBeing $|ij|$ and $|a|$ the amount of positions and attacks respectively.\n\nAfter that, we can Embed this as a Hamiltonian inside a QAOA Ansatz, and them minimize its cost using a classical optimizer (like COBYLA).\n\n![cost history](./cost-history-qaoa-old.png)\n![resulting board](./solution-board-qaoa-0111011000000011-no-retry.png)\n\nOnce it couldn't find the solution, I tried a different approach, given the algorithm $10$ tries to explore more parameters.\n\n![cost history](./cost-history-qaoa.png)\n\nHowever, it was still stuck in local optima. If you want to help me improve that, feel free to open an issue/PR.\n\n### Circuit based\n\nAs inspired by [arXiv:2312.16312](https://arxiv.org/abs/2312.16312) I decided to create a circuit myself. At first glance, I did a Grover's algorithm setup to solve this problem. However, during the process, I figured out that using it might be a big overhead, and doing the simple state setup and them checking is better.\n\nIn my setup, we have $2N$ qubits, being $N$ the total os cells in the board. The first register (first N qubits) consists of the state based on $W$ states tailored to have both unique rows and columns. After that, we apply a $MCX$ gates checking if each diagonal attack for each position and saving its values to its respective qubit on the second register.\n\n\n#### Especial W state\n\nTo create this especial $W$ state, we first apply the default $n$ $W$ state, being $n$ the side of the board. Then, for each new block, we check the previous ones, letting empty spaces within the new state. Doing that, at each new block, we reduce the size of the $W$ state until it becomes $1$.\n\nWhen we reach the $1$ size, we can do create the states ourselves using $MCX$ gates applying it to the last first register block.\n\n#### Complexity\n\nEven thought the amount of qubits grows linearly as the amount of cells grows $O(N)$, it still very costly to run, since the smallest board ($4x4$) raises a circuit $32$ qubits long.\n\n![state circuit for side=4](./n=4-board-state.png)\n![check circuit for side=4](./n=4-board-check.png)\n\nDue to that, it wasn't possible to test on my humble intel i5. So for Testing the $4x4$ board, I used the `ibm_torino` backend. However, this amount of qubits was enough to raise a tone of errors and by the end it wasn't possible to reliably get the final answer.\n\n![side=4 board state reg](./n=4-board-state-reg-ibm_torino.png)\n![side=4 board check reg](./n=4-board-check-reg-ibm_torino.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpbm%2Fqnqueens","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdpbm%2Fqnqueens","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpbm%2Fqnqueens/lists"}