Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

CPLEX 12.8 - the Generic Callback

737 views

Published on

CPLEX 12.8 introduces a new callback framework, that allows more performance and flexibility.

Published in: Software
  • Be the first to comment

  • Be the first to like this

CPLEX 12.8 - the Generic Callback

  1. 1. © 2017 IBM Corporation CPLEX 12.8: the Generic Callback INFORMS 2017, Houston Daniel Junglas, PhD, Software Scientist, CPLEX Xavier Nodet, Program Manager, CPLEX Optimization Studio
  2. 2. © 2017 IBM Corporation2 WHY CALLBACKS?
  3. 3. © 2017 IBM Corporation3 § CPLEX is black-box: input a problem, get a solution § For many, that’s all well and good § But some need more than this: - Additional information about the search process • Integration into a larger application • Or in a graphical environment - Customization • Drive CPLEX behavior: which variable or node to select • Provide input to CPLEX: heuristic solutions, cuts • Consider constraints outside the model: reject solutions, add lazy constraints § For all these reasons, CPLEX provides callbacks: - From time to time, CPLEX runs a user-specified function - That function can query CPLEX, and/or change its state
  4. 4. © 2017 IBM Corporation4 WHY NEW CALLBACKS?
  5. 5. © 2017 IBM Corporation5 History of callbacks in CPLEX 1988
  6. 6. © 2017 IBM Corporation6 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... History of callbacks in CPLEX
  7. 7. © 2017 IBM Corporation7 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... History of callbacks in CPLEX
  8. 8. © 2017 IBM Corporation8 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded History of callbacks in CPLEX 1996 Parallel MIP
  9. 9. © 2017 IBM Corporation9 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe History of callbacks in CPLEX
  10. 10. © 2017 IBM Corporation10 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe Using callbacks defaults to single- threaded mode Backward compatibility History of callbacks in CPLEX
  11. 11. © 2017 IBM Corporation11 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe Using callbacks defaults to single- threaded mode Dynamic Search is introduced Backward compatibility History of callbacks in CPLEX 2007
  12. 12. © 2017 IBM Corporation12 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe Using callbacks defaults to single- threaded mode Dynamic Search is introduced (Slightly) different from traditional B&C Query/control callbacks incompatible Backward compatibility History of callbacks in CPLEX
  13. 13. © 2017 IBM Corporation13 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe Using callbacks defaults to single- threaded mode Dynamic Search is introduced (Slightly) different from traditional B&C Query/control callbacks incompatible Backward compatibility Using callbacks disables dynamic search History of callbacks in CPLEX -20%
  14. 14. © 2017 IBM Corporation14 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe Using callbacks defaults to single- threaded mode Dynamic Search is introduced (Slightly) different from traditional B&C Query/control callbacks incompatible Backward compatibility Using callbacks disables dynamic search Monitor progress, compatible with dynamic search History of callbacks in CPLEX l Info callback
  15. 15. © 2017 IBM Corporation15 l Query/diagnostic callbacks Monitor progress - Iteration count - Node count - ... l Control callbacks Control MIP search - Branching - Heuristics - Node selection - ... CPLEX becomes multi-threaded Callbacks in existing applications may not be thread-safe Using callbacks defaults to single- threaded mode Dynamic Search is introduced (Slightly) different from traditional B&C Query/control callbacks incompatible Backward compatibility Using callbacks disables dynamic search l Info callback Monitor progress, compatible with dynamic search History of callbacks in CPLEX
  16. 16. © 2017 IBM Corporation16 “Artificial” limitations for backward compatibility • Callbacks default to single-threaded mode • Callbacks disable dynamic search
  17. 17. © 2017 IBM Corporation17 User feedback • Empty callback is not the same as no callback • Some callbacks not flexible enough • ... “Artificial” limitations for backward compatibility • Callbacks default to single-threaded mode • Callbacks disable dynamic search
  18. 18. © 2017 IBM Corporation18 User feedback • Empty callback is not the same as no callback • Some callbacks not flexible enough • ... Experience of CPLEX developers • Limited usability • Some callbacks not used by anybody • ... “Artificial” limitations for backward compatibility • Callbacks default to single-threaded mode • Callbacks disable dynamic search
  19. 19. © 2017 IBM Corporation19 User feedback • Empty callback is not the same as no callback • Some callbacks not flexible enough • ... Experience of CPLEX developers • Limited usability • Some callbacks not used by anybody • ... Create a new callback framework “Artificial” limitations for backward compatibility • Callbacks default to single-threaded mode • Callbacks disable dynamic search • Supports everything currently in CPLEX • Addresses feedback gathered over the last >20 years • No issues with backward compatibility • Support new and legacy framework for some versions (but don't allow mixing)
  20. 20. © 2017 IBM Corporation20 THE GENERIC CALLBACK
  21. 21. © 2017 IBM Corporation21 Design principles § No callback = empty callback = query callback = no path change § Don’t try to hide the details: - Queries usually return thread-local information - Callbacks may be called in parallel, are expected to be thread-safe - Callbacks must be ready for no node LP, no tree, etc. § Allows more flexibility, and behavior that’s easy to specify § Only one type of callback function § Called in different contexts § Attached to the model (CPXLPptr),not the environment (CPXENVptr) § No access to the presolved model
  22. 22. © 2017 IBM Corporation22 Design principles § No callback = empty callback = query callback = no path change § Don’t try to hide the details: - Queries usually return thread-local information - Callbacks may be called in parallel, are expected to be thread-safe - Callbacks must be ready for no node LP, no tree, etc. § Allows more flexibility, and predictable behavior § Only one type of callback function § Called in different contexts § Attached to the model (CPXLPptr),not the environment (CPXENVptr) § No access to the presolved model Caveat: • Not yet for continuous problems, where legacy callbacks are working fine • Not everything is available in the generic callback (no branch, solve, node select): tell us if you need them!
  23. 23. © 2017 IBM Corporation23 Features § Monitor progress - Node and iteration counts - Best bound - Best solution (aka incumbent) - ... § Post feasible (partial) solutions, found by your heuristics § Post cuts, to dynamically tighten the formulation § Reject candidate solutions, with or without providing a lazy constraint
  24. 24. © 2017 IBM Corporation24 Features § Monitor progress - Node and iteration counts - Best bound - Best solution (aka incumbent) - ... § Post feasible (partial) solutions, found by your heuristics § Post cuts, to dynamically tighten the formulation § Reject candidate solutions, with or without providing a lazy constraint Unless otherwise mentioned, all actions can be performed from any context!
  25. 25. © 2017 IBM Corporation25 C API, EXAMPLE
  26. 26. © 2017 IBM Corporation26 Based on 3 objects (here for C, other APIs are very similar)
  27. 27. © 2017 IBM Corporation27 Based on 3 objects (here for C, other APIs are very similar) l Callback function int mycallback(CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user); int CPXXcallbacksetfunc(CPXENVptr env, CPXLPptr lp, CPXLONG contextmask, CPXCALLBACKFUNC callback, void *user); contextmask/contextid: context in which callback is invoked callback: the callback function, shared between all threads and all contexts user: user data, passed verbatim to callback
  28. 28. © 2017 IBM Corporation28 Based on 3 objects (here for C, other APIs are very similar) l Callback function int mycallback(CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user); int CPXXcallbacksetfunc(CPXENVptr env, CPXLPptr lp, CPXLONG contextmask, CPXCALLBACKFUNC callback, void *user); contextmask/contextid: context in which callback is invoked callback: the callback function, shared between all threads and all contexts user: user data, passed verbatim to callback l Callback context id/mask specifies when to invoke the callback → bitmask to CPXXcallbacksetfunc specifies in which context callback is invoked → single value passed to mycallback THREAD_UP = 0x02 THREAD_DOWN = 0x04 LOCAL_PROGRESS = 0x08 GLOBAL_PROGRESS = 0x10 CANDIDATE = 0x20 RELAXATION = 0x40
  29. 29. © 2017 IBM Corporation29 Based on 3 objects (here for C, other APIs are very similar) l Callback function int mycallback(CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user); int CPXXcallbacksetfunc(CPXENVptr env, CPXLPptr lp, CPXLONG contextmask, CPXCALLBACKFUNC callback, void *user); contextmask/contextid: context in which callback is invoked callback: the callback function, shared between all threads and all contexts user: user data, passed verbatim to callback l Callback context id/mask specifies when to invoke the callback → bitmask to CPXXcallbacksetfunc specifies in which context callback is invoked → single value passed to mycallback THREAD_UP = 0x02 THREAD_DOWN = 0x04 LOCAL_PROGRESS = 0x08 GLOBAL_PROGRESS = 0x10 CANDIDATE = 0x20 RELAXATION = 0x40 l Callback context handle to interact with CPLEX from a callback CPXXcallbackgetincumbent(context, …) CPXXcallbackrejectcandidate(context, …) CPXXcallbackabort(context, ...)
  30. 30. © 2017 IBM Corporation30 Short example progress display LProunding heuristic
  31. 31. © 2017 IBM Corporation31 Short example callbackfunctionregister progress display LProunding heuristic
  32. 32. © 2017 IBM Corporation32 Short example int callback (CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user) { switch (contextid) { case CPX_CALLBACKCONTEXT_RELAXATION: case CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS: } return 0; } CPXDIM cols = CPXXgetnumcols(env, lp); CPXXcallbacksetfunc(env, lp, CPX_CALLBACKCONTEXT_RELAXATION | CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS, callback, &cols); CPXXmipopt(env, lp); callbackfunctionregister progress display LProunding heuristic
  33. 33. © 2017 IBM Corporation33 Short example int callback (CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user) { switch (contextid) { case CPX_CALLBACKCONTEXT_RELAXATION: CPXDIM cols = *(CPXDIM)user; double* ind = malloc(sizeof (double) * cols); double* x = malloc(sizeof (double) * cols); CPXXcallbackgetrelaxationpoint(context, x, 0, cols – 1); for (j = 0; j < cols; ++j) { ind[j] = j; x[j] = round(x[j]); } CPXXcallbackpostheursoln(context, cols, ind, x, CPXCALLBACKSOLUTION_CHECKFEAS); free(x); break; case CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS: } return 0; } CPXDIM cols = CPXXgetnumcols(env, lp); CPXXcallbacksetfunc(env, lp, CPX_CALLBACKCONTEXT_RELAXATION | CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS, callback, &cols); CPXXmipopt(env, lp); callbackfunctionregister progress display LProunding heuristic
  34. 34. © 2017 IBM Corporation34 Short example int callback (CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user) { switch (contextid) { case CPX_CALLBACKCONTEXT_RELAXATION: case CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS: CPXXcallbackgetintinfo(context, CPXCALLBACKINFO_FEASIBLE, &feasible); if ( feasible ) CPXXcallbackgetdblinfo(context, CPXCALLBACKINFO_BEST_SOL, &primal); else primal = INF; CPXXcallbackgetdblinfo(context, CPXCALLBACKINFO_BEST_BND, &dual); printf (“Current bounds: %f, %fn”, dual, primal); break; } return 0; } CPXDIM cols = CPXXgetnumcols(env, lp); CPXXcallbacksetfunc(env, lp, CPX_CALLBACKCONTEXT_RELAXATION | CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS, callback, &cols); CPXXmipopt(env, lp); callbackfunctionregister LProunding heuristic progress display
  35. 35. © 2017 IBM Corporation35 Short example int callback (CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *user) { switch (contextid) { case CPX_CALLBACKCONTEXT_RELAXATION: CPXDIM cols = *(CPXDIM)user; double* ind = malloc(sizeof (double) * cols); double* x = malloc(sizeof (double) * cols); CPXXcallbackgetrelaxationpoint(context, x, 0, cols – 1); for (j = 0; j < cols; ++j) { ind[j] = j; x[j] = round(x[j]); } CPXXcallbackpostheursoln(context, cols, ind, x, CPXCALLBACKSOLUTION_CHECKFEAS); free(x); break; case CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS: CPXXcallbackgetintinfo(context, CPXCALLBACKINFO_FEASIBLE, &feasible); if ( feasible ) CPXXcallbackgetdblinfo(context, CPXCALLBACKINFO_BEST_SOL, &primal); else primal = INF; CPXXcallbackgetdblinfo(context, CPXCALLBACKINFO_BEST_BND, &dual); printf (“Current bounds: %f, %fn”, dual, primal); break; } return 0; } CPXDIM cols = CPXXgetnumcols(env, lp); CPXXcallbacksetfunc(env, lp, CPX_CALLBACKCONTEXT_RELAXATION | CPX_CALLBACKCONTEXT_GLOBAL_PROGRESS, callback, &cols); CPXXmipopt(env, lp); LProunding heuristic progress display callbackfunctionregister
  36. 36. © 2017 IBM Corporation36 l THREAD_UP l THREAD_DOWN l LOCAL_PROGRESS l GLOBAL_PROGRESS l CANDIDATE l THREAD_UP l RELAXATION Invoked when CPLEX has found a new candidate integer feasible solution. Callback may reject that solution (with or without cuts). Monitor thread-local progress (see later) Invoked when CPLEX has an optimal solution to a node relaxation available Invoked when CPLEX activates a new thread only a limited set of actions is supported allows user to initialize thread-local callback data Counterpart to THREAD_UP Monitor global solution progress (see later) Callback contexts
  37. 37. © 2017 IBM Corporation37 LOCAL OR GLOBAL?
  38. 38. © 2017 IBM Corporation38 l best solution l best bound l cut pool l lazy constraint pool l ... Information model in CPLEX and callbacks
  39. 39. © 2017 IBM Corporation39 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Information model in CPLEX and callbacks
  40. 40. © 2017 IBM Corporation40 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Thread-local information Information model in CPLEX and callbacks
  41. 41. © 2017 IBM Corporation41 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Thread-local information snapshot l best solution l best bound l cut pool l lazy constraint pool l ... Information model in CPLEX and callbacks
  42. 42. © 2017 IBM Corporation42 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Thread-local information snapshot search l best solution l best bound l cut pool l lazy constraint pool l ... l best solution l best bound l cut pool l lazy constraint pool l ... Information model in CPLEX and callbacks
  43. 43. © 2017 IBM Corporation43 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Thread-local information snapshot – May only be valid in thread – Can be observed only in callbackssearch l best solution l best bound l cut pool l lazy constraint pool l ... l best solution l best bound l cut pool l lazy constraint pool l ... Information model in CPLEX and callbacks
  44. 44. © 2017 IBM Corporation44 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Thread-local information snapshot synchronize – May only be valid in thread – Can be observed only in callbackssearch l best solution l best bound l cut pool l lazy constraint pool l ... l best solution l best bound l cut pool l lazy constraint pool l ... Information model in CPLEX and callbacks
  45. 45. © 2017 IBM Corporation45 l best solution l best bound l cut pool l lazy constraint pool l ... – Globally valid – What user can query after CPLEX returns Global information Thread-local information snapshot synchronize – May only be valid in thread – Can be observed only in callbackssearch → Each thread works with its own copy of data/information → Synchronizes with global information l best solution l best bound l cut pool l lazy constraint pool l ... l best solution l best bound l cut pool l lazy constraint pool l ... Information model in CPLEX and callbacks
  46. 46. © 2017 IBM Corporation46 Information model in CPLEX and callbacks Example with callback: best solution during multi-threaded branch and bound
  47. 47. © 2017 IBM Corporation47 Best solution (z*, x*) Information model in CPLEX and callbacks Example with callback: best solution during multi-threaded branch and bound
  48. 48. © 2017 IBM Corporation48 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS Information model in CPLEX and callbacks Example with callback: best solution during multi-threaded branch and bound
  49. 49. © 2017 IBM Corporation49 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS (z*, x*) LOCAL_PROGRESS Information model in CPLEX and callbacks Pick an open node Example with callback: best solution during multi-threaded branch and bound
  50. 50. © 2017 IBM Corporation50 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS (z*, x*) (z*, x*) LOCAL_PROGRESS RELAXATION Information model in CPLEX and callbacks Pick an open node Solve relaxation Example with callback: best solution during multi-threaded branch and bound
  51. 51. © 2017 IBM Corporation51 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS (z*, x*) (z*, x*) (z*, x*) LOCAL_PROGRESS RELAXATION Information model in CPLEX and callbacks Pick an open node Solve relaxation Create child nodes Example with callback: best solution during multi-threaded branch and bound
  52. 52. © 2017 IBM Corporation52 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS (z*, x*) (z*, x*) (z*, x*) LOCAL_PROGRESS RELAXATION (z*, x*) (z*, x*) LOCAL_PROGRESS Information model in CPLEX and callbacks Pick an open node Solve relaxation Create child nodes Example with callback: best solution during multi-threaded branch and bound
  53. 53. © 2017 IBM Corporation53 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS (z*, x*) (z*, x*) (z*, x*) LOCAL_PROGRESS RELAXATION (z*, x*) (z*, x*) LOCAL_PROGRESS (z*, x*) CANDIDATE Information model in CPLEX and callbacks Pick an open node Solve relaxation Create child nodes Process integer feasible solution Example with callback: best solution during multi-threaded branch and bound
  54. 54. © 2017 IBM Corporation54 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS (z*, x*) (z*, x*) (z*, x*) LOCAL_PROGRESS RELAXATION (z*, x*) (z*, x*) LOCAL_PROGRESS (z*, x*) CANDIDATE Information model in CPLEX and callbacks Pick an open node Solve relaxation Create child nodes Process integer feasible solution Example with callback: best solution during multi-threaded branch and bound
  55. 55. © 2017 IBM Corporation55 Best solution (z*, x*) (z*, x*) GLOBAL_PROGRESS Pick an open node Solve relaxation (z*, x*) (z*, x*) (z*, x*) LOCAL_PROGRESS RELAXATION Create child nodes (z*, x*) (z*, x*) LOCAL_PROGRESS (z*, x*) CANDIDATE Process integer feasible solution Information model in CPLEX and callbacks Example with callback: best solution during multi-threaded branch and bound
  56. 56. © 2017 IBM Corporation56 Callbacks and speculative search CPLEX may launch threads to speculatively run some algorithms e.g: additional search tasks while root LP is solved Speculative tasks may be interrupted before complete Their results may even be ignored → Anything passed to CPLEX in such a task may be dropped/ignored (heuristic solutions, lazy constraints, user cuts, ...) → Any information reported by CPLEX in such tasks may have to be discarded as well → Thread-local information reported in callback may not make it into globally valid information
  57. 57. © 2017 IBM Corporation57 Callbacks and speculative search CPLEX may launch threads to speculatively run some algorithms e.g: additional search tasks while root LP is solved Speculative tasks may be interrupted before complete Their results may even be ignored → Anything passed to CPLEX in such a task may be dropped/ignored (heuristic solutions, lazy constraints, user cuts, ...) → Any information reported by CPLEX in such tasks may have to be discarded as well → Thread-local information reported in callback may not make it into globally valid information GLOBAL_PROGRESS Other contexts information reported by CPLEX Globally valid May not be globally valid (e.g., best bound may be “too good”)
  58. 58. © 2017 IBM Corporation58 Callbacks and speculative search CPLEX may launch threads to speculatively run some algorithms e.g: additional search tasks while root LP is solved Speculative tasks may be interrupted before complete Their results may even be ignored → Anything passed to CPLEX in such a task may be dropped/ignored (heuristic solutions, lazy constraints, user cuts, ...) → Any information reported by CPLEX in such tasks may have to be discarded as well → Thread-local information reported in callback may not make it into globally valid information GLOBAL_PROGRESS Other contexts information reported by CPLEX Globally valid May not be globally valid (e.g., best bound may be “too good”) information submitted to CPLEX (cuts, lazy constraints ...) Can be used by CPLEX May have to be discarded
  59. 59. © 2017 IBM Corporation59 Callbacks and speculative search CPLEX may launch threads to speculatively run some algorithms e.g: additional search tasks while root LP is solved → Anything passed to CPLEX in such a task may be dropped/ignored (heuristic solutions, lazy constraints, user cuts, ...) → Any information reported by CPLEX in such tasks may have to be discarded as well → Thread-local information reported in callback may not make it into globally valid information GLOBAL_PROGRESS Other contexts information reported by CPLEX Globally valid May not be globally valid (e.g., best bound may be “too good”) information submitted to CPLEX (cuts, lazy constraints ...) Can be used by CPLEX May have to be discarded Invoked with global lock held Invoked in parallel Speculative tasks may be interrupted before complete Their results may even be ignored
  60. 60. © 2017 IBM Corporation60 SUMMARY
  61. 61. © 2017 IBM Corporation61 § With the generic callback in CPLEX 12.8, you get - A simpler framework - More performance - More flexibility Latest news about CPLEX Optimization Studio http://ibm.co/2wv70gR Thank You! Don’t forget about Benders and Modeling Assistance…
  62. 62. © 2017 IBM Corporation63 Legal Disclaimer • © IBM Corporation 2017. All Rights Reserved. • The information contained in this publication is provided for informational purposes only. While efforts were made to verify the completeness and accuracy of the information contained in this publication, it is provided AS IS without warranty of any kind, express or implied. In addition, this information is based on IBM’s current product plans and strategy, which are subject to change by IBM without notice. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, this publication or any other materials. Nothing contained in this publication is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software. • References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or capabilities referenced in this presentation may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way. Nothing contained in these materials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you will result in any specific sales, revenue growth or other results. • Performance is based on measurements and projections using standard IBM benchmarks in a controlled environment. The actual throughput or performance that any user will experience will vary depending upon many factors, including considerations such as the amount of multiprogramming in the user's job stream, the I/O configuration, the storage configuration, and the workload processed. Therefore, no assurance can be given that an individual user will achieve results similar to those stated here. • IBM, the IBM logo, CPLEX Optimizer, CPLEX Optimization Studio are trademarks of International Business Machines Corporation in the United States, other countries, or both. Unyte is a trademark of WebDialogs, Inc., in the United States, other countries, or both.

×