I'm implementing a CP model with cplex but within the steps I want some data to be calculated in a function or some similar form then resolve the model using the result.
What I need to calculate is the angle between two points with a third one as the center point e.g.
Input:
x=(5, 0), y=(0, 0), z=(0, 5)
Output:
Angle = 90.0 degrees or 1.571 rad
Check this link for more details Or this link
In python the function would look like this:
def calculate_angle(
first_point: Vector, center_point: Vector,
second_point: Vector) -> float:
""" Calculate the angel between three points. """
# Change to scalars
a = np.array(first_point.as_list())
b = np.array(center_point.as_list())
c = np.array(second_point.as_list())
# Calculate vector differences
ba = a - b
bc = c - b
# Find the angle in degrees
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
cosine_angle = np.clip(cosine_angle, -1, 1)
angle_radians = np.arccos(cosine_angle)
return angle_radians
Is there a way to use the arccos in opl? or call the python function in the model file?
Thanks!
In OPL scripting you can call any function in java as can be seen in this example: https://github.com/AlexFleischerParis/oplscripting/blob/main/IloOplCallJava.mod
execute
{
var convert180toRadian = IloOplCallJava("java.lang.Math","toRadians", "", 180);
writeln("180 degrees in radian : ",convert180toRadian);
}
/*
180 degrees in radian : 3.141592654
*/
execute
{
var title="title";
var msg="hello";
IloOplCallJava("javax.swing.JOptionPane", "showMessageDialog",
"(Ljava/awt/Component;Ljava/lang/Object;Ljava/lang/String;I)V",
null, msg, title, 1);
}
execute{
writeln("5 random numbers");
var rnd = IloOplCallJava("java.util.Random", "<init>", "()");
rnd.setSeed(1);
for(var i=1;i<=5;i++)
{
var t = rnd.nextDouble();
writeln(t);
}
writeln("Gaussian");
for(var i=1;i<=5;i++)
{
var t = rnd.nextGaussian();
writeln(t);
}
}
If you want to call your python code you can use IloOplExec in scripting as can be seen at https://github.com/AlexFleischerParis/opltipsandtricks/blob/master/barchart.mod
{string} options={"OPL" , "Python", "Java", "C++/C/C#", "Julia", "Other"};
float percent[options]=[32, 25, 16, 14, 4, 9];
string lastOption=last(options);
execute
{
var o=new IloOplOutputFile("c:\\temp\\parambarchart.txt");
o.writeln("Which API do you use when you call CPLEX ?");
o.writeln("CPLEX API");
o.writeln("% of use");
for(var i in options)
{
o.write(i);
if (i!=lastOption) o.write(",");
}
o.writeln();
for(var i in options)
{
o.write(percent[i]);
if (i!=lastOption) o.write(",");
}
o.writeln();
o.close();
IloOplExec("C:\\Python36\\python.exe c:\\temp\\displaybarchart.py",false);
}
and in displaybarchart.py
import matplotlib.pyplot as plt
plt.style.use('ggplot')
f = open("c://temp//parambarchart.txt", "r")
title=f.readline()
xlabel=f.readline()
ylabel=f.readline()
xstring=f.readline()
ystring=f.readline()
f.close();
x = xstring.split(",")
values = [float(i) for i in ystring.split(",")]
x_pos = [i for i, _ in enumerate(x)]
plt.bar(x_pos, values, color='green')
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.title(title)
plt.xticks(x_pos, x)
plt.show()