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.
{
"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
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
Ty piszesz model. My prowadzimy wszystko pod nim.
Nic z tej listy nie dotyczy twojego biznesu. To wszystko maszyneria, a maszyneria jest nasza.
- Napisać model: decyzje, ograniczenia, cel.
- Ustawić termin i limit kosztu na uruchomienie.
- Odczytać odpowiedź, za każdym razem w tej samej postaci.
- 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.
Jedna koperta, wersjonowana
Cztery części. Koperta jest nasza i my ją walidujemy. Problem w środku należy do Państwa.
{
"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
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.
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.
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.
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.
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.