Я пытаюсь запустить задачу JobShop в Java. Пример для этого не существует в папке examples / java, но он существует в примерах C ++, C# и Python. Поэтому я взял пример C# и преобразовал его в Java. Компилируется нормально, но выдает ошибку компоновщика SWIG. Где я ошибаюсь?
Вот исходный код, который прекрасно компилируется на моей машине:
import com.google.ortools.sat.CpModel;
import com.google.ortools.sat.CpSolver;
import com.google.ortools.sat.CpSolverStatus;
import com.google.ortools.sat.IntVar;
import com.google.ortools.sat.IntervalVar;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* JobShop example.
*
*/
public class JobshopSat {
static class Task {
public Task(int taskId, int jobId, int duration, int machine)
{
TaskId = taskId;
JobId = jobId;
Duration = duration;
Machine = machine;
Name = "T" + taskId + "J" + jobId + "M" + machine + "D" + duration;
}
public int TaskId;
public int JobId;
public int Machine;
public int Duration;
public String Name;
}
//Number of machines.
public final int machinesCount = 3;
//horizon is the upper bound of the start time of all tasks.
public final int horizon = 300;
//this will be set to the size of myJobList variable.
public int jobsCount;
/* Search time limit in milliseconds. if it's equal to 0, then no time limit will be used. */
public final int timeLimitInSeconds = 0;
public static List<List<Task>> myJobList = new ArrayList<List<Task>>();
public void initTaskList() {
List<Task> taskList = new ArrayList<Task>();
taskList.add(new Task(0, 0, 65, 0));
taskList.add(new Task(1, 0, 5, 1));
taskList.add(new Task(2, 0, 15, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 1, 15, 0));
taskList.add(new Task(1, 1, 25, 1));
taskList.add(new Task(2, 1, 10, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 2, 25, 0));
taskList.add(new Task(1, 2, 30, 1));
taskList.add(new Task(2, 2, 40, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 3, 20, 0));
taskList.add(new Task(1, 3, 35, 1));
taskList.add(new Task(2, 3, 10, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 4, 15, 0));
taskList.add(new Task(1, 4, 25, 1));
taskList.add(new Task(2, 4, 10, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 5, 25, 0));
taskList.add(new Task(1, 5, 30, 1));
taskList.add(new Task(2, 5, 40, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 6, 20, 0));
taskList.add(new Task(1, 6, 35, 1));
taskList.add(new Task(2, 6, 10, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 7, 10, 0));
taskList.add(new Task(1, 7, 15, 1));
taskList.add(new Task(2, 7, 50, 2));
myJobList.add(taskList);
taskList = new ArrayList<Task>();
taskList.add(new Task(0, 8, 50, 0));
taskList.add(new Task(1, 8, 10, 1));
taskList.add(new Task(2, 8, 20, 2));
myJobList.add(taskList);
jobsCount = myJobList.size(); // Count
}
public static void main(String[] args) {
JobshopSat jobshopSat = new JobshopSat();
jobshopSat.initTaskList();
CpModel model = new CpModel();
// ----- Creates all intervals and integer variables -----
// Stores all tasks attached interval variables per job.
List<List<IntervalVar>> jobsToTasks = new ArrayList<List<IntervalVar>>(jobshopSat.jobsCount);
List<List<IntVar>> jobsToStarts = new ArrayList<List<IntVar>>(jobshopSat.jobsCount);
List<List<IntVar>> jobsToEnds = new ArrayList<List<IntVar>>(jobshopSat.jobsCount);
// machinesToTasks stores the same interval variables as above, but
// grouped my machines instead of grouped by jobs.
List<List<IntervalVar>> machinesToTasks = new ArrayList<List<IntervalVar>>(jobshopSat.machinesCount);
List<List<IntVar>> machinesToStarts = new ArrayList<List<IntVar>>(jobshopSat.machinesCount);
for (int i = 0; i < jobshopSat.machinesCount; i++) {
machinesToTasks.add(new ArrayList<IntervalVar>());
machinesToStarts.add(new ArrayList<IntVar>());
}
// Creates all individual interval variables.
for (List<Task> job: myJobList) {
jobsToTasks.add(new ArrayList<IntervalVar>());
jobsToStarts.add(new ArrayList<IntVar>());
jobsToEnds.add(new ArrayList<IntVar>());
for (Task task : job) {
IntVar start = model.newIntVar(0, jobshopSat.horizon, task.Name);
IntVar end = model.newIntVar(0, jobshopSat.horizon, task.Name);
IntervalVar oneTask = model.newIntervalVar(start, task.Duration, end, task.Name);
jobsToTasks.get(task.JobId).add(oneTask);
jobsToStarts.get(task.JobId).add(start);
jobsToEnds.get(task.JobId).add(end);
machinesToTasks.get(task.Machine).add(oneTask);
machinesToStarts.get(task.Machine).add(start);
}
}
// ----- Creates model -----
// Creates precedences inside jobs.
for (int j = 0; j < jobsToTasks.size(); ++j) {
for (int t = 0; t < jobsToTasks.get(j).size() - 1; ++t) {
model.addLessOrEqual(jobsToEnds.get(j).get(t), jobsToStarts.get(j).get(t + 1));
// model.Add(jobsToEnds.get(j).get(t) <= jobsToStarts.get(j).get(t + 1));
}
}
// Adds no_overkap constraints on unary resources.
for (int machineId = 0; machineId < jobshopSat.machinesCount; ++machineId) {
IntervalVar[] myArray = new IntervalVar[machinesToTasks.get(machineId).size()];
machinesToTasks.get(machineId).toArray(myArray);
model.addNoOverlap(myArray);
}
// Creates array of end_times of jobs.
IntVar[] allEnds = new IntVar[jobshopSat.jobsCount];
for (int i = 0; i < jobshopSat.jobsCount; i++) {
int sz = jobsToEnds.get(i).size();
allEnds[i] = jobsToEnds.get(i).get(sz-1);
}
// Objective: minimize the makespan (maximum end times of all tasks) of the problem.
IntVar makespan = model.newIntVar(0, jobshopSat.horizon, "makespan");
model.addMaxEquality(makespan, allEnds);
model.minimize(makespan);
// Create the solver.
CpSolver solver = new CpSolver();
// Set the time limit.
if (jobshopSat.timeLimitInSeconds > 0) {
// solver.StringParameters = "max_time_in_seconds:" + jobshopSat.timeLimitInSeconds;
solver.getParameters().setMaxTimeInSeconds(jobshopSat.timeLimitInSeconds);
}
// Solve the problem.
CpSolverStatus status = solver.solve(model);
if (status == CpSolverStatus.OPTIMAL) {
System.out.println("Makespan = " + solver.objectiveValue());
for (int m = 0; m < jobshopSat.machinesCount; ++m)
{
System.out.println("Machine {" + m + "}:");
SortedMap<Long, String> starts = new TreeMap<Long, String>();
for(IntVar var: machinesToStarts.get(m)) {
starts.put(solver.value(var), var.getName());
}
for (long key: starts.keySet()) {
System.out.println(" Task {" + starts.get(key) + "} starts at {" + key + "}");
}
}
}
else
{
System.out.println("No solution found!");
}
}
}
Я собираю и запускаю его из самой верхней папки следующим образом (обратите внимание на это точно так же, как и другие примеры):
anupambagchi:202[or-tools-binary] make build SOURCE=examples/java/JobshopSat.java
mkdir classes/JobshopSat
"/Library/Java/JavaVirtualMachines/openjdk-12.0.1.jdk/Contents/Home/bin/javac" -d classes/JobshopSat \
-cp lib/com.google.ortools.jar:lib/protobuf.jar \
examples/java/JobshopSat.java
rm -f lib/JobshopSat.jar
"/Library/Java/JavaVirtualMachines/openjdk-12.0.1.jdk/Contents/Home/bin/jar" cvf lib/JobshopSat.jar -C classes/JobshopSat .
added manifest
adding: JobshopSat$Task.class(in = 918) (out= 532)(deflated 42%)
adding: JobshopSat.class(in = 6212) (out= 2877)(deflated 53%)
anupambagchi:203[or-tools-binary] make run SOURCE=examples/java/JobshopSat.java
"/Library/Java/JavaVirtualMachines/openjdk-12.0.1.jdk/Contents/Home/bin/java" -Xss2048k -Djava.library.path=lib \
-cp lib/JobshopSat.jar:lib/com.google.ortools.jar:lib/protobuf.jar \
JobshopSat
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.google.ortools.util.mainJNI.new_Domain__SWIG_2(JJ)J
at com.google.ortools.util.mainJNI.new_Domain__SWIG_2(Native Method)
at com.google.ortools.util.Domain.<init>(Domain.java:68)
at com.google.ortools.sat.CpModel.newIntVar(CpModel.java:70)
at JobshopSat.main(JobshopSat.java:132)
make: *** [run] Error 1
Пожалуйста, помогите мне определить проблему. Спасибо.