Java调用Python脚本传递数据并返回计算结果

网友投稿 260 2023-01-12

Java调用Python脚本传递数据并返回计算结果

需求:最近在使用基于java编写的Cloudsim 4.0云仿真平台进行虚拟机动态迁移实验,由于中间有需要用到深度强化学习算法,因此需要将集群的状态表示为二维数组,比如物理机的计算能力Mips,RAM,带宽等等。希望将这样的二维数组传入到带torch等第三方库的python脚本进行深度强化学习训练,所以就有二维int数组的传入,和从Python计算后的结果返回读取这个需求

一、实现思路:将Java中的data结构化为字符串,以命令行参数的形式传入Python中

目前有几种Java调用Python的方法,不过能良好兼容Python第三方库的方法通常是使用

Process proc = Runtime.getRuntime().exec(args1); // 执行Python脚本并传参数

如果只是简单传入几个数字,或者几个URL,比如可直接写为

int num1 = 5;

int num2 = 10;

Process proc = Runtime.getRuntime().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

impgdRVgwDort 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

*/

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.getRuntime().exec(args1);

// 获取Python输出字符串作为输入流被Java读取

BufferedReader in = new BufferedReader(new InputStreamReader( proc.getInputStream() ));

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代码后得到如下结果

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:新手必备的IDEA常用设置总结
下一篇:音乐播放器免费api(免费播放音乐的播放器)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~