API dokümantasyonu

HTTP servisi olarak optimizasyon motoru: kesilecek parçaları ve stokları gönderin, onaylanmış bir kesim planı veya baskıya hazır bir PDF alın. Kararlı, versiyonlu ve geriye dönük uyumlu: alanlar kaldırılmaz, sadece eklenir.

Giriş

Temel URL https://api.linearcutting.com. PDF uç noktası hariç her şey JSON formatındadır. İstekler durum bilgisi tutmaz: kesim listelerinizi saklamayız.

Bunu denemek için bir API anahtarına ihtiyacınız yok. Aşağıdaki satır, yazıldığı gibi şu anda çalışır. Bir terminale yapıştırın.

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

Bu tam bir kesim listesi: beşi 2400, üçü 1800 ölçüsünde beş parça, 6000mm'lik çubuklardan kesilecek. Geriye yerleşim planlarını, kaç çubuk gerektiğini, ne kadar fire çıktığını ve planın kanıtlanabilir şekilde optimum olup olmadığını alırsınız.

Doğrulamasız çağrılar ücretsizdir. Ödemeden önce deneyin: IP adresi başına saatte 30, ayda 250 istek. Limiti aşarsanız ne zaman sıfırlanacağını belirten bir 429 hatası döner. Hatalı çağrılar sayılmaz. Gerçek bir iş için aylık $5'a bir anahtar alın: Bu anahtar limitleri ve boyut sınırlarını kaldırır, size özel işlem hakkı tanır. Böylece genel katmandaki yoğunluk sizi etkilemez.

Resmi istemciler

Sıfır bağımlılık, MIT lisanslı ve anahtar da gerektirmezler. Python veya JavaScript kullanıyorsanız, elle bir fetch yazmayın:

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

PyPI'da Python · npm'de JavaScript · Python kaynak kodu · JavaScript kaynak kodu

İki sağlam garanti: verified başarılı olduğunda daima true olur. Her plan, size gönderilmeden önce girdilerinize göre yeniden denetlenir, böylece listenizi kesmeyen bir plan size ulaşamaz. optimal bir tahmin değil, bir kanıttır. Yalnızca arama, olasılıkları tüketerek veya bir sertifika ile daha iyi bir planın mevcut olmadığını saptadığında true olur. Süre sınırı içinde kanıtlanamadığında, umut etmek yerine false deriz.

optimal ve stockBarsLowerBound farklı şeylerdir ve kasıtlı olarak uyuşmazlar. Alt sınır, kabaca "toplam uzunluk ÷ çubuk uzunluğu" olan bir gevşetmedir ve genellikle ulaşılamazdır. Beş adet 2400'lük ve üç adet 1800'lük 17.400mm eder, bu da 2,9 adet 6000'lik çubuk demektir, yani sınır 3 der. Bu parçaları 3 çubuktan kesemezsiniz; gerçek minimum 4'tür ve çözücü bunu kanıtlar. Yani stockBarsUsed: 4, stockBarsLowerBound: 3 ve optimal: true bir çelişki değildir. Bu, planın değil, sınırın gevşek olduğu anlamına gelir. Aramaya devam edip etmeyeceğinize karar vermek için optimal kullanın; sınırı sadece bir sağlama olarak kullanın.

Kısayol

Uzun form ayrıntılıdır ve biraz zahmetlidir. Yaygın durumlar için kısa yolu kullanın: sayı uzunluk, x ise adet anlamına gelir:

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

Bunların hepsi aynı anlama gelir, yazdığınız koda hangisi uyuyorsa onu kullanın:

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

Üçüncü bir öğe, parçada bir etiket ve stokta bir fiyattır: [2400, 5, "rail"], [6000, 20, 45.50]. Ve stock, eski stockLength / stocks ayrımının kolay adıdır; tek başına bir sayı, "bu uzunlukta, ihtiyacın kadar al" demektir.

Kısa yazım her şeyden önce genişletilir, yani farklı bir mod değil, bir yazma şeklidir: kısa bir istek ve genişletilmiş hali olan uzun istek, birebir aynı planları döndürür. İkisini serbestçe karıştırın, mevcut her istek eskisi gibi çalışmaya devam eder.

URL içinde kesim listesi

Küçük işler bir sorgu dizesine sığar, bu yüzden GET de çalışır. Bu, paylaşmak, teklife eklemek veya bir hata raporuna bırakmak istediğiniz bir bağlantı için kullanışlıdır:

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

POST ile aynı kimlik doğrulama, aynı sınırlar, aynı plan. İsterseniz tarayıcıda açın.

Kimlik Doğrulama

Herkese açık kademe anahtar gerektirmez. Ücretli kademeler anahtarlarını bir başlıkta gönderir; anahtarlar ayrıca izin verilen tarayıcı kaynaklarınızı da taşır, böylece kendi sitenizden yapılan çağrılar bir proxy olmadan çalışır.

http
X-API-Key: lk_live_9f2c...

Hatalı veya süresi dolmuş bir anahtar 401 döndürür. Anahtarlar çalışma alanı başına verilir: planları görün.

POST /v1/optimise

Bir kesim listesini çözer. Planı, istatistikleri ve kanıtlanabilir sınırları döndürür.

İstek gövdesi

FieldTürVarsayılanAçıklama
parts gerekli dizi- İhtiyacınız olan parçalar. Her biri: length (> 0), quantity (tam sayı ≥ 1), isteğe bağlı label, material, leftAngle, rightAngle.
stockLength sayı- Tek bir sınırsız stok boyu. Bunu veya stocks'u kullanın, ikisini birden değil.
stocks dizi- Satın alınabilir boylar. Her biri için: length, quantity (null = sınırsız), price (null = para yerine malzemeyi optimize et), isteğe bağlı material, priority.
offcuts dizi[] Elinizdeki boylar: length, quantity, isteğe bağlı material, priority. Bedelsiz malzeme, satın alma sayılmaz.
kerfsayı ≥ 00Kesim başına testere payı.
trimmantıksalfalseKesime başlamadan önce her stok malzemenin iki ucundan bir testere payı alın.
methoddizebalanced balanced, least_waste, offcuts_first, fewest_setups (diğer adıyla: fewest_setups). stocks üzerindeki fiyatlar, balanced metodunu en düşük maliyetliye çevirir.
minRemnantsayı ≥ 00Bu boy ve daha uzun artıklar, fire yerine usableRemnants olarak döner.
angleCutsnesnekapalı{enabled, width, axialSymmetry}. Bakınız açılı kesimler.
unitmetin"mm"Geri yansıtılır ve PDF'lere basılır. Herhangi bir birim çevirimi yapmaz.
unitFormatmetinondalıkfraction, PDF ölçülerini en yakın 1/64'lük kesirler halinde gösterir.
timeLimitsaniyeotomatikÇözüm süresi, üyelik seviyesiyle sınırlıdır. Arama istenildiği zaman durdurulabilir: daha uzun süre, sadece sonucu iyileştirir.

Yanıt

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" }
}
FieldAçıklama
plan.combinations[]Her farklı yerleşim için bir giriş. usedComb.combination o çubuktan kesilen parçaları listeler, length kaynaktır, source ise stock veya offcut'tır ve count o şekilde kaç adet çubuk kesileceğini belirtir.
usedComb.wastetotal = kaynak − parçalar; saw (testere payı + trim) ve remnant (kalan uç) olarak ikiye ayrılır.
plan.purchases[]Satın alma listesi: length, count, artı fiyat belirttiyseniz price/cost.
plan.usableRemnantsminRemnant'tan büyük veya eşit artıklar, en büyüğü başta: yarının kullanılabilir fire stoğu.
plan.unusedOffcutsPlanın ihtiyaç duymadığı kullanılabilir fireler.
plan.stockBarsUsedSatın alınacak toplam çubuk.
plan.optimalKanıt. Yalnızca plan kanıtlanabilir bir alt sınıra ulaştığında (veya arama tam olarak tamamlandığında) doğrudur. Kullanıcılara "mümkün olan en iyi" olarak güvenle gösterilebilir.
plan.verifiedBaşarılı olduğunda her zaman doğrudur: talep karşılandı, her yerleşim fiziksel olarak sığıyor, kullanılabilir fire stoğuna uyuldu.
plan.stockBarsLowerBound, costLowerBoundKanıtlanabilir minimumlar. optimal yanlış olduğunda, aradaki fark bu planın en fazla ne kadar sapabileceğini gösterir.
statsİş toplamları: parçalar, boylar, yieldPercent, cutCount, layoutCount, totalCost, trueWaste ve malzeme grupları kullanıldığında byMaterial.

POST /v1/optimise/pdf

Aynı istek gövdesi, artı isteğe bağlı bir jobName. application/pdf döndürür: sayfa 1 bir proje yöneticisi özetidir (satın alma siparişi, maliyetler, optimumluk sertifikası); sonraki sayfalar testere operatörü için kesim pozisyonlarını, parça etiketlerini ve her çubuk için bir onay kutusunu içeren sayfalardır. Anahtar sahibi olanların atıfları veya markaları basılır.

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" }

Malzeme grupları

parts, stocks ve offcuts öğelerini material ile etiketleyin; her malzeme tek bir istek içinde kendi işi olarak çözülür: kesimler yalnızca aynı malzemeden stok üzerine yapılır. Yerleşimler ve satın alımlar etiketlenmiş olarak geri döner ve stats.byMaterial rakamları gruba göre ayırır.

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
}

Bir stok veya artık parça üzerinde priority: true olması yumuşak bir tercihtir: eşit derecede iyi olan planlar arasında, öncelikli öğeler ilk kullanılır. Plan kalitesinden asla ödün vermez.

Açılı / gönyeli kesimler

Parçalara bir leftAngle ve rightAngle verin ve angleCuts özelliğini etkinleştirin. Açılar, parçanın durduğu konumdaki alt açılardır; üst açıyı negatif bir sayı olarak girin (120 ve -60 aynı kesimdir). Bu dönüşümden sonra geçerli aralık: 10 ila 170 derece.

angleCuts fieldAçıklama
enabledAna anahtar. Parçalardaki açılar yalnızca true olduğunda kabul edilir.
widthMalzeme genişliği, uzunluklarla aynı birimde. Açılı bir kesim width / tan(angle) kadar yana taşar.
axialSymmetrynone, X, Y, Z veya XYZ: malzemenin hangi çevirmelere izin verdiğini belirtir, bu da gönyeli kesimlerin nasıl iç içe geçebileceğini belirler. Kare profil tipik olarak XYZ'dir; tek taraflı malzeme none'dur.

İki komşu gönyeli kesim paralelse, tek bir testere kesimi her iki kenarı da oluşturur. Açı modundaki yerleşimler, sıralı bir parts dizisi (kullanılan yönelimle birlikte) ve cutPositions ekler: her kesim çubuğun sıfır ucundan ölçülür, açılı olduğunda bir [üst, alt] çifti olarak veya düz olduğunda tek bir sayı olarak.

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

Hatalar

Hata gövdeleri { "error": "...", "detail": "..." } şeklindedir. detail alanı bir insana gösterilmek üzere yazılmıştır: sorunlu parçayı veya malzemeyi adlandırır.

StatushataNe zaman
400validationHatalı uzunluklar veya miktarlar, bilinmeyen yöntem, hiçbir stoka sığmayan bir parça, talebin sonlu stoğu aşması, açı kurallarının ihlali, hem stocks hem de stockLength gönderilmesi.
401badKeyEksik, bilinmeyen veya devre dışı bırakılmış API anahtarı.
413partsLimitKatmanınızın izin verdiğinden daha fazla parça.
429rateLimitedHız veya aylık sınıra ulaşıldı. Retry-After başlığına uyun.
503busyÇözücü kapasitesi dolu. Kısa süre sonra tekrar deneyin.

Hız sınırları

Sınırlar kullanımı yavaşlatır; asla aşım faturası oluşturmazlar. Doğrulama hatası alan istekler aylık sınırınıza dahil edilmez. Tüm rakamlar planlar sayfasındadır.

GuardÜcretsizÜcretli katmanlar
SıklıkIP başına 5 dakikada 10 istekKademeye göre dakikada 20-240
Toplam parça300500 - 5,000
Farklı parça satırı60en çok 400
Çözüm süresi20 s60 - 300 s

Toplam parçaya ek olarak farklı parça satırları da sınırlıdır çünkü çözüm maliyeti boy çeşitliliğinden gelir: 300 aynı parça milisaniyeler içinde optimize edilir, 300 farklı parça ise edilemez.

Formüller

Birden fazla stok boyu için en ucuz karışım (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

Açılı kesim çerçeve parçaları (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"])

Yavaş ve büyük bir işle başa çıkma

Büyük listeler saniyeler veya dakikalar sürebilir. Arama herhangi bir zamanda durdurulabilir, bu yüzden timeLimit'i arayüzünüzün bekleyebileceği bir değere ayarlayın ve kullanıcılara cevabın kanıtlanmış mı yoksa sadece o ana kadar bulunan en iyi sonuç mu olduğunu göstermek için optimal'i kullanın.

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