Brief introduction to mathematical optimization
Mathematical optimization is at the heart of modern decision making. By representing real-world challenges as mathematical models, it offers a systematic and data-driven approach to solving complex problems. It provides a structured way of balancing competing objectives and constraints, which enables us to find the most efficient or cost-effective solutions in any scenario.
The beauty of mathematical optimization also lies in its versatility. It’s used in areas as diverse as scheduling airline crews, improving production lines, managing financial risk, handling energy systems, and even designing smart cities. When we optimize resource allocation, reduce costs, and enhance performance, we often uncover solutions that might not be intuitive, which has revolutionized multiple industries.
What is GAMS and what are the advantages of Set Based Declarative Algebraic Modeling
The General Algebraic Modeling System (GAMS) is a high-level programming environment specifically designed for creating optimization models. It’s a language that resembles classic mathematical notation, and it allows us to formulate problems in a simple and intuitive way.
GAMS’s distinguishing feature is its set-based declarative algebraic modeling framework, which emphasizes defining what the problem is rather than prescribing how to compute it. This particular approach isn’t just a technicality, it has several advantages:
-
Symbolic and Data-Independent Models: In GAMS, you build pure mathematical models. You construct the algebraic relationship between your variables, parameters, and functions that represent your real-world problem –independently of any one particular dataset. This means that your resulting model is completely symbolic. Then, it’s just a matter of choosing what data to feed your model with, and it will rapidly accommodate without modifications.
-
Simple and Compact Syntax: Because of its declarative style, GAMS models are particularly clean and concise. You can encapsulate decision variables, constraints and objectives in a minimalistic and simple code. This makes your models easy to write, edit, and understand –which is essential when it comes to large-scale projects.
-
Seamless Solver Integration: One of the biggest advantages of GAMS is that you aren’t tied to one solver. Rather, you have the possibility to choose from a wide range of state-of-the-art options, such as Baron, Xpress, Gurobi, and many others. Switching between solvers is as easy as changing a single line of code. And because GAMS is a reseller of commercial solvers with very competitive prices, you have all this access from a single environment. This way, you’re fully equipped to solve very different types of problems, such as linear programming (LP), nonlinear programming (NLP), and mixed-integer programming (MIP).
GAMSPy and Optimizing in Python
We all know Python: it’s one of the most popular programming languages out there –it’s clean, easy to learn, has tons of great libraries and features, and has been widely embraced by both academia and industry. A tool that lets you develop your models in Python with a set-based syntax was an obvious and natural step, which happened last year with the introduction of GAMSPy.
GAMSPy allows you to write and solve optimization problems directly in Python. It’s a tool that combines the powerful GAMS execution system, with the versatile Python language.
Now, GAMSPy isn’t the first optimization tool to embrace Python. Being able to streamline your whole optimization pipeline in a single environment is useful and convenient, and others like Pyomo or GurobiPy, just to name a few, are powerful tools that have been around for some time.
So how does optimizing in Python work? Some solutions have a simple approach: they generate a mathematical model in Python, and then export it as a file that a solver can read. Others build and solve the model directly in Python as an in-memory object. These approaches work, and you can usually find an intuitive solution to get your model running. But, more often than not, they can also lead to significant performance bottlenecks.
Naturally, if you’re willing to put the time and effort to really get into the code, you can develop good solutions. For example, it’s common to develop strategies such as power calls to a C++ backend to create sums or lookups in sparse data sets. These speedups can deliver great performance. But a simple fact remains: the model is still built constraint-by-constraint in Python, which is an inherently slow language.
GAMSPy takes a radically different approach.
Instead of generating the model instances in Python, GAMSPy uses Python mainly as a translator. The model is written in Python, yes, but the actual work is completely offloaded to GAMS. This means that you can write your model in a comfortable, familiar Pythonic way, but leave the job of creating and solving the model instances to GAMS’s powerful and highly optimized backend.
Think of it as building the blueprint in Python but letting GAMS handle the construction.
This difference in approach is critical. By simply generating a .gms file and using GAMS’ optimized machinery to handle the execution, GAMSPy ensures that even the most complex models are generated quickly and efficiently. In simple terms, it’s a method that combines Python with the advantages of set based declarative algebraic modeling and the raw computational power of GAMS.
But why is this difference in approach relevant?
GAMSPy performance
There are many things to take into account when deciding which optimization tool to choose. And performance is definitely high on that list.
With decades of optimization, GAMS’ performance when it comes to generating mathematical models is among the best out there. So how does GAMSPy, our newest release, perform?
Well, first of all it’s important to understand something. While GAMSPy has the advantage of leveraging GAMS’ backend, there’s still a small tradeoff: a communication overhead. This overhead is a natural result of the way GAMSPy and GAMS interact with each other. Every time you execute a command in GAMSPy, Python must communicate this instruction to GAMS, wait for GAMS to process it, and retrieve the result back into Python.
This overhead can be most noticeable in small models, simply because there is a fixed cost to it. However, as model size grows and complexity increases, it becomes less significant. Basically, the heavy lifting done by GAMS overshadows the delays caused by the data transfer.
When we compare GAMSPy performance against GAMS on our full model library (including solving time), we get an average overhead of 27% in our Linux system, and 8% on our Windows system –where GAMS itself takes over most of the total time.
To get a different perspective, we can also compare the time it takes both GAMSPy and GAMS to generate our IJKLM test model (without solving time):
As the graphic shows, the overhead here is between 30% and 50% for large models.
Now, this might sound significant, but actually it’s not. For starters, we are only measuring model generation time here. This means we are not taking solving time into account –which usually takes up most of the total time when it comes to larger models. And second, even if we take this overhead into consideration, how does GAMSPy measure against other optimization tools?
Well, making comparisons with other frameworks and solutions is never straightforward. Defining a set that truly does justice to the test, for example, is a challenge in itself. However, including GAMSPy in our IJKLM test , quickly shows its impressive performance.
As the graphic shows, when paired against other tools –even against our optimized versions of them– GAMSPy delivers a performance that puts it at the top of the table. It’s almost as fast as GAMS.
What’s more, it’s important to point out that while other Python optimization tools can rely heavily on improved coding to enhance performance, GAMSPy’s strategy is fundamentally different. Shifting the workload to GAMS not only boosts the speed of model generation, it also keeps your code simple and clear –something that can be just as valuable in large and complex models.
And that’s not all. If you do like getting into the bolts and nuts of the code, Python offers endless possibilities to enhance GAMSPy’s (as other frameworks’) performance. Being able to use your favorite libraries for data pre and post-processing can speed up your working time significantly. That’s the beauty of Python and having your whole pipeline in a single environment, and we’ll cover more about this in another blog post.
Conclusion and further information
Mathematical optimization plays an important role in solving today’s real-world problems. And tools like GAMS, with its set declarative algebraic framework, simplify the formulation of these problems while ensuring compatibility with multiple solvers. GAMSPy simply takes this approach into the Python ecosystem.
GAMSPy’s unique method to optimization modeling is a big step forward in the world of Python-based tools. By offloading the main computational tasks to GAMS –which is integrated into GAMSPy and doesn’t require a separate installation–, it can achieve a level of performance that is rarely seen in other frameworks. With GAMSPy, you get to use Python to write simple, minimalistic, and easy to follow models, all while ensuring top-notch performance. Just take a look at our GAMSPy model library –you can explore dozens of examples ready to run.
For those in academia, GAMS also offers a unique opportunity to use these tools through its Academic Program . If you’re a student, professor, or researcher, you have access to our technology for free or at highly discounted prices. Our goal is to make advanced modeling and solving techniques accessible to anyone in an educational or research context.
In summary, whether you’re a beginner exploring optimization or an expert seeking efficient solutions, GAMSPy provides the simplicity and raw power you need to write and solve your models. So go ahead and give it a try, all it takes to get started is a simple line:
pip install gamspy