Java调⽤Python脚本传递数据并返回计算结果
需求:最近在使⽤基于Java编写的Cloudsim 4.0云仿真平台进⾏虚拟机动态迁移实验,由于中间有需要⽤到深度强化学习算法,因此需要将集的状态表⽰为⼆维数组,⽐如物理机的计算能⼒Mips,RAM,带宽等等。希望将这样的⼆维数组传⼊到带torch等第三⽅库的Python脚本进⾏深度强化学习训练,所以就有⼆维int数组的传⼊,和从Python计算后的结果返回读取这个需求
⼀、实现思路:将Java中的data结构化为字符串,以命令⾏参数的形式传⼊Python中
⽬前有⼏种Java调⽤Python的⽅法,不过能良好兼容Python第三⽅库的⽅法通常是使⽤
Process proc = Runtime().exec(args1); // 执⾏Python脚本并传参数
如果只是简单传⼊⼏个数字,或者⼏个URL,⽐如可直接写为
int num1 = 5;
int num2 = 10;
Process proc = Runtime().exec(args1, String.valueOf(num1), String.valueOf(num2));
⽽如果要传⼊多维数组且每次传递时数组的⼤⼩会变,⽐如
int[][] stateInt = new int[][]{{2500, 5, 2610, 2620, 2630, 2640, 2650, 2660}, // Mips
{870, 5, 4091, 4092, 4093, 4094, 4095, 4096}}; // RAM
则需要把要传⼊的多维数据,结构化为可分割的字符串,上述⼆维数组就可转变为如下字符串
"2500 5 2610 2620 2630 2640 2650 2660;870 5 4091 4092 4093 4094 4095 4096"
这样传⼊到Python中就可以根据;和<;空格>通过split()将⼆维数组恢复出来
⼆、Python实现代码
import sys
from selenium import webdriver
import torch
def policy(state):
action = [2, 1, 0, 0]
action[0] += state[0][1]
return action
def str2int(stateStr):
'''将完整字符串转换为⼆维数组'''
stateList = []
multiVimState = stateStr.split(';')
for singleVimState in multiVimState:
elements = singleVimState.split(' ')
singleVimList = []
for e in elements:
singleVimList.append(int(e))
stateList.append(singleVimList)
return stateList
def int2str(actionIntArr):
'''将形如[0,1,0,0,0]的int动作向量转化为01000字符串,⽅便Java处理'''
actionStr = '';
for e in actionIntArr:
actionStr += str(e)
return actionStr
if __name__ == '__main__':
state = []
stateStr = sys.argv[1];
stateIntArr = str2int(stateStr)
actionIntArr = policy(stateIntArr)
actionStr = int2str(actionIntArr)
# [2+5=7, 1, 0, 0] => 7100
print(actionStr)
三、Java实现代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class testPython {
/**
* 将整型state数组转换为带分隔符的字符串,⽅便以命令⽅式传递给Python⽂件以进⾏计算
* @param stateInt 当前虚机 + 所有主机状态向量
* @return
python转java代码*/
public static String state2str(int[][] stateInt){
String stateStr = "";
for (int i = 0; i < stateInt.length; i++) {
for (int j = 0; j < stateInt[0].length; j++) {
if (j == 0) stateStr += String.valueOf(stateInt[i][j]);
else stateStr += " " + String.valueOf(stateInt[i][j]);
}
if (i != stateInt.length - 1) stateStr += ";";
}
return stateStr;
}
public static void main(String[] args) throws Exception {
// Python⽂件地址(Linux)
String pyPath = "/XXXX/XXXX.py";
int[][] stateInt = new int[][]{{2500, 5, 2610, 2620, 2630, 2640, 2650, 2660}, // Mips
{870, 5, 4091, 4092, 4093, 4094, 4095, 4096}}; // RAM
// 将整型state数组转换为带分隔符的字符串,⽅便以命令⽅式传递给Python⽂件以进⾏计算
String stateStr = state2str(stateInt);
String[] args1 = new String[] {"python", pyPath, stateStr};
// 执⾏Python⽂件,并传⼊参数
Process proc = Runtime().exec(args1);
// 获取Python输出字符串作为输⼊流被Java读取
BufferedReader in = new BufferedReader(new InputStreamReader( InputStream() ));
String actionStr = in.readLine();
if (actionStr != null)
System.out.println(actionStr);
in.close();
proc.waitFor();
// 将获取的字符串分割为字符串数组,然后逐个元素转换为int并求和
String nums[] = actionStr.split("");
int sum = 0;
for (int i = 0; i < nums.length; i++)
sum += Integer.valueOf(nums[i]);
System.out.println("求和为:" + sum);
}
}
运⾏Java代码后得到如下结果
到此这篇关于Java调⽤Python脚本传递数据并返回计算结果的⽂章就介绍到这了,更多相关Java调⽤Python脚本内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论