更新遗传算法默认参数;更新漏损流量单位为m3/h

This commit is contained in:
JIANG
2026-03-06 14:13:50 +08:00
parent bf6edf2662
commit 9beba1cf6f
4 changed files with 70 additions and 40 deletions
@@ -20,6 +20,7 @@ import { useNotification } from "@refinedev/core";
import { api } from "@/lib/api"; import { api } from "@/lib/api";
import { NETWORK_NAME, config } from "@config/config"; import { NETWORK_NAME, config } from "@config/config";
import { LeakageResultDetail } from "./types"; import { LeakageResultDetail } from "./types";
import { DMA_FLOW_DISPLAY_UNIT, toM3s } from "./utils";
interface Props { interface Props {
onResult: (result: LeakageResultDetail) => void; onResult: (result: LeakageResultDetail) => void;
@@ -33,15 +34,15 @@ const AnalysisParameters: React.FC<Props> = ({ onResult }) => {
dayjs().subtract(2, "hour"), dayjs().subtract(2, "hour"),
); );
const [endTime, setEndTime] = useState<Dayjs | null>(dayjs()); const [endTime, setEndTime] = useState<Dayjs | null>(dayjs());
const [popSize, setPopSize] = useState<number>(50); const [popSize, setPopSize] = useState<number>(10);
const [maxGen, setMaxGen] = useState<number>(100); const [maxGen, setMaxGen] = useState<number>(50);
const [qSum, setQSum] = useState<number>(0.4); const [qSum, setQSum] = useState<number>(1440);
const [advancedOpen, setAdvancedOpen] = useState(false); const [advancedOpen, setAdvancedOpen] = useState(false);
const [running, setRunning] = useState(false); const [running, setRunning] = useState(false);
const isValid = useMemo(() => { const isValid = useMemo(() => {
if (!schemeName.trim() || !startTime || !endTime) return false; if (!schemeName.trim() || !startTime || !endTime) return false;
return startTime.isBefore(endTime) && qSum >= 0.1; return startTime.isBefore(endTime) && qSum >= 360;
}, [schemeName, startTime, endTime, qSum]); }, [schemeName, startTime, endTime, qSum]);
const handleRun = async () => { const handleRun = async () => {
@@ -67,9 +68,9 @@ const AnalysisParameters: React.FC<Props> = ({ onResult }) => {
scada_end: endTime.toISOString(), scada_end: endTime.toISOString(),
pop_size: popSize, pop_size: popSize,
max_gen: maxGen, max_gen: maxGen,
q_sum: qSum, q_sum: toM3s(qSum, DMA_FLOW_DISPLAY_UNIT),
q_sum_unit: "m3/s", q_sum_unit: "m3/s",
output_flow_unit: "m3/s", output_flow_unit: DMA_FLOW_DISPLAY_UNIT,
}, },
); );
onResult(response.data as LeakageResultDetail); onResult(response.data as LeakageResultDetail);
@@ -115,25 +116,25 @@ const AnalysisParameters: React.FC<Props> = ({ onResult }) => {
<Typography variant="subtitle2" className="mb-1 font-medium"> <Typography variant="subtitle2" className="mb-1 font-medium">
DMA DMA
</Typography> </Typography>
<TextField <TextField
type="number" type="number"
value={dmaCount} value={dmaCount}
onChange={(e) => { onChange={(e) => {
const value = Number.parseInt(e.target.value, 10); const value = Number.parseInt(e.target.value, 10);
// Limit between 3 and 10 // Limit between 3 and 10
if (Number.isNaN(value)) { if (Number.isNaN(value)) {
setDmaCount(5); setDmaCount(5);
} else if (value > 10) { } else if (value > 10) {
setDmaCount(10); setDmaCount(10);
} else { } else {
setDmaCount(Math.max(3, value)); setDmaCount(Math.max(3, value));
} }
}} }}
fullWidth fullWidth
size="small" size="small"
inputProps={{ min: 3, max: 10, step: 1 }} inputProps={{ min: 3, max: 10, step: 1 }}
helperText="DMA 数量限制为 3-10 个" helperText="DMA 数量限制为 3-10 个"
/> />
</Box> </Box>
<LocalizationProvider <LocalizationProvider
@@ -171,7 +172,7 @@ const AnalysisParameters: React.FC<Props> = ({ onResult }) => {
<Box className="flex flex-col gap-2"> <Box className="flex flex-col gap-2">
<Typography variant="subtitle2" className="mb-1 font-medium"> <Typography variant="subtitle2" className="mb-1 font-medium">
(m3/s) ({DMA_FLOW_DISPLAY_UNIT})
</Typography> </Typography>
<TextField <TextField
type="number" type="number"
@@ -179,9 +180,9 @@ const AnalysisParameters: React.FC<Props> = ({ onResult }) => {
value={qSum} value={qSum}
onChange={(e) => { onChange={(e) => {
const value = Number(e.target.value); const value = Number(e.target.value);
setQSum(Number.isNaN(value) ? 0.4 : Math.max(0.1, value)); setQSum(Number.isNaN(value) ? 1440 : Math.max(360, value));
}} }}
inputProps={{ min: 0.1, step: 0.1 }} inputProps={{ min: 360, step: 10 }}
/> />
<Box <Box
sx={{ sx={{
@@ -13,7 +13,7 @@ import {
} from "@mui/material"; } from "@mui/material";
import { FormatListBulleted } from "@mui/icons-material"; import { FormatListBulleted } from "@mui/icons-material";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { getAreaColor } from "./utils"; import { DMA_FLOW_DISPLAY_UNIT, getAreaColor, toM3h } from "./utils";
import { LeakageResultDetail } from "./types"; import { LeakageResultDetail } from "./types";
interface Props { interface Props {
@@ -125,11 +125,13 @@ const RecognitionResults: React.FC<Props> = ({ result }) => {
{(() => { {(() => {
const val = (result.scheme_detail as any)?.algorithm_params const val = (result.scheme_detail as any)?.algorithm_params
?.q_sum; ?.q_sum;
const unit = const unit = String(
(result.scheme_detail as any)?.algorithm_params?.q_sum_unit || (result.scheme_detail as any)?.algorithm_params?.q_sum_unit ||
"m3/s"; "m3/s",
return val !== undefined );
? `${Number(val).toFixed(3)} ${unit}` const qSumM3h = toM3h(Number(val), unit);
return Number.isFinite(qSumM3h)
? `${qSumM3h.toFixed(3)} ${DMA_FLOW_DISPLAY_UNIT}`
: "-"; : "-";
})()} })()}
</Typography> </Typography>
@@ -163,8 +165,9 @@ const RecognitionResults: React.FC<Props> = ({ result }) => {
{(() => { {(() => {
const maxL = (result.scheme_detail as any)?.result_summary const maxL = (result.scheme_detail as any)?.result_summary
?.max_leakage; ?.max_leakage;
return maxL !== undefined const maxLeakageM3h = toM3h(Number(maxL), "m3/s");
? `${Number(maxL).toFixed(3)} m3/s` return Number.isFinite(maxLeakageM3h)
? `${maxLeakageM3h.toFixed(3)} ${DMA_FLOW_DISPLAY_UNIT}`
: "-"; : "-";
})()} })()}
</Typography> </Typography>
@@ -212,7 +215,7 @@ const RecognitionResults: React.FC<Props> = ({ result }) => {
align="right" align="right"
sx={{ fontWeight: 600, color: "#64748b", py: 1.5, pr: 3 }} sx={{ fontWeight: 600, color: "#64748b", py: 1.5, pr: 3 }}
> >
(m3/s) ({DMA_FLOW_DISPLAY_UNIT})
</TableCell> </TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
@@ -244,7 +247,7 @@ const RecognitionResults: React.FC<Props> = ({ result }) => {
align="right" align="right"
sx={{ pr: 3, py: 1.2, fontWeight: 500, color: "#334155" }} sx={{ pr: 3, py: 1.2, fontWeight: 500, color: "#334155" }}
> >
{row.LeakageFlow_m3_per_s.toFixed(3)} {toM3h(Number(row.LeakageFlow_m3_per_s), "m3/s").toFixed(3)}
</TableCell> </TableCell>
</TableRow> </TableRow>
))} ))}
@@ -24,6 +24,7 @@ import { useNotification } from "@refinedev/core";
import { api } from "@/lib/api"; import { api } from "@/lib/api";
import { NETWORK_NAME, config } from "@config/config"; import { NETWORK_NAME, config } from "@config/config";
import { LeakageResultDetail, LeakageSchemeRecord } from "./types"; import { LeakageResultDetail, LeakageSchemeRecord } from "./types";
import { DMA_FLOW_DISPLAY_UNIT, toM3h } from "./utils";
interface Props { interface Props {
onViewResult: (result: LeakageResultDetail) => void; onViewResult: (result: LeakageResultDetail) => void;
@@ -207,7 +208,10 @@ const SchemeQuery: React.FC<Props> = ({ onViewResult }) => {
<Typography variant="caption" className="font-medium text-gray-900"> <Typography variant="caption" className="font-medium text-gray-900">
{(() => { {(() => {
const value = Number((scheme.scheme_detail as any)?.result_summary?.max_leakage); const value = Number((scheme.scheme_detail as any)?.result_summary?.max_leakage);
return Number.isFinite(value) ? `${value.toFixed(3)} m3/s` : "-"; const maxLeakageM3h = toM3h(value, "m3/s");
return Number.isFinite(maxLeakageM3h)
? `${maxLeakageM3h.toFixed(3)} ${DMA_FLOW_DISPLAY_UNIT}`
: "-";
})()} })()}
</Typography> </Typography>
</Box> </Box>
@@ -218,8 +222,13 @@ const SchemeQuery: React.FC<Props> = ({ onViewResult }) => {
<Typography variant="caption" className="font-medium text-gray-900"> <Typography variant="caption" className="font-medium text-gray-900">
{(() => { {(() => {
const value = Number((scheme.scheme_detail as any)?.algorithm_params?.q_sum); const value = Number((scheme.scheme_detail as any)?.algorithm_params?.q_sum);
const unit = String((scheme.scheme_detail as any)?.algorithm_params?.q_sum_unit || "m3/s"); const unit = String(
return Number.isFinite(value) ? `${value.toFixed(3)} ${unit}` : "-"; (scheme.scheme_detail as any)?.algorithm_params?.q_sum_unit || "m3/s",
);
const qSumM3h = toM3h(value, unit);
return Number.isFinite(qSumM3h)
? `${qSumM3h.toFixed(3)} ${DMA_FLOW_DISPLAY_UNIT}`
: "-";
})()} })()}
</Typography> </Typography>
</Box> </Box>
@@ -11,6 +11,9 @@ export const AREA_COLORS = [
"#be123c", "#be123c",
]; ];
export const DMA_FLOW_DISPLAY_UNIT = "m3/h";
const M3H_FACTOR = 3600;
export const getAreaColor = (areaId: string | number | undefined) => { export const getAreaColor = (areaId: string | number | undefined) => {
const text = String(areaId ?? ""); const text = String(areaId ?? "");
let hash = 0; let hash = 0;
@@ -19,3 +22,17 @@ export const getAreaColor = (areaId: string | number | undefined) => {
} }
return AREA_COLORS[hash % AREA_COLORS.length]; return AREA_COLORS[hash % AREA_COLORS.length];
}; };
export const toM3h = (value: number, sourceUnit: string = "m3/s") => {
if (!Number.isFinite(value)) return Number.NaN;
const normalizedUnit = sourceUnit.trim().toLowerCase();
if (normalizedUnit === "m3/h") return value;
return value * M3H_FACTOR;
};
export const toM3s = (value: number, sourceUnit: string = "m3/h") => {
if (!Number.isFinite(value)) return Number.NaN;
const normalizedUnit = sourceUnit.trim().toLowerCase();
if (normalizedUnit === "m3/s") return value;
return value / M3H_FACTOR;
};