من السهل القيام به بنفسك اللوجستية



أريد أن أشارككم تجربة إنشاء نظام لوجستي في شركة تجارية واحدة.

في أحد الأيام الجميلة ، في عام 2012 القريب ، حدد رئيس المجموعة المهمة: التفكير في مشكلة تحسين تكاليف النقل في المؤسسة.
مجال النشاط الرئيسي للمؤسسة هو الجملة وتسليم المنتجات ، حيث تحتل تكاليف النقل حصة كبيرة من التكاليف.

اعتبرت الإدارة أن الوقت قد حان لترتيب الأمور في إنفاق الأموال على الوقود ، وكانت هناك أيضًا شكوك حول تورط السائقين بالإضافة إلى ذلك في التوصيل "الأيسر" بين الرحلات الجوية. في المؤسسات الصغيرة والمتوسطة الحجم ، يعتمد الكثير على الثقة ، حيث أن الاحتفاظ بالأفراد للسيطرة أمر غير مربح وغير مستحسن دائمًا. عندما ترتفع التكاليف وتنخفض الكفاءة ، ما عليك سوى فعل شيء.

بادئ ذي بدء ، حاولنا حل المشكلة عن طريق أساليب الإدارة: القياس المستمر لمستوى الوقود ، وقراءات مقياس سرعة الدوران ، وقياس وقت التسليم مع مرافقة شخصية للبضائع. لم يكن التأثير سوى السلبيات والشك والحركات غير الضرورية (قياس هذا هو أيضًا وظيفة لشخص ما). إذا كان لا يزال من الممكن تحديد نطاق تقريبي مع مسار واحد ، ثم مع رحلة من 25 إلى 35 منشأة للبيع بالتجزئة ، كل شيء تغير كثيرًا ، كان الفارق كبيرًا جدًا ، من حيث الوقت والوقود.

الهدف: إرسال المركبات المزدحمة إلى المؤسسات التجارية ، والحد من الأميال ، وبالتالي التكاليف. إذا كان ذلك ممكنا ، تجنب الانحراف عن الطريق. الهدف هو خفض التكاليف مع الحد الأدنى من الاستثمار في التمويل ووقت التنفيذ ، إذا جاز التعبير يوم أمس. خلال المناقشات ، وافقوا على عدة بدائل:

  1. استخدام إحدى الخدمات لحساب الطرق والمحاسبة الخاصة بالوقود ومواد التشحيم ؛
  2. وضعت على وحدات تتبع / تتبع الأسطول.
  3. تصميم شيء نفسك ؛

قررنا تجربة الحلول الثلاثة واختيار الأفضل:

1. في ذلك الوقت ، لم نجد حلاً جيدًا جاهزًا للاستخدام. إما تصميم جاهز ، لكنه مكلف ، أو اعتبره كما هو ومزيد من الاتفاق. لقد جربت العديد من الخدمات عبر الإنترنت. بشكل عام ، هذا ليس بالأمر السيئ ، ولكن كانت الصعوبة في الأساس هي تكرار المعلومات من نظام المحاسبة ، وعدد الإجراءات اللازمة للحصول على النتيجة (انقر هنا ، اذهب إلى هنا ، قم بتحديث الدليل) ، كل شيء على الإنترنت (في ذلك الوقت كانت مهمة). لكن العائق الأكبر هو صعوبة إنشاء طرق مع العديد من النقاط واختيار أفضل طريق. عادة ، كان يجب تحديد كل شيء يدويًا ، وضبط القيم ، التي كانت طويلة وليست ناجحة دائمًا كنتيجة لذلك.

بعد شهرين من العمل ، رفضوا هذا القرار.

2. كتجربة ، قاموا بتثبيت وحدات تتبع GSM على 12 سيارة.
والنتيجة هي أكثر نجاحا. أنت تعرف دائما أين كانت السيارة. لكن التكلفة أغلى من الخيار الأول. ومع ذلك ، بعد تحديد اثنين من حالات الانحراف عن الطريق (أحد السائقين shabbat ، والثاني زار سيدة القلب ، خلال ساعات العمل) ، بدأ الموظفون للتخلص بشكل مكثف من هذه الأجهزة. على الرغم من أنهم لم يقبلوا هذا الابتكار بحماس من قبل. إما أن تومض وحدة الطاقة بطريق الخطأ ، فقد فشل الجهاز أثناء إصلاح المحرك ، أو "تم زيادة حرارة" الإلكترونيات في الشمس. لذلك لمدة ثلاث سنوات فقدنا 9 أجهزة. بشكل عام ، اتضح أن القرار كان إيجابياً ، لكن من السلبيات - اضطررت إلى إلقاء نظرة على الطرق التي تم قطعها لفترة طويلة لتحديد النشاط المشبوه ، وهو أمر غير مناسب للغاية. كانت علامة الجمع في نظام التتبع هي العنصر الخاص بتصدير المسار ، والذي سمح بتجميع إحصاءات معينة على المسارات.

في وقت لاحق ، استخدمنا نظامًا آخر من أحد مشغلي الهاتف المحمول الرئيسيين في اتصالات الشركات وتتبع نشاط وكلاء المبيعات ، وكانت النتيجة متشابهة: تم تعطيل بطاقات SIM ، وفقدان الهواتف ، ونسيانها في المنزل ، واستنفاد البطارية ، وسيجد الناس دائمًا مخرجًا.

3. بالتوازي مع أول طريقتين ، قررنا اختراع دراجة ، لكي ندرك في نظامنا المحاسبي القدرة على بناء الطرق بأنفسنا.

أولاً ، أحضرنا جميع أماكن الزيارة وأدخلنا إحداثياتها الجغرافية في قاعدة البيانات. حصلنا على الإحداثيات وفقًا لتعقب GPS عند الزيارة ، وكذلك بصريًا من خرائط OSM ، لإيجاد المكان الصحيح باستخدام الماوس ونسخ الإحداثيات.

في المرحلة الثانية ، كان من الضروري الحصول على خرائط متجهة للمنطقة بتنسيق مناسب.
وقع الاختيار على نفس نظام التشغيل ، نظرًا لأن البطاقات لها تنسيق مفتوح. لم نتقن تفريغ الكوكب ، لذلك قمنا في البداية بتحميل البيانات في أجزاء بتنسيق XML ، من خلال التصدير من OSM نفسه ، ثم وصلنا المناطق. في وقت لاحق جاء عبر مشروع GIS-LAB . هؤلاء الأشخاص الجديرون لسنوات عديدة وضعوا مكبًا يوميًا للأراضي ، مقسمًا حسب المنطقة. لكن الجميع يريد أن يأكل ، فقد توقف المشروع مؤخرًا ، وانتقل الرجال ، وهم يقومون بنفس المهمة مقابل سعر معقول.

بعد استلام الخريطة بتنسيق XML ، استخرجنا الطبقة المسؤولة عن الطرق وفقًا للمواصفات . نظرًا لأن حجم البطاقات في العديد من المناطق المجاورة يشغل عشرة غيغابايت ، تم كتابة المحلل اللغوي SAX باللغة RUBY ، وحدد فقط العلامات اللازمة ودمج المناطق المجاورة التي تم فيها تنفيذ الأنشطة في بنية واحدة.

تتم كتابة المشروع نفسه كدليل DLL خارجي لنظام المحاسبة المكتوب في باسكال. كان أسطول الأجهزة التي كان من المفترض أن يعمل عليها النظام ، بعبارة بسيطة ، عفا عليها الزمن ، لذلك كان هناك حد 1 غيغابايت من ذاكرة الوصول العشوائي (نعم ، هناك أيضًا شركات تستخدم هذه التقنية ، وتعمل منذ 10 سنوات ، وستعمل بنفس المقدار). في البداية ، كانت هناك رغبة في تقسيم البطاقة إلى أجزاء وتحميلها في ذاكرة الوصول العشوائي حسب الحاجة (كما هو الحال في الملاحين) ، لكنها كانت بطيئة للغاية. ونتيجة لذلك ، تمكنا من إنشاء ما يصل إلى خمسين ميغابايت معقولة.

في OSM ، يتم تمثيل خرائط الطرق كأقسام متجهة من الطريق مع سمات إضافية. في قرارنا ، استخدمنا قوائم المجاورة . حيث تكون القمة نقطة على الخريطة ، وتكون الحواف هي المسارات إلى نقطة مجاورة. من أجل التحسين ، نعتقد أنه يمكن أن يكون هناك أربعة مسارات (تقاطع) بحد أقصى من قمة واحدة. إذا كان هناك أكثر من 4 مسارات ، فأنت بحاجة إلى تقسيم الحافة إلى مسارين إضافيين ، لذلك لدينا دائمًا عدد ثابت من الحواف = 4 لكل نقطة خريطة ، وهذا النهج يسمح لنا بمحاذاة البيانات في الذاكرة ، رغم أنها زائدة عن الحاجة إلى حد ما.

تجدر الإشارة إلى أن الأرض ليست كرة (بشكل غير متوقع) ، ولكنها جيودي ، ولكن لغرض رسم الخرائط يتم تبسيطها إلى كروي أو إهليلجي .

لأغراضنا ، وجدت صيغة لحساب المسافات بين نقطتين على سطح الإهليلجي ، والتي لم أستطع فهم المعنى الأعمق لها ، لكن هذا لا يمنعنا من استخدامها.

كود
function distance(StartLong:Single; StartLat:Single; EndLong:Single; EndLat:Single) : Single; const D2R: Double = 0.017453; // Degrees to Radians Conversion E2: Double = 0.006739496742337; // Square of eccentricity of ellipsoid var fPhimean: Double; // Mean latitude fdLambda: Double; // Longitude difference fAlpha: Double; // Bearing fRho: Double; // Meridional radius of curvature fNu: Double; // Transverse radius of curvature fR: Double; // Radius of spherical earth fz: Double; // Angular distance at centre of spheroid begin fdLambda := (StartLong - EndLong) * D2R; fPhimean := ((StartLat + EndLat) / 2.0) * D2R; fRho := (6378137.0 * (1 - E2)) / Power(1 - E2 * (Power(Sin(fPhimean),2)), 1.5); fNu := 6378137.0 / (Sqrt(1 - E2 * (Sin(fPhimean) * Sin(fPhimean)))); fz := Sqrt(Power(Sin((StartLat - EndLat) * D2R/2.0),2) + Cos(EndLat*D2R) * Cos(StartLat*D2R) * Power(Sin(fdLambda/2.0),2)); fz := 2 * ArcSin(fz); fAlpha := ArcSin(Cos(EndLat * D2R) * Sin(fdLambda) * 1 / Sin(fz)); fR := (fRho * fNu) / ((fRho * Power(Sin(fAlpha),2)) + (fNu * Power(Cos(fAlpha),2))); distance := fz * fR; // 1  1  end; 


بعد إنشاء قاعدة الطريق ، كانت هناك حاجة إلى طبقة مرئية لعرض المنطقة المحيطة بها. ساعد مشروع maperitive هنا ، حيث سمح لنا بتحليل خريطة OSM للمناطق إلى مقاطع مربعة بواسطة طبقات التقريب ، مثل 10 ^ 100 أو Yandex. كانت هناك محاولة للعمل مع خرائط عمالقة الإنترنت ، مما يجعل خريطة المتجهات أعلى طبقة المستعرض ، لكن بسبب قيود الترخيص ، قرروا الرفض. نتيجة لذلك ، أنشأنا قرصًا افتراضيًا وحملنا تفريغًا للبلاط إلى بضع عشرات غيغا بايت هناك ، ولكن كل شيء في متناول اليد ولا يتباطأ. صحيح ، مرة واحدة كل ستة أشهر يجب عليك تحديثها ، وعادة ما يتزامن ذلك مع الحمل الزائد للبطاقات.



لدمج صورة التجانب وخريطة المتجه ، عليك أن تعرف أن البلاط ، Google ، OpenStreetMap ، Bing ، Yahoo تم تمثيلها في إسقاط Mercator (بشكل أكثر دقة WEB MERCATOR ، وهو الإسقاط على الكرة) ، حيث تكون كل طبقة أعمق أكثر تفصيلاً من الطبقة السابقة.



تستخدم Yandex.Maps إسقاط الإهليلجويد لـ Mercator.

لا يهم إذا كان يمكنك إعادة حساب الإحداثيات الجغرافية على مستوى الإسقاط والعكس صحيح.

اخترنا المستوى 17 من التفاصيل كحد أقصى. Closer لا معنى له بسبب زيادة تخزين عدد التجانبات (كل مستوى أكبر بـ 4 مرات من المستوى السابق) ، بالإضافة إلى محتواها المنخفض من المعلومات.

2 ^ 17 * 256 = 33554432 (256 هو حجم حافة التجانب بالبكسل).

كود
 Const size =33554432; //      17  ; center=16777216; //  x  y     ; EXCT=0.081819790992; //        map_type=true; //  :  –    //============================================================= //     function TO_X(X:Single):Integer; begin TO_X := floor(center+size*(x/360)); //  X     Lon; end; //============================================================= //     function TO_Y(Y:Single):Integer; var ls:single; begin ls:=sin(Y*Pi/180); // C ; if map_type then TO_Y := floor(center-atanh(ls)*(size/(2*Pi))) //  Y     Lat   else TO_Y := floor(center-(atanh(ls) - EXCT * atanh(EXCT * ls))*(size/(2*Pi))); //  Y     Lat  ; end; //============================================================= //       function TO_LON(X:Single):Single; begin TO_LON := (X - center) * 360 / size; end; //============================================================= //       function TO_LAT(Y:Single):Single; var g:Double; begin if map_type then //   TO_LAT:= (180 / Pi)* (2 * ArcTan(exp((center - y) * 2 * Pi / size)) - Pi / 2) else begin //   g := (PI/2) - 2 * ArcTan(1 / Exp((20037508.342789 - (y*64) / 53.5865938) / 6378137)); TO_LAT:= 180 / Pi * (g + 0.00335655146887969 * Sin(2 * g) + 0.00000657187271079536 * Sin(4 * g) + 0.00000001764564338702 * Sin(6 * g) + 0.00000000005328478445 * Sin(8 * g)); end; end; //============================================================= 


الآن بعد أن أصبح لدينا الأدوات الأساسية ، يمكننا المتابعة مباشرةً إلى مهمة إنشاء المسار الأمثل. نقوم بتوصيل مرافق التسوق بأقرب حافة في الرسم البياني للطريق ، ثم نبدأ البحث عن أقصر الطرق. للقيام بذلك ، نستخدم مجموعة متنوعة من خوارزمية ديكسترا لتنوعها تفريغ بالتتابع لكل نقطة الزيارة. في الخرج ، نحصل على مصفوفة متقاربة من الحجم (N + 1) * (N + 1) مع ما لا نهاية على القطر الرئيسي (حظر الطوق) ، حيث N هو عدد نقاط الزيارة دون مراعاة نقطة الخروج.

تقوم المصفوفة الناتجة بتخزين الحد الأدنى للمسافة على طول الطرق بين جميع منشآت التسوق ، وهي مشكلة بائع متجول كلاسيكي. نظرًا لأن التعقيد الخوارزمي لمثل هذه المشكلة قد انتهى من القمة ، فقد استخدمنا الطريقة الفرعية والملزمة لحلها. بالنسبة لـ n <15 ، تكون شاملة ؛ وإلا ، فإن التقدير التقريبي يرتبط بعمق. الخيار هو بالتأكيد ليست مثالية ، ولكن العمل تماما.

نتيجة لذلك ، وصلنا إلى طريق قريب من المسافة المثلى مع تقدير بالكيلومترات. إذا لزم الأمر ، يمكن للمشغل تغيير المسار يدويًا لصالح أولوية النقاط الفردية.

يعمل الحل في المؤسسة منذ حوالي 7 سنوات ، بنجاح كبير ، على الرغم من أنه لا يخلو من العيوب ، سواء في الدقة أو في الراحة. تتوافق النتائج مع بيانات تتبع مركبة GPS. في تقديري ، سمح إدخال الخدمات اللوجستية بتوفير 10-12 ٪ من الأموال المخصصة للوقود. تم تصميم البرنامج وإطلاقه ومرافقته من قبل شخص واحد فقط - خادمك المتواضع.

إن قيادتي المحافظة ليست حريصة على "التألق" ، لذلك أقترح مثالًا وهميًا على طريق الانتباه.



بدون التصور ، يكون الحساب أسرع عدة مرات ، وداخل تسوية واحدة ، على الفور تقريبًا.

بعد عدة سنوات ، أحيانًا سلم الحكة للدخول إلى الشفرة ونسخها بتجربة جديدة لمنصة جديدة أكثر حداثة ، لكن حتى الآن لا توجد جدوى اقتصادية.

هذا كل ما أردت أن أخبرك به ، وآمل أن يكون مثيراً للاهتمام.
أعتذر إذا لم أكن دقيقة في مكان ما.

Source: https://habr.com/ru/post/ar437280/


All Articles