整体需求完善
This commit is contained in:
@ -0,0 +1,57 @@
|
||||
import random
|
||||
import sys
|
||||
|
||||
def quick_sort(arr):
|
||||
"""
|
||||
快速排序主函数,支持空数组处理
|
||||
"""
|
||||
if len(arr) <= 1:
|
||||
return arr
|
||||
|
||||
def partition(low, high):
|
||||
pivot_index = random.randint(low, high) # 随机选择基准
|
||||
arr[pivot_index], arr[high] = arr[high], arr[pivot_index]
|
||||
pivot = arr[high]
|
||||
i = low - 1
|
||||
|
||||
for j in range(low, high):
|
||||
if arr[j] <= pivot:
|
||||
i += 1
|
||||
arr[i], arr[j] = arr[j], arr[i]
|
||||
|
||||
arr[i+1], arr[high] = arr[high], arr[i+1]
|
||||
return i + 1
|
||||
|
||||
def recur_sort(low, high):
|
||||
if low < high:
|
||||
pi = partition(low, high)
|
||||
recur_sort(low, pi - 1)
|
||||
recur_sort(pi + 1, high)
|
||||
|
||||
recur_sort(0, len(arr) - 1)
|
||||
return arr
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 从命令行参数读取数据
|
||||
if len(sys.argv) > 1:
|
||||
try:
|
||||
# 处理多种输入格式:逗号分隔、空格分隔或混合分隔
|
||||
input_str = " ".join(sys.argv[1:])
|
||||
input_data = [float(x) if '.' in x else int(x)
|
||||
for x in input_str.replace(',', ' ').split()]
|
||||
|
||||
print("原始输入:", sys.argv[1:])
|
||||
print("解析数据:", input_data)
|
||||
|
||||
sorted_arr = quick_sort(input_data.copy())
|
||||
print("排序结果:", sorted_arr)
|
||||
|
||||
except ValueError:
|
||||
print("错误:输入数据包含非数字字符,请确保只输入数字")
|
||||
print("用法: python script.py [数字1 数字2 ...]")
|
||||
print("示例: python script.py 3 0 8 7 2 1 9 4")
|
||||
else:
|
||||
print("未提供输入数据,使用默认测试用例")
|
||||
test_case = [3, 0, 8, 7, 2, 1, 9, 4]
|
||||
print("测试数据:", test_case)
|
||||
print("排序结果:", quick_sort(test_case.copy()))
|
@ -0,0 +1,57 @@
|
||||
import random
|
||||
import sys
|
||||
|
||||
def quick_sort(arr):
|
||||
"""
|
||||
快速排序主函数,支持空数组处理
|
||||
"""
|
||||
if len(arr) <= 1:
|
||||
return arr
|
||||
|
||||
def partition(low, high):
|
||||
pivot_index = random.randint(low, high) # 随机选择基准
|
||||
arr[pivot_index], arr[high] = arr[high], arr[pivot_index]
|
||||
pivot = arr[high]
|
||||
i = low - 1
|
||||
|
||||
for j in range(low, high):
|
||||
if arr[j] <= pivot:
|
||||
i += 1
|
||||
arr[i], arr[j] = arr[j], arr[i]
|
||||
|
||||
arr[i+1], arr[high] = arr[high], arr[i+1]
|
||||
return i + 1
|
||||
|
||||
def recur_sort(low, high):
|
||||
if low < high:
|
||||
pi = partition(low, high)
|
||||
recur_sort(low, pi - 1)
|
||||
recur_sort(pi + 1, high)
|
||||
|
||||
recur_sort(0, len(arr) - 1)
|
||||
return arr
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 从命令行参数读取数据
|
||||
if len(sys.argv) > 1:
|
||||
try:
|
||||
# 处理多种输入格式:逗号分隔、空格分隔或混合分隔
|
||||
input_str = " ".join(sys.argv[1:])
|
||||
input_data = [float(x) if '.' in x else int(x)
|
||||
for x in input_str.replace(',', ' ').split()]
|
||||
|
||||
print("原始输入:", sys.argv[1:])
|
||||
print("解析数据:", input_data)
|
||||
|
||||
sorted_arr = quick_sort(input_data.copy())
|
||||
print("排序结果:", sorted_arr)
|
||||
|
||||
except ValueError:
|
||||
print("错误:输入数据包含非数字字符,请确保只输入数字")
|
||||
print("用法: python script.py [数字1 数字2 ...]")
|
||||
print("示例: python script.py 3 0 8 7 2 1 9 4")
|
||||
else:
|
||||
print("未提供输入数据,使用默认测试用例")
|
||||
test_case = [3, 0, 8, 7, 2, 1, 9, 4]
|
||||
print("测试数据:", test_case)
|
||||
print("排序结果:", quick_sort(test_case.copy()))
|
@ -3,6 +3,7 @@ package com.bipt.intelligentapplicationorchestrationservice.service.Impl;
|
||||
import com.bipt.intelligentapplicationorchestrationservice.mapper.AlgorithmInfoMapper;
|
||||
import com.bipt.intelligentapplicationorchestrationservice.pojo.AlgorithmInfo;
|
||||
import com.bipt.intelligentapplicationorchestrationservice.service.AlgorithmInfoService;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -11,10 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -31,8 +29,10 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
@Autowired
|
||||
private AlgorithmInfoMapper algorithmInfoMapper;
|
||||
|
||||
@Value("${algorithm.upload.dir:/tmp/algorithm-files/}") // 默认上传目录
|
||||
// 从配置文件读取上传目录
|
||||
@Value("${algorithm.upload.dir:algorithm_files}")
|
||||
private String uploadDir;
|
||||
|
||||
@Override
|
||||
public AlgorithmInfo getById(Long id) {
|
||||
return algorithmInfoMapper.selectById(id);
|
||||
@ -78,6 +78,11 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增算法
|
||||
* @param algorithmInfo
|
||||
* @param file
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void save(AlgorithmInfo algorithmInfo, MultipartFile file) {
|
||||
@ -99,32 +104,31 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
// 生成唯一文件名,避免冲突
|
||||
String fileName = UUID.randomUUID().toString() + "_" + originalFilename;
|
||||
|
||||
// 关键修改:使用实际存在的绝对路径(替换为你的实际路径,如 D:/algorithm_files)
|
||||
// 建议在配置文件中配置,而非硬编码
|
||||
String uploadDir = "D:/algorithm_files"; // 例如:Windows 路径用 D:/xxx,Linux 用 /home/xxx
|
||||
// 构建相对路径(相对于项目根目录)
|
||||
Path relativePath = Paths.get(uploadDir, fileName);
|
||||
|
||||
// 构建路径对象(使用 Path 而非 File,更适合跨平台)
|
||||
Path saveDirPath = Paths.get(uploadDir);
|
||||
// 获取当前应用的运行目录(兼容开发和部署环境)
|
||||
Path basePath = Paths.get("").toAbsolutePath();
|
||||
Path absolutePath = basePath.resolve(relativePath);
|
||||
|
||||
// 确保目录存在(createDirectories 会创建所有不存在的父目录,跨平台兼容)
|
||||
if (!Files.exists(saveDirPath)) {
|
||||
Files.createDirectories(saveDirPath); // 关键:创建多级目录
|
||||
log.info("已创建存储目录: {}", saveDirPath.toAbsolutePath());
|
||||
// 确保目录存在
|
||||
Path parentDir = absolutePath.getParent();
|
||||
if (!Files.exists(parentDir)) {
|
||||
Files.createDirectories(parentDir);
|
||||
log.info("已创建存储目录: {}", parentDir);
|
||||
}
|
||||
|
||||
// 完整文件路径
|
||||
Path saveFilePath = saveDirPath.resolve(fileName);
|
||||
|
||||
// 保存文件到指定路径
|
||||
file.transferTo(saveFilePath); // 使用 Path 重载方法,更可靠
|
||||
file.transferTo(absolutePath);
|
||||
|
||||
// 设置文件路径到实体类(存储绝对路径或可访问的相对路径)
|
||||
algorithmInfo.setAlgorithmFile(saveFilePath.toString());
|
||||
// 存储相对路径到数据库
|
||||
algorithmInfo.setAlgorithmFile(relativePath.toString());
|
||||
|
||||
// 设置文件大小
|
||||
algorithmInfo.setFileSize(Files.size(saveFilePath));
|
||||
algorithmInfo.setFileSize(Files.size(absolutePath));
|
||||
|
||||
log.info("文件保存成功: {}", saveFilePath.toAbsolutePath());
|
||||
log.info("文件保存成功 - 相对路径: {}, 绝对路径: {}",
|
||||
relativePath, absolutePath);
|
||||
} catch (Exception e) {
|
||||
log.error("文件保存失败", e);
|
||||
throw new RuntimeException("文件保存失败: " + e.getMessage(), e);
|
||||
@ -132,7 +136,7 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
} else {
|
||||
// 文件为空的处理逻辑
|
||||
algorithmInfo.setAlgorithmFile(null);
|
||||
algorithmInfo.setFileSize(0L); // 空文件大小设为0
|
||||
algorithmInfo.setFileSize(0L);
|
||||
}
|
||||
|
||||
algorithmInfo.setCreateTime(LocalDateTime.now());
|
||||
@ -142,15 +146,33 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
|
||||
/**
|
||||
* 执行Python算法脚本并返回结果
|
||||
* @param scriptPath Python脚本路径
|
||||
* @param scriptPath Python脚本路径(数据库中存储的相对路径)
|
||||
* @param args 命令行参数列表
|
||||
* @return 脚本执行结果
|
||||
*/
|
||||
public String run(String scriptPath, List<String> args) throws IOException, InterruptedException {
|
||||
// 构建命令:python [脚本路径] [参数1] [参数2] ...
|
||||
if (scriptPath == null || scriptPath.isEmpty()) {
|
||||
throw new IllegalArgumentException("脚本路径不能为空");
|
||||
}
|
||||
|
||||
// 获取当前应用的运行目录(兼容开发和部署环境)
|
||||
Path basePath = Paths.get("").toAbsolutePath();
|
||||
Path absoluteScriptPath = basePath.resolve(scriptPath);
|
||||
|
||||
// 验证文件是否存在
|
||||
if (!Files.exists(absoluteScriptPath)) {
|
||||
throw new FileNotFoundException("脚本文件不存在: " + absoluteScriptPath);
|
||||
}
|
||||
|
||||
// 验证文件是否可执行(针对Python脚本)
|
||||
if (!Files.isReadable(absoluteScriptPath)) {
|
||||
throw new IOException("脚本文件不可读: " + absoluteScriptPath);
|
||||
}
|
||||
|
||||
// 构建命令:python [脚本绝对路径] [参数1] [参数2] ...
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("python"); // Python解释器路径,可配置在application.properties中
|
||||
command.add(scriptPath); // 脚本路径
|
||||
command.add(absoluteScriptPath.toString()); // 使用绝对路径执行脚本
|
||||
command.addAll(args); // 添加所有参数
|
||||
|
||||
// 打印完整命令(用于调试)
|
||||
@ -158,6 +180,10 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
|
||||
// 创建进程并执行命令
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
|
||||
// 设置工作目录为脚本所在目录
|
||||
processBuilder.directory(absoluteScriptPath.getParent().toFile());
|
||||
|
||||
processBuilder.redirectErrorStream(true); // 将错误输出合并到标准输出
|
||||
Process process = processBuilder.start();
|
||||
|
||||
@ -176,7 +202,12 @@ public class AlgorithmInfoServiceImpl implements AlgorithmInfoService {
|
||||
|
||||
// 检查脚本是否成功执行
|
||||
if (exitCode != 0) {
|
||||
throw new RuntimeException("脚本执行失败,退出码: " + exitCode);
|
||||
// 捕获详细的错误信息
|
||||
String errorMsg = "脚本执行失败,退出码: " + exitCode +
|
||||
"\n命令: " + String.join(" ", command) +
|
||||
"\n输出: " + output.toString();
|
||||
log.error(errorMsg);
|
||||
throw new RuntimeException(errorMsg);
|
||||
}
|
||||
|
||||
return output.toString();
|
||||
|
@ -60,3 +60,6 @@ spring.profiles.active=dev
|
||||
#配置IP列表(后续根据需求修改ip数据,以下仅为测试用例)
|
||||
available.ips=192.168.1.100,192.168.1.101,192.168.1.102
|
||||
|
||||
# 算法文件上传目录(相对于项目根目录)
|
||||
algorithm.upload.dir=algorithm_files
|
||||
|
||||
|
Reference in New Issue
Block a user