Example



A simple assignment problem will be used to illustrate how XAD works with Mosel to create interactive mathematical programming models.

Here is a screenshot of the application:

XAD/assignment.png

Figure 10.1: Interactive mathematical programming model

The user can modify the preferences by changing the numbers in the input boxes in the upper left corner. After pressing Solve, the results are shown in the diagram. This procedure can be repeated any number of times.

Let's examine the code, piece by piece:

XAD/assign1.png

Here, we tell Mosel that we need to use Xpress-Optimizer (mmxprs) as well as XAD (mmxad) to build this application. We also declare some identifiers to be used later in the model, such as the decision variable array assign.

In the next section:

XAD/assign2.png

We assign some suggested preferences (these will be editable by the user). The objective function Satisfaction reflects the overall sum of preferences depending on whether assignments are made or not. Two sets of constraints, one person per project and one project per person complete the mathematical formulation of this model.

Let's examine the user interface code:

XAD/assign3.png

In the code above, a new group of declarations is used to assign unique ids to various GUI objects. The window is created first, then the XAD objects are created one by one, with id_win as their parent. Note that id_inputs and id_texts are special in the sense that they are used in combination with i and j to create unique ids for more than one item. Also note how the expresion ""+PREF(i,j) actually fills each input object with the corresponding preference rating.

The coordinates and dimensions of all the GUI objects can be derived using the Xpress Application Developer Designer tool, which is a Mosel program (written with XAD) that acts as a What You See Is What You Get GUI editor. Some experimentation with layout may be needed before the end result is satisfactory.

The use of integers as ids for XAD objects facilitates grouping objects in easy to understand and manage categories (such as all the inputs above). The user should take advantage of this feature, especially for large models/applications.

The canvas id_canvas displays the results of our optimization problem. An entire procedure is dedicated to updating this object with the most recent information:

XAD/assign4.png

As a general rule, a canvas should be erased first using XADcanvaserase. After all the drawing is complete, call XADcanvasrefresh to update the contents of the canvas.

The procedure UpdateCanvas draws a grid and then updates each cell based on the optimized values in the assign array. If the assignment is made, a check mark is also drawn in the cell from a bitmap image file. If an assignment is not made, the text in the cell is drawn with a lighter shade of gray to de-emphasize it.

We shall now examine the event handling callback procedure and the code that kick starts the application.

XAD/assign5.png

Three events are of interest to us in this application: When the window opens and when either of the two buttons is pressed.

Two more statements in the Mosel code are of interest. We must ensure that XADseteventcallback is called before opening the window, so that the window can send its events to it. Finally, XADwindowopen opens the window, giving it control over the execution (through events).

Note that when we call XADwindowclose or when we close the window with the mouse, execution of the Mosel code in fact continues with the statement following XADwindowopen (in this case there's nothing else to execute, so the application ends). This means that we should always think of windows as mere components of a Mosel application that temporarily gain control of the Mosel execution through the event handler. Mosel is always in charge and can dismiss a window at any time.

(When developing XAD applications in Xpress-IVE, do not use the Stop feature to end the program execution. This could interrupt the Mosel execution during a system call dealing with the user objects, leaving Mosel and IVE in a corrupt state. Always close all XAD windows instead of using Stop.)

For more instances of XAD applications please refer to the set of examples that accompanies XAD.



If you have any comments or suggestions about these pages, please send mail to docs@dashoptimization.com.