API dokumentáció

Optimalizáló HTTP szolgáltatásként. Küldje el a darabokat és a szálanyagot, válaszként ellenőrzött vágási tervet vagy nyomdakész PDF-et kap. Stabil, verziózott és visszafelé kompatibilis: mezők csak hozzáadódnak, soha nem törlődnek.

Bevezetés

Alap URL: https://api.linearcutting.com. Minden JSON, kivéve a PDF végpontot. A kérések állapotmentesek: nem tároljuk a vágáslistáit.

A kipróbáláshoz nem kell API kulcs. Az alábbi sor, ahogy van, azonnal futtatható. Illessze be egy terminálba.

Copy, paste, run
curl -X POST https://api.linearcutting.com/v1/optimise \
  -H "Content-Type: application/json" \
  -d '{"parts": "2400x5, 1800x3", "stock": 6000}'

Ez egy teljes vágási lista: öt darab 2400-as, három 1800-as, 6000 mm-es szálakból vágva. Megkapja a kiosztásokat, a szükséges szálak számát, a hulladék mennyiségét és azt, hogy a terv bizonyíthatóan optimális-e.

Próbálja ki fizetés előtt. A hitelesítés nélküli hívások ingyenesen futnak: óránként 30, havonta 250 kérés IP-címenként. A limitet túllépve 429-es hibát kap, ami megmutatja, mikor nullázódik a számláló. A sikertelen hívások nem számítanak a limitbe. Éles használathoz szerezzen egy kulcsot havi 5 dollártól: ez feloldja a limiteket, megemeli a méretkorlátokat és saját erőforrásokat biztosít, így a publikus szint terheltsége nem lassítja le.

Hivatalos kliensek

Nulla függőség, MIT licenc, és kulcs sem kell hozzájuk. Ha Pythonban vagy JavaScriptben dolgozik, ne írjon saját fetch-et:

pip install linearcutting
import linearcutting as lc

plan = lc.optimise(parts="2400x5, 1800x3", stock=6000)
plan.bars_used   # 4
plan.optimal     # True, proved, not guessed
npm install linearcutting
import { optimise } from "linearcutting";

const plan = await optimise({ parts: "2400x5, 1800x3", stock: 6000 });
plan.barsUsed;   // 4
plan.optimal;    // true

Python a PyPI-on · JavaScript az npm-en · Python forráskód · JavaScript forráskód

Két garancia, amire alapozhat. A verified sikeres esetben mindig igaz: minden tervet újraellenőrzünk a megadott adatok alapján, mielőtt visszaküldenénk, így nem kaphat olyan tervet, ami nem adja ki a darablistát. Az optimal egy bizonyíték, nem tipp. Csak akkor igaz, ha a keresés megállapította, hogy nem létezik jobb terv, vagy mert kimerítette a lehetőségeket, vagy egy tanúsítvány alapján. Ha az időkeret alatt nem bizonyítható, reménykedés helyett false értéket adunk.

Az optimal és a stockBarsLowerBound két különböző dolog, és szándékosan térnek el. Az alsó korlát egy közelítés, nagyjából "összes hossz ÷ szálhossz", és gyakran nem elérhető. Öt 2400-as és három 1800-as darab az 17 400 mm, ami 2,9 darab 6000-es szál, tehát a korlát 3. Ezeket a darabokat valójában nem lehet 3 szálból kivágni; 4 a valódi minimum, és ezt a megoldó bizonyítja. Tehát a stockBarsUsed: 4, stockBarsLowerBound: 3 és optimal: true nem ellentmondás, hanem azt jelenti, hogy a korlát volt pontatlan, nem a terv. Az optimal alapján döntse el, hogy folytatja-e a keresést; a korlátot csak ellenőrzésre használja.

Rövidítés

A hosszú forma egyértelmű, de kicsit körülményes. A gyakori esetre van egy rövidebb út: a szám a hossz, az x pedig a darabszám:

The short form
{"parts": "2400x5, 1800x3, 600", "stock": 6000}

Mindegyik ugyanazt jelenti, használja azt, amelyik a kódjához a legjobban illik:

All equivalent
{"parts": "2400x5"}
{"parts": ["2400x5"]}
{"parts": [[2400, 5]]}
{"parts": [{"length": 2400, "quantity": 5}]}

Egy harmadik elem címkét jelent a darabon, és árat az anyagon: [2400, 5, "rail"], [6000, 20, 45.50]. A stock pedig a régi stockLength / stocks kettéosztás barátságosabb neve. Egy sima szám azt jelenti: "ez a hossz, vegyél, amennyi kell".

A rövidített forma kibontása minden más előtt megtörténik, tehát ez egy gépelési mód, nem pedig egy másik üzemmód: egy rövid kérés és a hosszú, amivé kibővül, bájt-azonos terveket ad vissza. Használja őket vegyesen, minden meglévő kérés pontosan ugyanúgy működik, mint eddig.

Váglista egy URL-ben

A kis munkák beleférnek egy lekérdező karakterláncba, így a GET is működik. Ez hasznos, ha egy linket szeretne megosztani, árajánlathoz csatolni vagy hibajelentésbe tenni:

GET /v1/optimise
curl "https://api.linearcutting.com/v1/optimise?parts=2400x5,1800x3&stock=6000"

Azonos hitelesítés, azonos korlátok, azonos terv, mint a POST esetében. Megnyithatja böngészőben is.

Hitelesítés

A publikus csomaghoz nem kell kulcs. A fizetős csomagok a kulcsot egy fejlécben küldik; a kulcsok tartalmazzák az engedélyezett böngésző eredeteket is, így a saját oldaláról indított hívások proxy nélkül is működnek.

http
X-API-Key: lk_live_9f2c...

Egy rossz vagy lejárt kulcs 401-et ad vissza. A kulcsokat munkaterületenként adjuk ki: lásd a csomagokat.

POST /v1/optimise

Megold egy váglistát. Visszaadja a tervet, a statisztikákat és a bizonyítható korlátokat.

Kérés törzse

FieldTípusAlapértelmezettLeírás
parts kötelező tömb- A szükséges darabok. Mindegyikhez: length (> 0), quantity (egész szám ≥ 1), opcionális label, material, leftAngle, rightAngle.
stockLength szám- Egyetlen, korlátlan szálanyag. Ezt vagy a stocks mezőt használja, ne mindkettőt.
stocks tömb- Megvásárolható szálak. Mindegyik: length, quantity (null = végtelen), price (null = anyagoptimalizálás pénz helyett), opcionális material, priority.
offcuts tömb[] Már meglévő szálanyagok: length, quantity, opcionális material, priority. Ingyenes anyag, soha nem számít vásárlásnak.
kerfszám ≥ 00A vágás szélessége.
trimlogikaifalseMinden szálanyag mindkét végéről levág egy vágásnyit a darabolás előtt.
methodszövegbalanced balanced, least_waste, offcuts_first, fewest_setups (más néven: fewest_setups). Ha a stocks-nál árak vannak megadva, a balanced a legalacsonyabb költségű megoldásra vált.
minRemnantszám ≥ 00Az ilyen vagy ennél hosszabb leesők usableRemnants-ként (hasznos maradékként) térnek vissza, nem hulladékként.
angleCutsobjektumki{enabled, width, axialSymmetry}. Lásd: ferde vágások.
unitstring"mm"A válaszban visszakapja, és a PDF-re is rákerül. Nem végez átváltást.
unitFormatstringdecimálisA fraction a PDF méreteket a legközelebbi 1/64-es törtként jeleníti meg.
timeLimitmásodpercautoSzámítási időkeret, a csomagnak megfelelően maximalizálva. A keresés 'anytime' jellegű: a hosszabb időkeret csak javíthat az eredményen.

Válasz

200 application/json
{
  "plan": {
    "combinations": [
      {
        "usedComb": {
          "combination": [2400, 2400, 1200],
          "length": 6500,
          "source": "stock",
          "waste": { "total": 492, "remnant": 484, "saw": 8 }
        },
        "count": 2
      }
    ],
    "purchases":      [{ "length": 6500, "count": 2 }],
    "usableRemnants": [],
    "unusedOffcuts":  [],
    "stockBarsUsed":  2,
    "stockBarsLowerBound": 2,
    "totalWaste":     984,
    "optimal":        true,
    "verified":       true,
    "solveTimeMs":    12.5
  },
  "stats": {
    "totalParts": 8, "totalPartsLength": 15600, "totalUsedLength": 16600,
    "yieldPercent": 93.98, "cutCount": 8, "layoutCount": 1,
    "totalCost": null, "trueWaste": 984
  },
  "costLowerBound": null,
  "meta": { "method": "balanced", "kerf": 4, "tier": "public",
            "poweredBy": "linearcutting.com" }
}
FieldLeírás
plan.combinations[]Egy bejegyzés minden kiosztáshoz. A usedComb.combination a szálról levágott darabokat sorolja fel, a length a forrás, a source lehet stock (alapanyag) vagy offcut (maradék), a count pedig az így vágandó szálak száma.
usedComb.wastetotal = forrás − darabok; felosztva saw (vágásrés + igazítás) és remnant (fennmaradó vég) részekre.
plan.purchases[]A bevásárlólista: length (hossz), count (darabszám), plusz price/cost (ár/költség), ha megadott árakat.
plan.usableRemnantsA minRemnant méretet elérő vagy meghaladó leesők, a legnagyobbal kezdve: a holnapi felhasználható maradékok.
plan.unusedOffcutsA terv által fel nem használt maradékok.
plan.stockBarsUsedMegvásárolandó szálak összesen.
plan.optimalBizonyíték. Csak akkor igaz, ha a terv elért egy bizonyítható minimumot (vagy a keresés teljesen lefutott). A felhasználónak nyugodtan megjeleníthető mint "lehető legjobb".
plan.verifiedSikeres futás esetén mindig igaz: az igények teljesítve, minden kiosztás fizikailag lehetséges, a maradékok felhasználása helyes.
plan.stockBarsLowerBound, costLowerBoundBizonyítható minimumok. Ha az optimal hamis, a különbség megmutatja, hogy a terv legfeljebb mennyivel térhet el a tökéletestől.
statsMunka összesítése: darabok, hosszak, yieldPercent (anyagkihozatal), cutCount (vágások száma), layoutCount (kiosztások száma), totalCost (összköltség), trueWaste (teljes hulladék), és byMaterial (anyagtípusonként), ha anyacsoportok vannak használva.

POST /v1/optimise/pdf

Ugyanaz a kérés törzse, plusz egy opcionális jobName. application/pdf-et ad vissza: az 1. oldal egy projektvezetői összefoglaló (anyagrendelés, költségek, optimalitási igazolás); a következő oldalak a gépkezelő lapjai, folyamatos vágási pozíciókkal, darabcímkékkel és egy jelölőnégyzettel minden szálhoz. A kulccsal rendelkező hívóknak megjelenik a nevük vagy márkajelzésük.

bash
curl -X POST https://api.linearcutting.com/v1/optimise/pdf \
  -H "Content-Type: application/json" \
  -H "X-API-Key: lk_live_9f2c..." \
  -d '{ "parts": [{"length": 2400, "quantity": 4}], "stockLength": 6500,
       "kerf": 4, "jobName": "Smith deck order" }' \
  --output cutting-plan.pdf

GET /v1/health

json
{ "status": "ok", "version": "1.3.0", "solver": "Linear Cutlist Optimizer v2" }

Anyagcsoportok

Címkézze fel az alkatrészeket, szálanyagokat és leesőket az anyag szerint, és minden anyagot külön feladatként kezel a rendszer egy kérésen belül: a vágások csak azonos anyagú szálanyagra kerülhetnek. A kiosztások és a beszerzések címkézve érkeznek vissza, a stats.byMaterial pedig csoportonként bontja le a számokat.

json
{
  "parts": [
    { "length": 2400, "quantity": 4, "material": "40x40 SHS" },
    { "length": 1300, "quantity": 6, "material": "Pine 90x45" }
  ],
  "stocks": [
    { "length": 6500, "quantity": null, "material": "40x40 SHS" },
    { "length": 5400, "quantity": null, "material": "Pine 90x45", "priority": true }
  ],
  "kerf": 3
}

A priority: true egy szálanyagon vagy leesőn egy enyhe preferencia: az egyformán jó tervek közül az elsőbbséget élvező tételek kerülnek felhasználásra először. Ez soha nem megy a terv minőségének rovására.

Szög- / gérvágás

Adjon az alkatrészeknek leftAngle és rightAngle tulajdonságot, és engedélyezze az angleCuts opciót. A szögek a darab alsó szögei, ahogy fekszik; a felső szöget negatív számként adja meg (a 120 és a -60 ugyanaz a vágás). Az átalakítás után az érvényes tartomány: 10-től 170 fokig.

angleCuts fieldLeírás
enabledFőkapcsoló. Az alkatrészeken lévő szögeket csak akkor fogadja el, ha ez igaz.
widthAnyagszélesség, ugyanabban a mértékegységben, mint a hosszúságok. A szögvágás oldalirányú kiterjedése: width / tan(angle).
axialSymmetrynone, X, Y, Z vagy XYZ: meghatározza, hogy az anyag melyik tengely mentén forgatható, ami befolyásolja a gérvágások egymásba ágyazását. A zártszelvények jellemzően XYZ szimmetriájúak; az egyoldalas anyagok none.

Ahol két szomszédos gérvágás párhuzamos, ott egyetlen fűrészvágás mindkét élt létrehozza. A szögvágás mód kiosztásai egy rendezett parts tömböt (a használt orientációval) és cutPositions adatokat adnak hozzá: minden vágás a szál nulla végétől mért távolság, [felső, alsó] párként, ha szögben van, vagy egyetlen számként, ha derékszögű.

angle-mode layout (excerpt)
"cutPositions": [[1200, 1300], [2442.265, 2500], 3300]

Hibák

A hibatörzsek formátuma: { "error": "...", "detail": "..." }. A detail emberi olvasásra készült: megnevezi a hibás alkatrészt vagy anyagot.

StatushibaMikor
400validationHibás hosszúságok vagy mennyiségek, ismeretlen módszer, egy alkatrész, amely egyik forrásanyagra sem illeszkedik, a kereslet meghaladja a véges készletet, a szögvágási szabályok megsértése, vagy a stocks és a stockLength egyszerre van elküldve.
401badKeyHiányzó, ismeretlen vagy letiltott API kulcs.
413partsLimitTöbb alkatrész, mint amennyit a csomagja megenged.
429rateLimitedElérte a futtatási vagy a havi korlátot. Vegye figyelembe a Retry-After fejlécet.
503busyA megoldó leterhelt. Próbálja újra hamarosan.

Futtatási korlátok

A korlátok lassítanak, de soha nem generálnak túlszámlázást. Az érvényesítésen megbukott kérések nem számítanak bele a havi keretbe. A teljes adatok a csomagok oldalon találhatók.

GuardIngyenesFizetős szintek
Korlát10 kérés / 5 perc IP-címenként20-240 / perc csomagonként
Darabok összesen300500 - 5,000
Különböző darabtípusok60legfeljebb 400
Számítási keret20 s60 - 300 s

A különböző darabtípusok és a darabok összmennyisége is korlátozva van, mert a számítási költséget a méretek sokfélesége adja: 300 egyforma vágás optimális eredményt ad ezredmásodpercek alatt, 300 különböző viszont nem.

Példák

Legolcsóbb kombináció több szálanyagból (JavaScript)

javascript
const res = await fetch("https://api.linearcutting.com/v1/optimise", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "lk_live_9f2c...",
  },
  body: JSON.stringify({
    parts: [
      { length: 3000, quantity: 8 },
      { length: 1200, quantity: 10 },
    ],
    stocks: [
      { length: 6500, quantity: null, price: 45 },   // unlimited
      { length: 12000, quantity: 4, price: 70 },     // only four on hand
    ],
    offcuts: [{ length: 2600, quantity: 1 }],
    kerf: 4,
    minRemnant: 400,
    method: "balanced",   // prices present -> optimises dollars
  }),
});

const { plan, stats } = await res.json();
console.log(plan.purchases);     // what to buy
console.log(stats.totalCost);    // what it costs
console.log(plan.optimal);       // true = provably the cheapest

Gérvágott keretdarabok (Python)

python
import requests

r = requests.post(
    "https://api.linearcutting.com/v1/optimise",
    json={
        "parts": [
            {"length": 1300, "quantity": 2, "leftAngle": 90, "rightAngle": 45},
            {"length": 1200, "quantity": 2, "leftAngle": 135, "rightAngle": 60},
        ],
        "stockLength": 3310,
        "kerf": 0,
        "angleCuts": {"enabled": True, "width": 100, "axialSymmetry": "none"},
    },
    timeout=30,
)
r.raise_for_status()

for combo in r.json()["plan"]["combinations"]:
    print(combo["count"], "x", combo["usedComb"]["cutPositions"])

Nagy, lassú munkák kezelése

A nagy listák feldolgozása másodpercekig vagy percekig is tarthat. A keresés bármikor leállítható, ezért állítsa a timeLimit értékét annyira, amennyit a felület bír várakozással, és az optimal jelzéssel tudassa a felhasználóval, hogy a kapott eredmény bizonyítottan a legjobb, vagy csak az eddig talált legjobb.

json
{ "parts": [ /* 900 parts */ ], "stockLength": 6500,
  "kerf": 4, "timeLimit": 60 }