[{"data":1,"prerenderedAt":431},["ShallowReactive",2],{"dev-\u002Fdeveloper\u002Fguides\u002Fhigher-order-binary":3},{"id":4,"title":5,"body":6,"description":412,"extension":413,"faq":414,"meta":424,"navigation":425,"noindex":426,"path":427,"seo":428,"stem":429,"__hash__":430},"content\u002Fdeveloper\u002Fguides\u002Fhigher-order-binary.md","Higher-order binary optimization (PUBO) in Python",{"type":7,"value":8,"toc":406},"minimark",[9,13,38,43,46,50,74,323,328,332,350,359,363,386,397,402],[10,11,5],"h1",{"id":12},"higher-order-binary-optimization-pubo-in-python",[14,15,16,17,21,22,25,26,29,30,33,34,37],"p",{},"Not every binary problem is quadratic. When the objective multiplies ",[18,19,20],"strong",{},"three or\nmore"," binary variables together, it is a ",[18,23,24],{},"PUBO"," (polynomial) or ",[18,27,28],{},"HUBO","\n(higher-order) problem — the class quantum computers are built for, here solved\nclassically. ",[18,31,32],{},"quicopt"," optimizes the higher-order objective ",[18,35,36],{},"directly",": no\nreduction to a quadratic QUBO, no auxiliary variables.",[39,40,42],"h2",{"id":41},"the-naive-approach","The naive approach",[14,44,45],{},"The common workaround is to reduce the degree — introduce a helper binary for\neach product of variables until everything is quadratic, then feed a QUBO solver.\nThat inflates the variable count and adds penalty terms that reshape the energy\nlandscape. Solve the objective as written instead.",[39,47,49],{"id":48},"a-worked-example-labs","A worked example: LABS",[14,51,52,53,56,57,60,61,64,65,69,70,73],{},"The ",[18,54,55],{},"low-autocorrelation binary sequence (LABS)"," problem asks for a string of\n±1 symbols that looks as little like a shifted copy of itself as possible. Its\nenergy is a ",[18,58,59],{},"degree-four"," polynomial in the binaries — a genuine PUBO. Modeled\nin ",[18,62,63],{},"Pyomo"," (",[66,67,68],"code",{},"pip install \"quicopt[pyomo]\"","), here for ",[66,71,72],{},"N = 7",":",[75,76,82],"pre",{"className":77,"code":78,"filename":79,"language":80,"meta":81,"style":81},"language-python shiki shiki-themes github-dark","import pyomo.environ as pyo\nfrom quicopt import Client\n# LABS (low-autocorrelation binary sequences) for N=7: a degree-4 (PUBO) energy.\nN = 7\nm = pyo.ConcreteModel()\nm.x = pyo.Var(range(N), domain=pyo.Binary)\ns = [1 - 2 * m.x[i] for i in range(N)]\nm.obj = pyo.Objective(\n    expr=sum(sum(s[i] * s[i + k] for i in range(N - k)) ** 2 for k in range(1, N)),\n    sense=pyo.minimize)\nprint(Client(\"https:\u002F\u002Ftry.quicoptapi.pgi.fz-juelich.de\").solve(m).display)\n","labs.py","python","",[66,83,84,103,117,124,137,148,174,215,226,296,307],{"__ignoreMap":81},[85,86,89,93,97,100],"span",{"class":87,"line":88},"line",1,[85,90,92],{"class":91},"snl16","import",[85,94,96],{"class":95},"s95oV"," pyomo.environ ",[85,98,99],{"class":91},"as",[85,101,102],{"class":95}," pyo\n",[85,104,106,109,112,114],{"class":87,"line":105},2,[85,107,108],{"class":91},"from",[85,110,111],{"class":95}," quicopt ",[85,113,92],{"class":91},[85,115,116],{"class":95}," Client\n",[85,118,120],{"class":87,"line":119},3,[85,121,123],{"class":122},"sAwPA","# LABS (low-autocorrelation binary sequences) for N=7: a degree-4 (PUBO) energy.\n",[85,125,127,130,133],{"class":87,"line":126},4,[85,128,129],{"class":95},"N ",[85,131,132],{"class":91},"=",[85,134,136],{"class":135},"sDLfK"," 7\n",[85,138,140,143,145],{"class":87,"line":139},5,[85,141,142],{"class":95},"m ",[85,144,132],{"class":91},[85,146,147],{"class":95}," pyo.ConcreteModel()\n",[85,149,151,154,156,159,162,165,169,171],{"class":87,"line":150},6,[85,152,153],{"class":95},"m.x ",[85,155,132],{"class":91},[85,157,158],{"class":95}," pyo.Var(",[85,160,161],{"class":135},"range",[85,163,164],{"class":95},"(N), ",[85,166,168],{"class":167},"s9osk","domain",[85,170,132],{"class":91},[85,172,173],{"class":95},"pyo.Binary)\n",[85,175,177,180,182,185,188,191,194,197,200,203,206,209,212],{"class":87,"line":176},7,[85,178,179],{"class":95},"s ",[85,181,132],{"class":91},[85,183,184],{"class":95}," [",[85,186,187],{"class":135},"1",[85,189,190],{"class":91}," -",[85,192,193],{"class":135}," 2",[85,195,196],{"class":91}," *",[85,198,199],{"class":95}," m.x[i] ",[85,201,202],{"class":91},"for",[85,204,205],{"class":95}," i ",[85,207,208],{"class":91},"in",[85,210,211],{"class":135}," range",[85,213,214],{"class":95},"(N)]\n",[85,216,218,221,223],{"class":87,"line":217},8,[85,219,220],{"class":95},"m.obj ",[85,222,132],{"class":91},[85,224,225],{"class":95}," pyo.Objective(\n",[85,227,229,232,234,237,240,242,245,248,251,254,257,259,261,263,265,268,271,274,277,279,282,285,287,289,291,293],{"class":87,"line":228},9,[85,230,231],{"class":167},"    expr",[85,233,132],{"class":91},[85,235,236],{"class":135},"sum",[85,238,239],{"class":95},"(",[85,241,236],{"class":135},[85,243,244],{"class":95},"(s[i] ",[85,246,247],{"class":91},"*",[85,249,250],{"class":95}," s[i ",[85,252,253],{"class":91},"+",[85,255,256],{"class":95}," k] ",[85,258,202],{"class":91},[85,260,205],{"class":95},[85,262,208],{"class":91},[85,264,211],{"class":135},[85,266,267],{"class":95},"(N ",[85,269,270],{"class":91},"-",[85,272,273],{"class":95}," k)) ",[85,275,276],{"class":91},"**",[85,278,193],{"class":135},[85,280,281],{"class":91}," for",[85,283,284],{"class":95}," k ",[85,286,208],{"class":91},[85,288,211],{"class":135},[85,290,239],{"class":95},[85,292,187],{"class":135},[85,294,295],{"class":95},", N)),\n",[85,297,299,302,304],{"class":87,"line":298},10,[85,300,301],{"class":167},"    sense",[85,303,132],{"class":91},[85,305,306],{"class":95},"pyo.minimize)\n",[85,308,310,313,316,320],{"class":87,"line":309},11,[85,311,312],{"class":135},"print",[85,314,315],{"class":95},"(Client(",[85,317,319],{"class":318},"sU2Wk","\"https:\u002F\u002Ftry.quicoptapi.pgi.fz-juelich.de\"",[85,321,322],{"class":95},").solve(m).display)\n",[324,325],"term-result",{":rows":326,"cmd":327},"[\"├── shots\",\"│   ├── 1 · Heuristic 1   91    0.0s\",\"│   ├── 2 · Heuristic 2    3   0.01s  ◀ best\",\"│   └── 3 · Heuristic 3    3   3.58s\",\"├── status:     heuristic\",\"├── feasible:   n\u002Fa\",\"├── objective:  3.0\",\"├── x:          x1=1, x2=0, x3=1, x4=1, x5=0, x6=0, …  (7 variables)\",\"└── solve_time: 3.5866 s\"]","$ python labs.py",[39,329,331],{"id":330},"what-you-get","What you get",[14,333,334,335,338,339,342,343,345,346,349],{},"quicopt returns energy ",[66,336,337],{},"3"," — the ",[18,340,341],{},"known optimum"," for LABS at ",[66,344,72],{}," (established\nby exhaustive results in the literature) — straight from the degree-four\nobjective, with no manual reduction to quadratic. Because a PUBO has no\nconstraints, the status is ",[66,347,348],{},"heuristic",", and the few seconds reflect several\nheuristic passes over the non-convex energy — inherent to higher-order search, not\na fixed overhead.",[14,351,352,353,358],{},"The same directness scales: on the public LABS instances quicopt reaches\nbest-known energies orders of magnitude faster than established solvers — see the\n",[354,355,357],"a",{"href":356},"\u002Fbenchmarks\u002Flabs","LABS benchmark",".",[39,360,362],{"id":361},"next","Next",[364,365,366,374,379],"ul",{},[367,368,369,370],"li",{},"The problem class behind this: ",[354,371,373],{"href":372},"\u002Fproblems\u002Fpubo","PUBO \u002F higher-order binary",[367,375,376,377],{},"Measured results at scale: ",[354,378,357],{"href":356},[367,380,381,382],{},"The quadratic cousin: ",[354,383,385],{"href":384},"\u002Fdeveloper\u002Fguides\u002Fmax-cut","Max-cut (QUBO)",[14,387,388,391,392,396],{},[18,389,390],{},"Reference:"," T. Packebusch and S. Mertens, ",[393,394,395],"em",{},"Low autocorrelation binary\nsequences",", Journal of Physics A, 2016.",[398,399],"contact-cta",{"sub":400,"title":401},"Tell us what you're optimizing. We'll help you model it and point you at the right approach.","A higher-order objective — or a different problem?",[403,404,405],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":81,"searchDepth":105,"depth":105,"links":407},[408,409,410,411],{"id":41,"depth":105,"text":42},{"id":48,"depth":105,"text":49},{"id":330,"depth":105,"text":331},{"id":361,"depth":105,"text":362},"Minimize a binary objective of degree three or higher (PUBO\u002FHUBO) in Python — solved directly with quicopt, with no reduction to a quadratic QUBO and no auxiliary variables. Worked on the LABS problem.","md",[415,418,421],{"q":416,"a":417},"What's the difference between QUBO and PUBO?","QUBO objectives are degree two (pairwise). PUBO (polynomial) and HUBO (higher-order) allow degree three and up — products of three or more binary variables. Many real binary objectives are naturally higher-order.",{"q":419,"a":420},"Why not just reduce it to a QUBO?","Reducing a degree-k objective to quadratic adds auxiliary variables and penalty terms that blow up the model and distort the landscape. quicopt optimizes the higher-order objective directly, as written.",{"q":422,"a":423},"Is quicopt free to use?","Yes — pip install quicopt and your first call sets up a free key, no license.",{},true,false,"\u002Fdeveloper\u002Fguides\u002Fhigher-order-binary",{"title":5,"description":412},"developer\u002Fguides\u002Fhigher-order-binary","jQMeTFtBbKHzkVRnLGMwbBJnXueos4m2vIEpU7_P6tM",1784110686352]