When working with optimization tasks, there may be scenarios where you want to run multiple models concurrently. This can be particularly useful for batch processing or when dealing with large-scale problems that can be divided into independent subproblems. The following Java code demonstrates how to execute multiple Gurobi models in parallel using threads:
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import com.gurobi.gurobi.GRBEnv;
import com.gurobi.gurobi.GRBException;
import com.gurobi.gurobi.GRBModel;
import com.gurobi.gurobi.GRB;
public class ThreadingConcurrentModels {
static final int THREADS = 5;
static List<GRBModel> listModels = new ArrayList<GRBModel>();
private static class ParallelTask implements Runnable {
@Override
public void run() {
try {
GRBEnv env = new GRBEnv();
var name = Thread.currentThread().getName();
System.err.println("starting "+ name);
GRBModel model = null;
model = new GRBModel(env);
model.set(GRB.StringAttr.ModelName, name);
listModels.add(model);
model.addVars(10000, GRB.INTEGER);
model.addConstrs(10000);
model.optimize();
env.dispose();
System.out.println(name + " is finished.");
} catch(GRBException excp) {
System.out.println(excp.getMessage());
}
}
}
public static void main(String[] args) {
Map<Integer, Thread> mapThreads = new HashMap<Integer, Thread>();
int i = 0;
Thread t = null;
for( i = 0; i < THREADS; i++) {
t = new Thread(new ParallelTask(), "Model " + Integer.toString(i));
mapThreads.put(i, t);
t.start();
}
// Wait until all threads are done
boolean bThreadsRunning = true;
while(bThreadsRunning){
bThreadsRunning = false;
for( i = 0; i < THREADS; i++) {
Thread thr = mapThreads.get(i);
bThreadsRunning = thr.isAlive();
if ( bThreadsRunning == true ) {
break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Dispose of model and environment
for (GRBModel model : listModels) {
if ( model != null ) {
model.dispose();
}
}
}
}
Explanation
This code utilizes Java's threading capabilities to run multiple Gurobi models simultaneously. Each thread is responsible for creating and optimizing its own model. Here's a breakdown of the key components:
-
ParallelTask Class: This is a
Runnable
class that defines the task each thread will execute. It creates a newGRBEnv
andGRBModel
, sets up a dummy model, and performs the optimization. They key is to use a separateGRBEnv
for each model becauseGRBEnv
is not thread-safe. -
Main Method: The main method initializes a specified number of threads (
THREADS
) and starts them. It then waits for all threads to finish before disposing of the models and environments. -
Thread Management: The code includes logic to ensure all threads complete before the program exits. This is achieved by periodically checking the status of each thread.
This approach ensures that multiple models can be optimized concurrently, maximizing the utilization of computational resources and potentially reducing overall execution time.
Comments
0 comments
Article is closed for comments.