أوبتيم جيه

OptimJ هو إضافة للغة Java تدعم كتابة نماذج التحسين وتجريدات معالجة البيانات الضخمة. طُوّرت هذه الإضافات والمنتج الخاص الذي يُنفّذها بواسطة شركة Ateji التي أفلست في سبتمبر 2011. [ 1 ] يهدف OptimJ إلى توفير تدوين جبري واضح وموجز لنمذجة التحسين، وإزالة عوائق التوافق بين أدوات نمذجة التحسين وأدوات برمجة التطبيقات، وإتاحة تقنيات هندسة البرمجيات، مثل البرمجة الكائنية ودعم بيئات التطوير المتكاملة الحديثة، لخبراء التحسين.

تتوافق نماذج OptimJ مباشرةً مع شفرة مصدر Java، ومكتبات Java الموجودة مثل الوصول إلى قواعد البيانات، والاتصال ببرنامج Excel، والواجهات الرسومية. كما يتوافق OptimJ مع أدوات التطوير مثل Eclipse وCVS وJUnit وJavaDoc. يتوفر OptimJ مجانًا مع صيغ الملفات التالية: lp_solve وglpk وLP وMPS، ويدعم أيضًا صيغ الملفات التجارية التالية: MOSEK وIBM ILOG CPLEX Optimization Studio.

مفاهيم اللغة

يجمع OptimJ بين مفاهيم لغات البرمجة الإجرائية الموجهة للكائنات ومفاهيم لغات النمذجة الجبرية لحل مسائل التحسين. سنستعرض هنا مفاهيم التحسين المضافة إلى لغة جافا، بدءًا بمثال عملي.

مثال على تلوين الخريطة

تهدف مسألة تلوين الخرائط إلى تلوين الخريطة بحيث يكون للمناطق التي تشترك في حدود مشتركة ألوان مختلفة. ويمكن التعبير عنها في OptimJ كما يلي.

أمثلة على الحزم ؛// نموذج بسيط لمشكلة تلوين الخريطة public model SimpleColoring solver lpsolve { // الحد الأقصى لعدد الألوان int nbColors = 4 ;// متغيرات القرار تحمل لون كل دولة var int belgium in 1 .. nbColors ; var int denmark in 1 .. nbColors ; var int germany in 1 .. nbColors ;// يجب أن يكون للدول المجاورة قيود لونية مختلفة { بلجيكا != ألمانيا ؛ ألمانيا != الدنمارك ؛ }// نقطة دخول رئيسية لاختبار نموذجنا public static void main ( String [] args ) { // إنشاء نسخة من النموذج SimpleColoring m = new SimpleColoring ();// حلها m.extract ( ); m.solve ( ) ;// طباعة الحلول System.out.println ( " بلجيكا : " + m.value ( m.belgium ) ) ; System.out.println ( " الدنمارك : " + m.value ( m.denmark ) ) ; System.out.println ( " ألمانيا : " + m.value ( m.germany ) ) ; } }

سيلاحظ القراء المطلعون على لغة جافا تشابهاً كبيراً مع هذه اللغة. في الواقع، تُعدّ OptimJ امتداداً محافظاً للغة جافا: فكل برنامج جافا صالح هو أيضاً برنامج OptimJ صالح وله نفس السلوك.

يُظهر مثال تلوين الخريطة هذا أيضًا ميزات خاصة بالتحسين ليس لها مكافئ مباشر في جافا، والتي تم تقديمها بواسطة الكلمات الرئيسية model، var، constraints.

مفاهيم خاصة ببحوث العمليات

نماذج

النموذج هو امتداد لفئة جافا، ويمكن أن يحتوي ليس فقط على الحقول والأساليب، بل أيضًا على القيود ودالة الهدف. يُعرَّف النموذج باستخدام modelالكلمة المفتاحية `model`، ويتبع نفس قواعد تعريف الفئات. يجب ربط النموذج غير المجرد بمُحلِّل، يُعرَّف باستخدام الكلمة المفتاحية `solve` solver. تحدد إمكانيات المُحلِّل نوع القيود التي يمكن التعبير عنها في النموذج؛ فعلى سبيل المثال، لا يسمح مُحلِّل المعادلات الخطية مثل `lp solve` إلا بالقيود الخطية.

نموذج عام SimpleColoring محلل lpsolve

متغيرات القرار

توفر اللغات الإجرائية مثل جافا مفهوم المتغيرات الإجرائية ، والتي تمثل بشكل أساسي مواقع الذاكرة التي يمكن الكتابة إليها والقراءة منها.

يُقدّم OptimJ أيضًا مفهوم متغير القرار، الذي يُمثّل أساسًا كميةً مجهولةً يُراد البحث عن قيمتها. حلّ مسألة التحسين هو مجموعة من القيم لجميع متغيرات القرار الخاصة بها، والتي تُراعي قيود المسألة؛ فبدون متغيرات القرار، لا يُمكن التعبير عن مسائل التحسين. مصطلح "متغير القرار" مُستمدّ من مجتمع التحسين، لكنّ متغيرات القرار في OptimJ تُشابه مفهوم المتغيرات المنطقية في لغات البرمجة المنطقية مثل Prolog.

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

// نوع متغير لنوع بيانات أساسي في جافا var int x ;// نوع متغير لفئة معرفة من قبل المستخدم var MyClass y ;

في مثال تلوين الخريطة، تم تقديم متغيرات القرار مع نطاق القيم التي يمكن أن تأخذها.

var int germany in 1 .. nbColors ;

هذا مجرد اختصار يعادل وضع قيد على المتغير.

قيود

تُعبّر القيود عن الشروط التي يجب أن تتحقق في أي حل للمسألة. ويمكن أن يكون القيد أي تعبير منطقي في لغة جافا يتضمن متغيرات قرار.

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

القيود { بلجيكا != ألمانيا ؛ ألمانيا != الدنمارك ؛ }

المعامل !=هو معامل عدم المساواة القياسي في لغة جافا.

تأتي القيود عادةً على شكل مجموعات ويمكن تحديدها كمياً باستخدام forallعامل التشغيل. على سبيل المثال، بدلاً من سرد جميع البلدان وجيرانها بشكل صريح في شفرة المصدر، قد يكون لدى المرء مصفوفة من البلدان، ومصفوفة من متغيرات القرار التي تمثل لون كل بلد، ومصفوفة boolean[][] neighboringأو دالة منطقية (دالة منطقية) boolean isNeighbor().

القيود { لكل ( الدولة c1 : الدول ، الدولة c2 : الدول ، : isNeighbor ( c1 ، c2 )) { اللون [ c1 ] != اللون [ c2 ] ؛ } }

Country c1 : countriesهو مولد: يقوم بالتكرار c1على جميع القيم في المجموعة countries.

:isNeighbor(c1,c2):هو مرشح: فهو يحتفظ فقط بالقيم التي تم إنشاؤها والتي يكون الشرط صحيحًا بالنسبة لها ( يمكن قراءة الرمز على أنه "إذا").

بافتراض أن المصفوفة countriesتحتوي على belgium، germanyو denmark، وأن الشرط isNeighborيعود trueللأزواج ( Belgium ، Germany) ​​و ( Germany، Denmark)، فإن هذا الكود يعادل كتلة القيود في مثال تلوين الخريطة الأصلي.

أهداف

اختيارياً، عندما يصف نموذج ما مشكلة تحسين، يمكن تحديد دالة الهدف المراد تقليلها أو زيادتها في النموذج.

مفاهيم عامة

المفاهيم العامة هي مفاهيم برمجية لا تقتصر على مشاكل بحوث العمليات، بل تُناسب أي نوع من أنواع تطوير التطبيقات. تُسهّل هذه المفاهيم، التي أضافها OptimJ إلى لغة Java، التعبير عن نماذج بحوث العمليات أو تجعلها أكثر إيجازًا. غالبًا ما تكون هذه المفاهيم موجودة في لغات النمذجة القديمة، مما يوفر لخبراء بحوث العمليات طريقة مألوفة للتعبير عن نماذجهم.

المصفوفات الترابطية

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

int [ String ] age ;

النوع int[String]الذي يشير إلى مصفوفة intمفهرسة بواسطة String. الوصول إلى مصفوفات OptimJ باستخدام صيغة Java القياسية:

العمر [ "ستيفان" ] = 37 ؛ س = العمر [ "ليندا" ] ؛

تُستخدم المصفوفات الترابطية بكثرة في صياغة مسائل التحسين. وتُعدّ مصفوفات OptimJ الترابطية مفيدة للغاية عند ربطها بصيغة التهيئة الخاصة بها. ويمكن تحديد القيم الأولية في تعريف مقصود ، كما يلي:

int [ String ] age = { "Stephan" -> 37 , "Lynda" -> 29 };

أو يمكن تقديمها بتعريف موسع ، كما في:

int [ String ] length [ String name : names ] = name.length ( ) ;

length[i]هنا يتم تهيئة كل مدخل من المدخلات بـ names[i].length().

تهيئة موسعة

المجموعات

تُعدّ المجموعات (Tuples) شائعة الاستخدام في الحوسبة، لكنها غائبة عن معظم لغات البرمجة الشائعة، بما في ذلك جافا. يوفر OptimJ مفهومًا للمجموعات على مستوى اللغة، وهو مفهوم مفيد جدًا كمؤشرات عند استخدامه مع المصفوفات الترابطية.

(: int , String :) myTuple = new (: 3 , "Three" :); String s = myTuple # 1 ;

يتم كتابة أنواع الصفوف وقيم الصفوف بين (:و :).

نطاقات

فهم المقروء

التعبيرات المترابطة ، والتي تُسمى أيضًا عمليات التجميع أو الاختزال، هي تعبيرات OptimJ تُوسّع عملية ثنائية مُعطاة على مجموعة من القيم. ومن الأمثلة الشائعة على ذلك عملية الجمع.

// مجموع جميع الأعداد الصحيحة من 1 إلى 10 int k = sum { i | int i in 1 .. 10 };

هذا التركيب مشابه جدًا لترميز الجمع الكبير سيجما المستخدم في الرياضيات، مع بناء جملة متوافق مع لغة جافا.

يمكن أيضًا استخدام التعبيرات المترابطة لإنشاء مجموعات، مثل القوائم أو المجموعات أو المجموعات المتعددة أو الخرائط:

// مجموعة جميع الأعداد الصحيحة من 1 إلى 10 HashSet <Integer> s = ` hashSet ( ) { i | int i in 1..10 } ;

يمكن أن يكون لتعبيرات الفهم تعبير عشوائي كهدف، كما في:

// مجموع جميع مربعات الأعداد الصحيحة من 1 إلى 10 int k = sum { i * i | int i in 1 .. 10 };

ويمكن أن تحتوي أيضاً على عدد غير محدود من المولدات والمرشحات:

// مجموع جميع الدوال f(i,j)، حيث 0<=i<10، 1<=j<=10 و i!=j int k = sum { f ( i , j ) | int i : 10 , int j : 1 .. 10 , : i != j }

لا يقتصر تطبيق الفهم على القيم العددية فقط. إن فهم بناء المجموعات أو المجموعات المتعددة، وخاصةً عند دمجه مع صفوف السلاسل النصية، يُمكّن من التعبير عن استعلامات مشابهة جدًا لاستعلامات قواعد بيانات SQL:

// تحديد الاسم من قائمة الأشخاص حيث العمر > 18 ` multiSet (){ p . name | Person p : persons , : p . age > 18 }

في سياق نماذج التحسين، توفر تعبيرات الفهم طريقة موجزة ومعبرة لمعالجة بيانات الإدخال وتنظيفها، وتنسيق بيانات الإخراج.

بيئة التطوير

يتوفر OptimJ كإضافة لبرنامج Eclipse. يقوم المترجم بتنفيذ ترجمة من المصدر إلى المصدر من OptimJ إلى Java القياسية، مما يوفر توافقًا فوريًا مع معظم أدوات التطوير في بيئة Java.

واجهة المستخدم الرسومية OptimJ والنمذجة السريعة

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

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

توفر واجهة المستخدم الرسومية لبرنامج OptimJ، التي يتم إنشاؤها بواسطة المُصرّف، على خبير بحوث العمليات عناء كتابة جميع التعليمات البرمجية اللازمة لربط المكتبات الرسومية بالبيانات. كما أنها تُمكّن من إنشاء نماذج أولية سريعة، من خلال توفير تلميحات بصرية فورية حول بنية البيانات.

يُقدّم جزء آخر من واجهة المستخدم الرسومية لبرنامج OptimJ تقارير إحصائيات الأداء في الوقت الفعلي من المُحلِّل. يُمكن استخدام هذه المعلومات لفهم مشاكل الأداء وتحسين وقت الحل. وهي متاحة حاليًا فقط لوظيفة lp_solve.

الحلول المدعومة

يتوفر برنامج OptimJ مجانًا مع تنسيقات ملفات lp_solve و glpk و LP أو MPS، كما يدعم أيضًا برامج الحلول التجارية التالية: Mosek و IBM ILOG CPLEX Optimization Studio.

مراجع

  1. "أتيجي مغلق" . تم الاطلاع عليه بتاريخ 11 يناير 2012 .