B4J Question Google OR-Tools

Johan Schoeman

Expert
Licensed User
Longtime User
Did you manage to find a solution using OR-Tools?
OK - have sort of figured it out after a number of attempts:

1. Have found zip file "or-tools_x64_VisualStudio2022_java_v9.12.4544.zip" on the web
2. Used 7-zip to open it
3. inside the archive there is a folder called ortools-win32-x86-64-9.12.4544.jar
4. Just click on it and then click on folder "ortools-win32-x86-64"
5. Inside this folder are the following *.dll files.

1753606542707.png


6. While you have this open in 7-zip, open your "C:\Windows\System32" folder, select all the *.dll files from the opened 7-zip folder and drag-and-drop them into your "C:\Windows\System32" folder.
7. Find the following 2 x Jars on the web and copy them to your B4J additional library folder.
B4X:
#AdditionalJar: ortools-java-9.14.6206
#AdditionalJar: com.sun.jna_5.13.0
8. Run the attached project - it is Inline Java code from one of the Google or-tools examples.

Sample code:

Google or-tools example:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

#AdditionalJar: ortools-java-9.14.6206
#AdditionalJar: com.sun.jna_5.13.0

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
 
    Dim nativeMe As JavaObject
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
 
 
 
    nativeMe = Me
    Dim aa(1) As String
    aa(0) = ""
    nativeMe.RunMethod("main1", Array(aa))
 
End Sub

Sub Button1_Click
    xui.MsgboxAsync("Hello World!", "B4X")
End Sub


#if Java

import com.google.ortools.Loader;
import com.google.ortools.graph.MaxFlow;
import com.google.ortools.graph.MinCostFlow;

/**
 * Sample showing how to model using the flow solver.
 *
 */
  private static void solveMinCostFlow() {
    System.out.println("Min Cost Flow Problem - Simple interface");
    final int numSources = 4;
    final int numTargets = 4;
    final int[][] costs = {
        {90, 75, 75, 80}, {35, 85, 55, 65}, {125, 95, 90, 105}, {45, 110, 95, 115}};
    final int expectedCost = 275;
    MinCostFlow minCostFlow = new MinCostFlow();
    for (int source = 0; source < numSources; ++source) {
      for (int target = 0; target < numTargets; ++target) {
        minCostFlow.addArcWithCapacityAndUnitCost(
            source, numSources + target, 1, costs[source][target]);
      }
    }
    for (int node = 0; node < numSources; ++node) {
      minCostFlow.setNodeSupply(node, 1);
      minCostFlow.setNodeSupply(numSources + node, -1);
    }
    if (minCostFlow.solve() == MinCostFlow.Status.OPTIMAL) {
      final long totalFlowCost = minCostFlow.getOptimalCost();
      System.out.println("total flow = " + totalFlowCost + "/" + expectedCost);
      for (int i = 0; i < minCostFlow.getNumArcs(); ++i) {
        if (minCostFlow.getFlow(i) > 0) {
          System.out.println("From source " + minCostFlow.getTail(i) + " to target "
              + minCostFlow.getHead(i) + ": cost " + minCostFlow.getUnitCost(i));
        }
      }
    } else {
      System.out.println("No solution found");
    }
  }

  private static void solveMaxFlow() {
    System.out.println("Max Flow Problem - Simple interface");
    final int[] tails = {0, 0, 0, 0, 1, 2, 3, 3, 4};
    final int[] heads = {1, 2, 3, 4, 3, 4, 4, 5, 5};
    final int[] capacities = {5, 8, 5, 3, 4, 5, 6, 6, 4};
    final int expectedTotalFlow = 10;
    MaxFlow maxFlow = new MaxFlow();
    for (int i = 0; i < tails.length; ++i) {
      maxFlow.addArcWithCapacity(tails[i], heads[i], capacities[i]);
    }
    if (maxFlow.solve(0, 5) == MaxFlow.Status.OPTIMAL) {
      System.out.println("Total flow " + maxFlow.getOptimalFlow() + "/" + expectedTotalFlow);
      for (int i = 0; i < maxFlow.getNumArcs(); ++i) {
        System.out.println("From source " + maxFlow.getTail(i) + " to target " + maxFlow.getHead(i)
            + ": " + maxFlow.getFlow(i) + " / " + maxFlow.getCapacity(i));
      }
      // TODO(user): Our SWIG configuration does not currently handle these
      // functions correctly in Java:
      // maxFlow.getSourceSideMinCut(...);
      // maxFlow.getSinkSideMinCut(...);
    } else {
      System.out.println("There was an issue with the input.");
    }
  }

  public static void main1(String[] args) throws Exception {
    Loader.loadNativeLibraries();
//    System.load("C:/Users/Johans/Documents/B4J/orTools/orTools/Files/libortools.so");
    solveMinCostFlow();
    solveMaxFlow();
  }

#End If

See the B4J log when running the sample project.

1753607331405.png


Now you can use Google OR-Tools either with inline java code or with Java Object.



Download link above :

Copy JARs to B4J additional library folder
Copy *.dll files to your c:\windows\system32 folder.
 

Attachments

  • orTools.zip
    3 KB · Views: 33
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
OK... runs but I didn;t understand the example :-( sorry...

ORTools:
I ve read: Is good for optimizing Flows and schedule programming...

I was hopping... ofcourse to using perhaps arrays or lists... and using more b4j commands and not java :)

and an example perhaps creating programs for hours of employees...
Let's say we have a company that need to work 5days with 12hours per day... (8:00~20:00)
But Employess must not work more than 8hrs...
We have 3 Employees: Maria, Nick, George
George this week can work only from 13:00 and must take two days off...

Can this Library somehow feed it... with those data and automatically create the program :) ?
and how ?

* Ofcourse i can do it... with some if and loops - but i want how better is that :cool: library of Google ?
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
OK... runs but I didn;t understand the example :-( sorry...

ORTools:
I ve read: Is good for optimizing Flows and schedule programming...

I was hopping... ofcourse to using perhaps arrays or lists... and using more b4j commands and not java :)

and an example perhaps creating programs for hours of employees...
Let's say we have a company that need to work 5days with 12hours per day... (8:00~20:00)
But Employess must not work more than 8hrs...
We have 3 Employees: Maria, Nick, George
George this week can work only from 13:00 and must take two days off...

Can this Library somehow feed it... with those data and automatically create the program :) ?
and how ?

* Ofcourse i can do it... with some if and loops - but i want how better is that :cool: library of Google ?
Take a look at the attached example - read the commented section before the inline Java code.

You need to download protobuf-java-4.31.1.jar from here
and add it to your B4J additional library folder. Then run the attached B4J project.

The link to the example:

....more or less that you are after.....

1753720176919.png
 

Attachments

  • orToolsNurses.zip
    3.6 KB · Views: 32
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
Take a look at the attached example - read the commented section before the inline Java code.

You need to download protobuf-java-4.31.1.jar from here
and add it to your B4J additional library folder. The run the attached B4J project.

The link to the example:

....more or less that you are after.....

View attachment 165635
Just WOW!!!!! :)

especially the shift request is a very good option...

Now I need to think how will pass the values easy, especially the shift requests... (ofcourse no need now to use it anywhere... but i am very sure that soon will have the chance)


Q1: As i can understand is a Windows library - right ? - So if need it to an android device - may be need to have it as a service (api, webservice, something) to use it...

Q2: What exactly are those statistics, when i can say that those are good or bad, or need to adjust something ?
conflicts, branches, wall time...
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Take a look at the attached example - read the commented section before the inline Java code.

You need to download protobuf-java-4.31.1.jar from here
and add it to your B4J additional library folder. The run the attached B4J project.

The link to the example:

....more or less that you are after.....

View attachment 165635
@Johan Schoeman check here:
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
Just messing around with Employee Scheduling:

You need to download protobuf-java-4.31.1.jar from here
Central Repository: com/google/protobuf/protobuf-java/4.31.1
and add it to your B4J additional library folder. Then run the attached B4J project.

Also follow instructions in post #3 above

You might, based on selection of the comboboxes, run into a No Optimal Solotion:

No Optimal Solution.png


Use the comboboxes to select your No of Employees, No of Days, and No of Shifts per day - the UI will automatically follow the combobox selection(s). The shift preferences are prepopulated with "0" for each employee / days / shifts
Set the days and shifts for each employee you/they would prefer to work by changing the appropriate cell to "1"
Eg Below:

Preferences Set.png


Once done, click button Solve

Solution.png


Explanation of model output:
0 = shift not specifically requested and shift not assigned by the model
1x = specific shift requested and shift assigned by the model
0x = shift not specifically requested but shift has been assigned by the mode
1 = shift requested but not assigned by the model.

The model tries to accommodate as many request as possible while at the same time attempt to spread shifts equally between the employees.

Added setters to the inline Java code and returning a List from the inline java code to the B4J call with the solution of the model.

Probably a million other constraints that one can add to the inline java code but leaving it up to you to read up on in and change the inline java code accordingly.
 

Attachments

  • orToolsPersonSchedule.zip
    5.7 KB · Views: 19
Last edited:
Upvote 0
Top