コンテンツにスキップ

SDK 共通QUBO問題生成ガイド

更新日: 2026-08-28

目的

SDK利用者が、道路巡回、配送、低空UAV回廊、高高度空域、任意の割当問題を、量子アニーリング・量子最適化・古典アニーリングで共有するQUBO形式へ変換するためのガイドです。

共通APIは evospikenet.optimization にあります。生成したQUBOは既存の dwaveopenjijfixstars_amplifyqiskit、または古典フォールバックへ渡せます。

インストール

基本機能はCoreの標準依存だけで使えます。

cd EvoSpikeNet-Core
pip install -e .

OpenStreetMapから実道路網を取得する場合だけ、OSMnxを任意依存として導入します。

pip install -e '.[road]'

道路スナップショットを読み込む通常運用・自動テストでは、OSMnxやネットワーク接続は不要です。

最小例: 道路リンクからQUBOを作る

import networkx as nx
from evospikenet.optimization import RoadLocation, RoadNetworkBuilder, QuboProblemBuilder

graph = nx.MultiDiGraph()
graph.add_edge("hub", "depot", length=1200.0)
graph.add_edge("depot", "hub", length=1500.0)  # 一方通行を含め往復は別コスト

locations = [
    RoadLocation("hub", 35.5492, 139.7898),
    RoadLocation("depot", 35.5312, 139.7029),
]
snapshot = RoadNetworkBuilder().from_graph(
    graph,
    locations,
    {"hub": "hub", "depot": "depot"},
)
road_problem = snapshot.to_optimization_problem("route-replan")
solver_input = QuboProblemBuilder().build(road_problem).as_problem_dict()

solver_input は次のキーを持ちます。

  • name: 問題名
  • labels: QUBO変数と道路リンクの対応
  • qubo: 対称QUBO行列
  • metadata: 生成元、時刻、有効な動的制約、禁止候補

実道路網の取得

from evospikenet.optimization import RoadLocation, RoadNetworkBuilder

snapshot = RoadNetworkBuilder().from_osm(
    [
        RoadLocation("haneda", 35.5492, 139.7898, "Haneda Hub"),
        RoadLocation("kawasaki", 35.5312, 139.7029, "Kawasaki Depot"),
    ],
    north=35.65,
    south=35.50,
    east=139.82,
    west=139.65,
)
  • network_type="drive" のOSM道路グラフを利用します。
  • 道路グラフは無向化しません。一方通行により \(d(i,j) \ne d(j,i)\) になるためです。
  • 到達不能な拠点対は候補リンクとして生成されません。
  • 実行ごとのOSMダウンロードを避けるため、本番では道路グラフまたは RoadNetworkSnapshot をバージョン・取得日時付きでキャッシュしてください。

突発的禁止条件

事故、工事、災害、通行止め、飛行禁止、気象、機体故障は DynamicConstraint として投入します。

from datetime import datetime, timedelta, timezone
from evospikenet.optimization import DynamicConstraint

now = datetime.now(timezone.utc)
closure = DynamicConstraint(
    constraint_id="closure-20260828-01",
    constraint_type="road_closure",
    severity="hard",
    candidate_ids=frozenset({"road:haneda:kawasaki"}),
    active_from=now,
    active_until=now + timedelta(minutes=30),
    penalty=10_000.0,
)
road_problem = snapshot.to_optimization_problem(
    "route-replan",
    dynamic_constraints=[closure],
)
  • hard: 禁止対象に大きな罰則を追加し、解の適用前にも拒否すべき条件です。
  • soft: 渋滞、強風、通信品質低下などを追加コストにします。
  • candidate_ids の代わりに、attributes={"road_class": "motorway"} のような候補属性の照合も使えます。
  • 有効時間外の制約はQUBOへ反映されません。

ソルバーへ渡す

from evospikenet.optimizer import get_optimizer

solver_input = QuboProblemBuilder().build(road_problem).as_problem_dict()
solutions = get_optimizer("dwave").solve(
    solver_input,
    options={"sampler": "QPU", "num_reads": 100},
)

QPU利用には各バックエンドのSDKと認証情報が必要です。実機が利用できない場合は、明示的に選んだシミュレータまたは古典ソルバーで検証してください。量子ソルバーの解は、道路規制、空域規制、衝突判定、Safety Barrierによる最終検証を通すまで実運用へ適用してはいけません。

SDKサンプル

road_qubo_generation_demo.py は、ネットワークアクセスを使わずに以下を実演します。

  1. 有向 MultiDiGraph から道路リンクを生成
  2. 一時道路閉鎖をハード制約として追加
  3. QUBOと変数ラベルを生成
  4. 既存量子・アニーリングバックエンドに渡せる入力を表示
cd EvoSpikeNet-Core
python3.10 examples/sdk/programs/road_qubo_generation_demo.py

詳細な内部設計と受け入れ条件は 量子アニーリング前処理・共通問題生成仕様 を参照してください。