Skip to content

【代码贡献】Fix QUBO_QAOA.run crashing with default arguments - #45

Open
mnn31 wants to merge 1 commit into
OriginQ:developfrom
mnn31:fix/qubo-default-layer
Open

【代码贡献】Fix QUBO_QAOA.run crashing with default arguments#45
mnn31 wants to merge 1 commit into
OriginQ:developfrom
mnn31:fix/qubo-default-layer

Conversation

@mnn31

@mnn31 mnn31 commented Aug 10, 2026

Copy link
Copy Markdown

Problem

QUBO.QUBO_QAOA(f).run() raises ValueError: layer number must be a positive integer. Every argument of run is optional, so calling it with nothing but
defaults should work, and instead it fails before any circuit is built.

Root cause

pyqpanda_alg/QUBO/QUBO.py, QUBO_QAOA.run (line 482) declares layer=None
and forwards that value straight into qaoa.QAOA.run:

def run(self, layer=None, optimizer='SLSQP', optimizer_option=None):
    ...
    qaoa_result = qaoa_model.run(layer=layer, ...)

QAOA.run itself declares layer=1 and validates the argument in
_check_layer_and_generate_initial_para (pyqpanda_alg/QAOA/qaoa.py, line 748):

if not isinstance(layer, int) or layer <= 0:
    raise ValueError('layer number must be a positive integer')

None is not an int, so the wrapper's own default is the only value of layer
that QAOA.run rejects outright. The sentinel is never resolved anywhere
between the two calls.

Fix

Give QUBO_QAOA.run the same default its callee already documents and uses,
layer=1, and mark the parameter optional in the docstring. Nothing else in
the method changes, and any explicit layer argument behaves exactly as
before.

Verification

import numpy as np
import sympy as sp
from pyqpanda_alg import QUBO

np.random.seed(42)
x0, x1, x2 = sp.symbols('x0 x1 x2')
f = -0.5*x0*x1 - 0.7*x0*x1 + 0.9*x1*x2 + 1.3*x0 - x1 - 0.5*x2
print(QUBO.QUBO_QAOA(f).run())

before

Traceback (most recent call last):
  File "<string>", line 8, in <module>
  File ".../pyqpanda_alg/QUBO/QUBO.py", line 534, in run
    qaoa_result = qaoa_model.run(layer=layer, loss_type='default', optimize_type='default',
  File ".../pyqpanda_alg/QAOA/qaoa.py", line 972, in run
    initial_para, start_layer = self._check_layer_and_generate_initial_para(layer, initial_para)
  File ".../pyqpanda_alg/QAOA/qaoa.py", line 749, in _check_layer_and_generate_initial_para
    raise ValueError('layer number must be a positive integer')
ValueError: layer number must be a positive integer

after

{'010': 0.28458858391887987, '011': 0.23393109083311936, '001': 0.16721640530088427,
 '110': 0.15803008224084578, '111': 0.11565724592803006, '000': 0.03113904080962043,
 '100': 0.008549759074835428, '101': 0.0008877918937850163}

The highest probability bitstring is 010, the true minimizer of the test
function, so a single layer already returns a usable answer at the default.

The class docstring example, run(layer=5, optimizer='SLSQP', optimizer_option={'options': {'eps': 1e-3}}), still runs and still returns
010 as the most probable bitstring (0.83 under the same seed), unchanged from
develop.

I checked the sibling QUBO_GAS_origin.run for the same class of problem. Its
init_value=None is resolved to self.constant inside the body, and
QUBO_GAS_origin(f).run() completes on defaults, so nothing there needed
touching.

Tests

2 cases added to test/QAlgBase/Test_QUBO_QUBO_QAOA_run.py: run() on pure
defaults returns a normalized 8 entry distribution with real weight on the
correct solution, and the default result is identical to run(layer=1) under
the same seed. Both are seeded and deterministic. Both fail on develop and pass with
this change.

pytest test/QAlgBase/Test_QUBO_QUBO_QAOA_run.py     3 passed
cd test && pytest                                  19 passed

Scope note: this touches QUBO.py only, so it does not overlap #40, which
changes qaoa.py (CVaR/Gibbs loss).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant