Przejdź do zawartości

Dowolny problem optymalizacyjny. Jedna odpowiedź.

Marszrutyzacja, harmonogramowanie, obsady, pakowanie, przydział i każdy inny problem z decyzjami, ograniczeniami i kosztem. Problem opisuje się raz, wskazuje solver albo meta-solver i płaci za sekundę obliczeń, z twardym limitem kosztu na każdym uruchomieniu.

POST /solve/v1/problems 201 Created prb_9f3c…

            {
            "api_version": "1",
            "problem": {
            "variables": [
            {"name": "chairs", "lower": 0},
            {"name": "tables", "lower": 0}
            ],
            "constraints": [
            {"expr": "4*chairs + 8*tables <= 160", "name": "machine_hours"},
            {"expr": "2*chairs + 3*tables <= 75", "name": "material"}
            ],
            "objective": {"sense": "max", "expr": "45*chairs + 80*tables"}
            },
            "solver": "highs",
            "options": {"compute_preset": "cpu-standard", "time_limit_seconds": 5, "tags": ["quickstart"]}
            }
        
"solver": "highs","compute_preset": "cpu-standard","time_limit_seconds": 5
Pokaż całą kopertę

            {
            "api_version": "1",
            "problem": {
            "variables": [
            {"name": "chairs", "lower": 0},
            {"name": "tables", "lower": 0}
            ],
            "constraints": [
            {"expr": "4*chairs + 8*tables <= 160", "name": "machine_hours"},
            {"expr": "2*chairs + 3*tables <= 75", "name": "material"}
            ],
            "objective": {"sense": "max", "expr": "45*chairs + 80*tables"}
            },
            "solver": "highs",
            "options": {"compute_preset": "cpu-standard", "time_limit_seconds": 5, "tags": ["quickstart"]}
            }
        
objective
1750
hold
rozliczone
wall_seconds
0.4
solver_used
highs
outcome
solved
termination_status
OPTIMAL
chairs
30
tables
5
GET /problems/{id}/result solution
Szybki start z dokumentacji w działaniu. Optimum: 30 krzeseł, 5 stołów, funkcja celu 1750.
Problem

Optymalizację trudno kupić

Matematyka ma za sobą osiemdziesiąt lat. Zespoły grzęzną dopiero przy wdrożeniu jej na produkcji, bo krajobraz solverów jest rozdrobniony.

Każdy solver jest inny

Własne API, format modelu i licencjonowanie. Wiedza o jednym słabo przekłada się na następny.

API, format, licencja

Ograniczenia trzeba przeformułowywać

Natywny dla jednego silnika, przebudowywany dla następnego. Wyniki wracają w tylu postaciach, ilu jest solverów.

n solverów, n formatów

Nie każde ograniczenie jest obsługiwane

Wymaganie może wypaść poza to, co przyjmuje silnik. Albo przenosi się cały model, albo zastępuje je przybliżeniem, a model przestaje odpowiadać rzeczywistemu problemowi.

jedno ograniczenie, nowy silnik

Silniki wymagają różnego sprzętu

Jedne działają na CPU, inne wymagają GPU. Wybór silnika oznacza dziś przygotowanie maszyny, na której działa, zanim wiadomo, czy wygrywa.

CPU albo GPU, zależnie od silnika

Wybór to właśnie ekspertyza

To, który silnik pasuje do ograniczeń, samo w sobie jest pytaniem badawczym. Dobra odpowiedź wymaga specjalisty z dziedziny spoza zespołu.

wybór to cała praca

Najlepszy silnik ciągle się zmienia

Solvery wydają nowe wersje i ten, który rok temu wygrywał na danych instancjach, dziś może już nie wygrywać. Nikt w zespole nie dostaje pieniędzy za powtórzenie tego testu.

każda wersja tasuje wyniki

Modele danych spawają się z dostawcą

Wybór solvera po cichu przesądza też o schemacie danych. Wyrośnięcie z niego oznacza rozcinanie spawu pod presją.

zamiast tego jedna koperta

Co bierzemy na siebie

Ty piszesz model. My prowadzimy wszystko pod nim.

Nic z tej listy nie dotyczy twojego biznesu. To wszystko maszyneria, a maszyneria jest nasza.

Trzy rzeczy, które robisz
  • Napisać model: decyzje, ograniczenia, cel.
  • Ustawić termin i limit kosztu na uruchomienie.
  • Odczytać odpowiedź, za każdym razem w tej samej postaci.
Siedem rzeczy, których już nie robisz
  • Nauka nowego API, formatu modelu i licencji dla każdego silnika.
  • Przeformułowanie tych samych ograniczeń pod kolejny silnik.
  • Rezygnacja z wymagania, bo silnik go nie przyjmuje.
  • Przygotowanie maszyny z GPU pod uruchomienie trwające minutę.
  • Rozstrzyganie, który silnik pasuje do problemu, który masz przed sobą.
  • Powtarzanie testów wydajności przy każdej nowej wersji solvera.
  • Wpuszczanie schematu dostawcy do własnej bazy danych.

Dodaj ograniczenie w przyszłym kwartale: zmienia się model i nic poza tym.

Koperta

Jedna koperta, wersjonowana

Cztery części. Koperta jest nasza i my ją walidujemy. Problem w środku należy do Państwa.

envelope.json
{
  "api_version": "1",
  "problem": {
    "variables": [
      {"name": "chairs", "lower": 0},
      {"name": "tables", "lower": 0}
    ],
    "constraints": [
      {"expr": "4*chairs + 8*tables <= 160",
       "name": "machine_hours"},
      {"expr": "2*chairs + 3*tables <= 75",
       "name": "material"}
    ],
    "objective": {
      "sense": "max",
      "expr": "45*chairs + 80*tables"
    }
  },
  "solver": "highs",
  "options": {
    "compute_preset": "cpu-standard",
    "time_limit_seconds": 5,
    "tags": ["quickstart"]
  }
}
api_version
Wersja protokołu. Dziś zawsze „1”.
problem
Model klienta: zmienne, ograniczenia, funkcja celu. Nieprzezroczysty dla nas, walidowany przez solver.
solver
Nazwa konkretnego solvera albo nazwa meta-solvera: nazwanego zbioru silników członkowskich, z których każdy może przyjąć zadanie.
options
time_limit_seconds, compute_preset, webhook, idempotency_key, tags. Wszystkie opcjonalne.

Treść zadania traktujemy jako nieprzezroczystą. Menedżer waliduje kopertę i mierzy zużycie, ale nigdy nie czyta modelu.

Wysyłka, śledzenie, pobranie

Zgłoszenie zwraca identyfikator i status w kolejce od razu. Zarejestruj podpisany webhook, a odpowiedź przyjdzie sama, albo utrzymaj jedno żądanie otwarte na wywołaniu wait aż do końca zadania. Rozwiązanie pobiera się jednym wywołaniem.

solved
rozwiązanie optymalne albo mieszczące się w tolerancji
no_solution
dowiedziona sprzeczność albo brak ograniczenia, rozliczane, bo dowód jest produktem
limit
obliczenie zatrzymał limit; jeśli istnieje bieżące najlepsze rozwiązanie, zostaje zwrócone
error
silnik poległ na tym modelu; bez ponowienia, trzeba wybrać inny solver albo przeformułować

Zbudowane pod solvery, które padają, i sieci, które się rwą

Obliczenie, które padło albo utknęło, jest wykrywane, wraca do kolejki i zostaje podjęte ponownie. Rozliczana jest jedna próba, ta udana. Webhooki końcowe są ponawiane z narastającym odstępem, a potem trafiają do dziennika dead-letter, który można przejrzeć i odtworzyć.

Jedna koperta, dwie próby, jeden rachunek

Rozmiar koperty
do 20 MB
Limit czasu
domyślnie 300 s, maksymalnie 6 h
Zgłoszenie wsadowe
do 100 kopert w jednym wywołaniu
Ponowienia webhooków
1 min, 5 min, 25 min, 2 h, potem dead-letter
Podpis
X-Solve-Signature, HMAC SHA-256 z surowej treści
Rozliczenie po awarii
raz, tylko udana próba
Anulowane w kolejce
bez opłaty, blokada zwolniona
Ograniczanie liczby zapytań
429 z nagłówkiem Retry-After
Silniki

Każdy silnik, który uruchamiamy, i to, czy odpowiada w tej chwili

Na tej stronie nie opublikowano jeszcze żadnego silnika.

Silniki otwarte działają po naszej stronie. Silniki komercyjne działają na własnej licencji klienta. Meta-solver to nazwany zbiór silników członkowskich, nie czarna skrzynka, a użyty silnik i jego cena są podawane w każdym wyniku.

Cennik

Mierzone jak zasoby, wycenione przed uruchomieniem

cost = base_fee + ceil(seconds × effective_rate)

Każdy silnik ma opublikowaną opłatę podstawową i stawkę za sekundę rezerwowanych zasobów, a każdy profil obliczeniowy mnoży tę stawkę. Koszt maksymalny wynika z silnika, profilu i ustawionego czasu, i jest rezerwowany z salda przed startem obliczenia. Płacisz za zużyte sekundy. Anuluj w dowolnej chwili i zapłać za te sekundy, nigdy więcej. Darmowe kredyty przy rejestracji, bez karty.

API

REST API do przeczytania za jednym razem

Wersjonowane endpointy, ustrukturyzowane błędy wskazujące błędne pole, podpisane webhooki z widocznym dziennikiem dostarczeń i strumień zdarzeń na wypadek, gdy nie da się ich odebrać. Każda integracja ma te same trzy ruchy: wysyłka, śledzenie, pobranie.

jumpy, nasze SDK w Pythonie

Model pisze się w Pythonie, a rozwiązanie czyta jako obiekty. Wysyłanie, wywołanie wait, kontrola webhooków i bezpieczne ponowienia są już gotowe. Studio uruchamia je w przeglądarce, bez instalowania czegokolwiek.

Bezpieczeństwo

Klucze o ograniczonym zakresie, sekrety w postaci skrótów, kontrolowany ruch wychodzący

Klucze

Nazwane klucze działają wyłącznie w API optymalizacji i można je unieważniać pojedynczo, więc wymiana jednego nie rusza pozostałych.

Sekrety

Przechowywane wyłącznie jako skróty. Surowy sekret jest pokazywany raz i nigdy więcej.

Ruch wychodzący webhooków

Adresy docelowe są sprawdzane pod kątem zakresów prywatnych i metadanych, zanim się połączymy, więc przejęty adres nie sięgnie usług wewnętrznych.

Retencja

Dane zadań są usuwane według opublikowanego harmonogramu, domyślnie po 90 dniach. Metadane zostają na potrzeby śladu audytowego.

Pytania, które naprawdę zadają inżynierowie

Czy mogę wymusić konkretny solver?

Tak. Wskazanie konkretnego solvera w kopercie jest respektowane dokładnie. Meta-solver jest na sytuacje, w których wolą Państwo nie wybierać.

Które klasy problemów są obsługiwane?

Wszystko, co rozwiązują podłączone silniki: LP, MIP, NLP, CP, harmonogramowanie i marszrutyzacja. Koperta z założenia nie zna klas problemów.

Co się dzieje, gdy obliczenie padnie w trakcie?

Jest wykrywane, automatycznie wraca do kolejki i zostaje podjęte ponownie. Widać to w historii prób, a rozliczana jest jedna, ta udana.

Jak długo przechowujecie dane mojego problemu?

Dane zadań są usuwane według opublikowanego harmonogramu, domyślnie po 90 dniach. Metadane zostają na potrzeby śladu audytowego. Po usunięciu pobranie zwraca 410 purged.

Pierwsze obliczenie jest pięć minut stąd

Uruchom prawdziwy model na prawdziwym solverze, w przeglądarce. Bez konta, bez karty.