Communitygithub.com

Compétence Kaiwu de modélisation et résolution

Utilise le SDK QBoson Kaiwu (Enterprise/Community) pour modéliser des problèmes d'optimisation combinatoire en QUBO/Ising, gérer les contraintes, la précision, la compatibilité des versions et les résultats de résolution.

Qu'est-ce que Compétence Kaiwu de modélisation et résolution ?

Cette compétence spécialisée permet de modéliser et résoudre des problèmes d'optimisation combinatoire (localisation, ordonnancement, routage, couverture, règles booléennes, Max-Cut, optimisation mixte discret-continu) en utilisant le SDK Kaiwu d'QBoson dans les versions Enterprise et Community. Elle guide l'utilisateur à travers les étapes clés : identification de la version cible, installation appropriée du package (`kaiwu` pour Enterprise, `kaiwu-community` pour Community), conversion correcte des objectifs métier en formulation QUBO/Ising avec gestion des contraintes (égalité, inégalité, implications logiques) via des coefficients de pénalité bien dimensionnés. La compétence détaille l'API à utiliser selon la version (1.3.x vs 1.4.0), fournit des exemples de code exécutables avec `SimulatedAnnealingOptimizer`, explique le décodage des candidats, la vérification des contraintes métier et la sélection de la meilleure solution réalisable. Elle insiste sur des pratiques robustes : éviter les coefficients de pénalité excessifs, adapter les paramètres du solveur à la taille du problème et au budget temps, respecter les contraintes utilisateur (seed, limite de temps), et ne jamais substituer les résultats du SDK par des solutions externes ou du code en dur. La compétence s'applique aussi bien à l'optimisation locale qu'aux appels sur machine réelle (cloud CIM), et inclut des directives pour la gestion de la précision avec `PrecisionReducer`. La compétence de modélisation énergétique PyTorch (RBM/BM/DBN, QVAE, QDiffusion) est traitée séparément par la compétence `kpp-coding-skill`.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/qboson/kaiwu-coding-skill/tree/main

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Modélisation et résolution avec Kaiwu

Confirmez d'abord l'interpréteur cible, la distribution et la version ; si le problème est donné et la licence déjà installée, utilisez-la directement sans réinstallation ni demande. Si ce n'est pas installé, utilisez python -m pip install kaiwu (Enterprise) ou python -m pip install kaiwu-community (modélisation uniquement). Le nom d'importation est kaiwu dans les deux cas. La résolution locale Enterprise nécessite une licence existante ; le cloud CIM n'est utilisé que si l'utilisateur le demande et fournit les identifiants. Lors de l'appel à une machine réelle via cette compétence, task_name doit commencer par kaiwu_skill, par exemple kaiwu_skill_tsp.

Garantir d'abord l'équivalence du modèle

Distinguer l'objectif métier original, le domaine réalisable et l'énergie de résolution. Utilisez de courtes formules pour expliquer les variables, les objectifs et toutes les contraintes ; le code doit exprimer le même modèle. Si l'objectif original est une maximisation, prenez le négatif pour construire le QUBO, mais rapportez la valeur selon l'objectif original. Pour l'identification de la famille de problèmes et la modélisation des variantes, consultez le catalogue de problèmes selon les besoins.

Exigence originaleEncodage quadratique ; P = coefficient de pénalité dur positif
Exactement un / égalitéP * (sum(x) - c)**2
Au plus unP * sum(x[i]*x[j] pour i<j)
Choisir a implique choisir b / choisir ensemble ou pasP*a*(1-b) / P*(a-b)**2
OU de deux littéraux : au moins un vraiP * (1-a)*(1-b) ; pas (a+b-1)**2
OU mou pondéréPoids multiplié par l'indicateur de violation ; pour un seul littéral 1-a, pour deux littéraux (1-a)*(1-b)
Limite supérieure de ressource entière load <= CP*(load+s-C)**2, relaxation entière non négative s couvrant tous les 0..C
Au moins un (plusieurs variables)P*(sum(x)-1-s)**2, s couvrant 0..n-1

La valeur de vérité d'un littéral positif est x, et d'un littéral négatif est 1-x. L'indicateur de violation d'un OU n'est 1 que lorsque tous les littéraux sont faux ; ne pas utiliser 1-sum(literals) (peut être négatif), ni sum(1-literals)**2 (change les préférences). Le produit de trois littéraux ou plus est un terme d'ordre élevé, pas directement un modèle quadratique ; nécessite des variables auxiliaires appropriées et une réduction équivalente.

Les variables de relaxation peuvent être directement déclarées comme Integer('slack', min_value=0, max_value=C), ou encodées avec des poids binaires. Par exemple, pour une limite supérieure C=5, les poids [1,2,2] peuvent représenter exactement 0..5 ; si C=0, ne créez pas de bit de relaxation. Généralement, pour C>0, prenez k=C.bit_length()-1, poids [2**j for j in range(k)] + [C-(2**k-1)]. La capacité permet un reste ; ne pas utiliser (load-C)**2 comme contrainte de limite supérieure.

Le coefficient de pénalité doit couvrir la plage d'amélioration possible de l'objectif original : si la valeur non nulle minimale du terme de pénalité dur est 1, prenez P supérieur à la différence entre les bornes supérieure et inférieure de l'objectif original. Pour les règles molles pondérées, prenez P supérieur à la somme des poids ; pour les coûts d'affectation non négatifs, prenez P supérieur à la somme des bornes supérieures de chaque coût. Un coefficient trop élevé élargit la plage dynamique, augmentant la difficulté d'échantillonnage ; la justification doit être écrite, et l'on ne peut pas réparer un modèle erroné en augmentant indéfiniment P. Lorsqu'il existe une borne de réparation locale prouvable, utilisez la borne la plus stricte. Par exemple, pour une couverture de sommets pondérée non négative, l'objectif est sum(w[i]*x[i]), le terme de pénalité est P*sum((1-x[u])*(1-x[v])) : prenez P>max(w). Si les poids sont des entiers non négatifs, prenez par défaut P=max(w)+1, sans augmenter le coefficient de pénalité par intuition. Car chaque arête non couverte peut ajouter une extrémité, l'objectif augmente d'au plus max(w), le terme de pénalité diminue d'au moins P, et aucune nouvelle violation n'est créée. Cela ne s'applique qu'à ce type de contrainte de couverture monotone, et ne peut pas être étendu aux contraintes de capacité, d'exclusion mutuelle ou d'égalité ; vous devez expliquer que la réparation ne viole pas les autres contraintes.

Enterprise 1.4.0 : utilisez directement ce flux API

Voici un exemple exécutable parmi trois options, montrant uniquement l'appel SDK et le décodage ; remplacez l'objectif, les pénalités et la validation métier originale pour traiter le problème réel. N'inventez pas d'interfaces comme kaiwu.seed, QuboModel.add_variable, vartype ou iterations_per_temperature.

import numpy as np
from kaiwu.core import (ndarray, Binary, QuboModel, PenaltyMethodConstraint,
                        qubo_matrix_to_ising_matrix, qubo_model_to_ising_model,
                        get_sol_dict, get_val)
from kaiwu.classical import SimulatedAnnealingOptimizer

x = ndarray(3, 'x', Binary)
original = 3*x[0] + 2*x[1] + 4*x[2]
model = QuboModel()
model.set_objective(original + 10*(x.sum()-1)**2)
model.set_constraint_handler(PenaltyMethodConstraint)  # passez la classe, pas l'instance
q = model.get_matrix()
h, offset = qubo_matrix_to_ising_matrix(q)  # offset est une constante, pas un dictionnaire de variables
variables = qubo_model_to_ising_model(model).get_variables()
solver = SimulatedAnnealingOptimizer(
    initial_temperature=100, alpha=0.99, cutoff_temperature=0.001,
    iterations_per_t=100, size_limit=32, rand_seed=20261001)
pool = np.asarray(solver.solve(h))
valid = []
for row in pool:
    sol = get_sol_dict(row[:-1]*row[-1], variables)
    bits = [int(round(get_val(x[i], sol))) for i in range(3)]
    if sum(bits) == 1:  # pour le problème réel, recalculez ici toutes les contraintes métier originales
        valid.append((int(round(get_val(original, sol))), bits))
if not valid:
    raise RuntimeError('Aucune solution réalisable dans les candidats SDK')
cost, decision = min(valid)
print({'bits': decision, 'objective': cost, 'feasible': True})

Paramètres SA vérifiés : initial_temperature, alpha, cutoff_temperature, iterations_per_t, size_limit, flag_evolution_history, verbose, rand_seed, process_num. Ne transmettez pas seed, time_limit, num_reads. Le contrôle du temps d'exécution doit être effectué en gérant les lots en externe, ne créez pas de paramètres de construction fictifs. Les bits de l'exemple sont des décisions binaires, pas identiques au champ solution de chaque tâche. Les champs de sortie et les conventions de numérotation suivent la tâche en cours ; utilisez json.dumps lorsque du JSON est demandé, ne recopiez pas le format d'impression de l'exemple. Pour les problèmes de taille moyenne avec contraintes, augmentez iterations_per_t, ou utilisez plusieurs lots avec différents rand_seed parmi les candidats SDK ; enregistrez également le temps réel et respectez la limite de temps de l'utilisateur. Les paramètres de l'exemple sont un point de départ, ils ne garantissent pas l'optimalité pour chaque problème.

Si le coefficient de pénalité rend l'amplitude de la matrice d'Ising beaucoup plus grande que la température de l'exemple, la température initiale de 100 peut ne pas suffire pour explorer. Lorsque les paramètres de la tâche ne sont pas fixés, vous pouvez d'abord prendre initial_temperature=max(100, 2*np.max(np.abs(h))) ; pour les problèmes locaux avec contraintes d'une dizaine de variables, utilisez iterations_per_t=200, size_limit=128 comme point de départ, puis jugez en fonction de la qualité réelle des candidats et de la limite de temps. Ne recopiez pas simplement la température et la taille du pool du petit exemple en prétendant garantir l'optimalité.

Pour les livraisons d'optimisation avec plus d'une centaine de variables et sans paramètres d'échantillonnage fixés dans l'énoncé, ne terminez pas en exécutant uniquement la configuration d'échantillonnage faible du petit exemple. Par exemple, pour un objectif de qualité et un budget d'exécution d'environ 40 secondes, pour 128 à 512 variables avec un couplage creux (proportion de non-nuls inférieure à 10%), le lot par défaut est iterations_per_t=(200,800,2400), size_limit=128. Les autres paramètres restent cohérents, utilisez toujours la graine spécifiée, et la matrice originale n'est compilée qu'une seule fois. Pour plus de variables, une matrice dense ou un budget plus court, commencez par des lots plus petits comme (200,400,800). Après chaque lot, estimez le coût en fonction du temps réel et du rapport avec le nombre d'itérations du lot suivant, en laissant au moins 20% de marge et 2 secondes pour le décodage et la sortie. Si le lot suivant peut être terminé dans le temps restant, continuez avec le lot par défaut ; la décision de continuer dépend toujours de la qualité des candidats et de la limite de temps comme ci-dessous ; si un dépassement de temps est prévu, retournez immédiatement le meilleur candidat réalisable trouvé, sans dépasser le temps pour terminer un nombre fixe de lots. L'ensemble du programme ne conserve qu'une seule échéance unifiée. Dans la limite de temps d'exécution de l'utilisateur, recalculez l'objectif métier original pour tous les candidats réellement retournés, et conservez le candidat réalisable avec le coût le plus bas ; cela fait partie de la stratégie de résolution avec budget dans le programme. Ne prenez pas le premier candidat réalisable comme meilleur résultat. Les préférences molles ne sont pas des contraintes dures : en l'absence de contrainte dure, n'introduisez pas artificiellement de grands coefficients de pénalité, et n'ajoutez pas de contraintes d'équilibrage non demandées dans l'énoncé.

Ajustez les paramètres par défaut en fonction de la taille et de la complexité. Les valeurs ci-dessus sont des points de départ empiriques, pas une recette fixe pour tous les problèmes. Considérez d'abord le nombre de variables, le nombre de couplages non nuls, l'étendue des coefficients et la force des contraintes dures, puis organisez la taille d'un lot unique en fonction de la limite de temps d'exécution. Les matrices denses ou un grand nombre de variables auxiliaires augmentent le coût de chaque résolution ; commencez par un petit lot, en réservant du temps pour la compilation, le décodage et la sortie. Augmenter les itérations, ralentir le refroidissement ou élargir le pool de solutions ne garantit pas de meilleurs résultats métier ; conservez cumulativement le meilleur candidat SDK réalisable trouvé jusqu'à présent, comparez la proportion de candidats réalisables, le coût métier original et le temps réel avant de décider de continuer, sans écraser les meilleurs anciens candidats. Corrigez d'abord la modélisation erronée ou les coefficients de pénalité trop grands, puis ajustez les paramètres ; enregistrez les paramètres utilisés et les conditions d'arrêt, ne prétendez pas garantir l'optimalité.

Respectez d'abord les paramètres expérimentaux spécifiés dans la tâche. Si l'énoncé fixe une graine aléatoire, utilisez explicitement la même rand_seed spécifiée à chaque création d'un solveur, sans incrémenter, créer une liste de graines ou utiliser le temps pour générer la graine ; les suggestions de plusieurs graines ci-dessus ne s'appliquent que lorsque la tâche le permet. Avec une graine fixe, ajustez la température, le nombre d'itérations, etc., uniquement si l'énoncé le permet ; enregistrez la configuration réelle.

solve retourne un pool de spins non trié par énergie, la dernière colonne étant le spin de référence ; parcourez chaque ligne, multipliez d'abord par le spin de référence pour normaliser, puis décodez en utilisant le dictionnaire de variables du modèle d'Ising. Utilisez get_val pour accéder aux variables, ne devinez pas les chaînes de clés internes. Seules les décisions décodées à partir de candidats réels et vérifiées par la validation du problème original peuvent être sorties ; n'utilisez pas d'énumération exhaustive, de réponses codées en dur ou d'un solveur tiers pour remplacer le SDK.

Les termes de pénalité que vous avez ajoutés à l'objectif ne sont pas équivalents à des contraintes enregistrées : sans add_constraint, le fait que verify_constraint retourne 0 ne prouve pas que le problème original est réalisable. Que les contraintes soient enregistrées ou non, recalculez toutes les contraintes métier à partir de la décision. Si vous appelez verify_constraint, décompressez d'abord unsatisfied, details = model.verify_constraint(sol). Imprimez séparément le coût métier et l'énergie QUBO/Ising, ne prenez pas les pénalités, le décalage constant ou le signe négatif de maximisation comme indicateurs métier. Lors de la transmission des coefficients, sauvegardez l'ordre des variables, la constante, les termes linéaires, les termes quadratiques et la correspondance avec les variables auxiliaires ; P est effectivement multiplié dans les coefficients, et les contributions de chaque terme sont additionnées. L'ordre de la matrice SDK n'est pas nécessairement égal à l'ordre de création des tableaux ; le décalage du convertisseur ne contient pas les constantes métier retirées lors de la compilation de l'expression, les deux sont sauvegardés séparément. Le coût pour le même état est w*(1-x[i]-x[j]+2*x[i]*x[j]), le coût pour un état différent est w*(x[i]+x[j]-2*x[i]*x[j]), vérifiez la direction avec 00, 01, 10, 11, pour éviter de confondre le bruit de co-canal avec l'objectif Max-Cut.

Le rapport des règles molles pondérées suit l'énoncé : si "minimiser le coût de violation" est demandé, rapportez sum(poids for rule in soft if not satisfied(rule)), et choisissez le candidat avec la plus petite valeur légale. "Somme des poids satisfaits" et "coût de violation" s'additionnent pour donner la somme totale des poids mous, les deux directions d'optimisation sont opposées, ne mélangez pas les noms de champs objective. Avant la sortie, recalculez l'objectif original en fonction des bits finaux ; même si la décision est la même, rapporter la valeur de la direction opposée constitue une erreur de livraison.

Versions et documentation thématique : ne lisez que les parties pertinentes

APIEnterprise 1.3.1Enterprise 1.4.0
QuboModelkaiwu.qubokaiwu.core
Deux convertisseurs QUBO/Isingkaiwu.conversionkaiwu.core
ndarray/Binary/Integer/quicksum/get_val/get_sol_dict/PenaltyMethodConstraintkaiwu.corekaiwu.core
Accès aux éléments de tableauget_val par élément ou get_array_valget_val supporte les tableaux ; pas de get_array_val
PrecisionReducerkaiwu.cimkaiwu.preprocess
Solveur de méthode de pénalitékaiwu.solver.PenaltyMethodSolverkaiwu.hybrid.PenaltyMethodOptimizer

Quand la version est connue, importez directement le module correspondant. En cas d'exigence explicite de prise en charge multi-version ou d'incertitude, ne faites des branches de compatibilité que pour les importations réellement migrées. quicksum transmet une liste entre les versions ; ndarray((n,m), 'x', Binary) utilise des arguments positionnels. Community ne peut pas supposer la présence d'un solveur classique local.

  • 1.3.x ou signature plus complète : API Enterprise, Aperçu API.
  • Exemple historique TSP 1.3.x : Exemples SDK ; pour migrer vers 1.4.x, vous devez modifier les importations selon le tableau ci-dessus.
  • Gestion de la précision : PrecisionReducer est un décorateur d'optimiseur, les valeurs par défaut varient entre les versions, écrivez explicitement only_feasible_solution ; perform_precision_adaption_split retourne (split_matrix, last_var_idx), restaurez et vérifiez l'énergie de la matrice originale selon la correspondance.
  • Accès machine réelle : Complément de workflow, ne lisez que si la tâche demande une machine réelle.
  • Autres interfaces : Index des modules, Community.
  • Contient à la fois des quantités continues et des décisions discrètes : écrivez d'abord les contraintes de couplage complètes ; Kaiwu trouve les candidats discrets, puis résolvez le sous-problème continu/fluide en fixant les variables discrètes. Ne décomposez pas binairement une grande quantité de variables continues, ne supprimez pas les contraintes de couplage comme "flux nul si non activé".

Livraison et validation

En cas de génération à partir de zéro, donnez un script complet ; en cas de modification de code existant, donnez les modifications nécessaires. Respectez les données de l'énoncé, le protocole de sortie et la limite de temps, en priorisant un code complet. Lorsque les conditions d'exécution le permettent, vérifiez d'abord les importations, puis compilez, résolvez, décodez et vérifiez le problème original ; ne prétendez pas avoir exécuté si la tâche interdit l'exécution.

La vérification mathématique porte sur deux points : chaque état métier légal peut-il prendre des variables auxiliaires pour que le terme de pénalité dur soit nul ? Dans ce cas, l'énergie est-elle égale à l'objectif original plus une constante ? Vous pouvez utiliser une table de vérité ou l'énumération exhaustive de petits cas pour vérifier les erreurs d'encodage dans un développement de validation indépendant, mais ne mélangez pas ce résultat d'énumération avec le résultat retourné par le SDK. Ne déclarez l'optimalité que si vous avez une borne de référence ou une preuve indépendante ; sinon, rapportez la solution réalisable trouvée, la valeur de l'objectif réel et la limitation de non-optimalité non prouvée.

Complément : normes de livraison de code

Les règles suivantes contraignent le code SDK nouveau et modifié ; les exigences de modélisation et de version ci-dessus sont conservées.

  • Gardez une responsabilité unique. Organisez la modélisation, la résolution SDK, le décodage des candidats et la validation métier originale en étapes claires ; pour une petite taille, un seul script et quelques fonctions suffisent. N'introduisez pas de framework générique, d'enregistrement de plugins, d'héritage multi-niveaux ou de multiples couches de redirection pour un simple appel SDK. Supprimez le code mort, les branches redondantes et les dépendances inutilisées générées par cette modification.
  • Utilisez des interfaces confirmées. Lorsque la version SDK est connue, importez directement l'API correspondante, ne parcourez pas l'ensemble du package, n'essayez pas de deviner les noms de classe et les paramètres. Si une compatibilité multi-version est réellement requise, écrivez des branches étroites autour des interfaces réellement migrées, ne camouflez pas les erreurs métier en problèmes de compatibilité de version.
  • Les exceptions doivent avoir un résultat de traitement clair. N'attrapez que les exceptions spécifiques aux frontières réelles comme l'entrée, l'autorisation, les appels externes, etc., que vous pouvez traiter ; si la récupération est impossible, conservez la cause et échouez. Interdiction de except Exception: pass, des captures multiples redondantes, des tentatives infinies, et de retourner des solutions réalisables fausses ou des valeurs par défaut "succès" après une erreur. N'ajoutez pas de try/except inutile pour des calculs internes fixés.
  • Validez aux vraies frontières. Vérifiez les dimensions, les plages de valeurs et la cohérence des contraintes pour les données externes ; ne vérifiez pas en couches redondantes les données déjà validées en interne, n'ajoutez pas de cadre de sécurité non lié à la tâche pour un petit script local. Lisez les clés secrètes depuis l'environnement ou la configuration existante, ne les codez pas en dur, ne les écrivez pas dans les logs ; n'utilisez pas eval, exec ou de concaténation de commandes shell pour analyser les données. L'installation, la mise en réseau et la soumission au cloud respectent le périmètre d'autorisation de la tâche en cours.
  • Rendez le coût de résolution contrôlable. Définissez la décroissance de la température, le nombre d'itérations par température et la taille du pool de solutions en fonction de la taille des variables et de la limite de temps, en évitant de commencer avec des paramètres très grands. La vérification du temps d'arrêt externe ne peut pas interrompre un solve déjà bloqué, donc un seul lot doit aussi être suffisamment petit ; utilisez une horloge monotone pour gérer les lots, en enregistrant le temps réel. Arrêtez-vous après avoir atteint les limites d'appel, de temps ou de coût, ne traînez pas avec des reconnexions répétées.
  • Réduisez les calculs inutiles. Réutilisez les matrices, données et correspondances de variables inchangées ; décodez et filtrez les candidats lot par lot, n'accumulez pas sans limite des solutions redondantes, n'utilisez pas de grands tableaux intermédiaires pour remplacer des calculs clairs. Ne supprimez pas de vraies contraintes, ne modifiez pas l'objectif original, et ne remplacez pas les résultats de résolution par des réponses non SDK pour gagner en vitesse.
  • Rendez les indices et les unités clairs. Convertissez les numéros d'entrée et les indices de tableau uniformément à l'entrée ; les littéraux positifs/négatifs sont localisés par idx = abs(literal) - 1, puis décidez de l'inversion. Distinguez l'objectif métier, les termes de pénalité et le décalage d'énergie, utilisez des noms de variables qui expliquent la signification, n'écrivez pas de conversions contradictoires dans plusieurs fonctions.
  • Ne faites que des validations qui justifient la correction. Vérifiez les frontières réalisables/non réalisables représentatives, l'objectif métier original et la source réelle des candidats SDK ; ne prenez pas des tests qui ne font que correspondre au texte d'implémentation comme une preuve. Livrez le code nécessaire complet et exécutable, précisez clairement ce qui a été réellement validé ; si l'exécution n'est pas possible, dites-le directement, ne falsifiez pas d'enregistrements d'exécution.

Skills associés