import React, { useState } from 'react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; import { generateMinPathSumCase, solveMinPathSumCase, runMinPathSumBenchmark } from '../api'; const MinPathSum = () => { const [params, setParams] = useState({ rows: 5, cols: 5, min: 1, max: 20 }); const [currentCase, setCurrentCase] = useState(null); const [solveResults, setSolveResults] = useState(null); const [benchmarkResults, setBenchmarkResults] = useState(null); const [loading, setLoading] = useState(false); const [selectedAlgorithms, setSelectedAlgorithms] = useState({ dp: true, recursion: true }); const algorithmsList = [ { id: 'dp', name: '动态规划 (DP) O(MN)' }, { id: 'recursion', name: '递归 (Recursion) O(2^(M+N))' } ]; const getSelectedAlgoKeys = () => { return Object.keys(selectedAlgorithms).filter(k => selectedAlgorithms[k]); }; const handleGenerate = async () => { setLoading(true); try { const data = await generateMinPathSumCase(params.rows, params.cols, params.min, params.max); setCurrentCase(data.grid); setSolveResults(null); } catch (error) { console.error("Error generating case:", error); alert("生成测试用例失败"); } setLoading(false); }; const handleSolve = async () => { if (!currentCase) return; const algos = getSelectedAlgoKeys(); if (algos.length === 0) { alert("请至少选择一种算法"); return; } setLoading(true); try { const results = await solveMinPathSumCase(currentCase, algos); setSolveResults(results); } catch (error) { console.error("Error solving case:", error); alert("求解失败"); } setLoading(false); }; const handleBenchmark = async () => { const algos = getSelectedAlgoKeys(); if (algos.length === 0) { alert("请至少选择一种算法"); return; } setLoading(true); try { // Sizes for Square grids (N x N) const sizes = [2, 4, 6, 8, 10, 12, 14]; // Recursion will be very slow around 15x15 (2^30 operations roughly is too big, but O(2^(M+N)) is loose bound. // Actually C(M+N-2, N-1) paths. C(28, 14) = 40 million calls. Too slow for web. // Stick to small sizes. const results = await runMinPathSumBenchmark(sizes, algos); const chartData = results.map(item => { const point = { size: item.size }; item.algorithms.forEach(algo => { if (algo.time_seconds !== undefined && algo.time_seconds !== null) { point[algo.algorithm] = algo.time_seconds; } }); return point; }); setBenchmarkResults(chartData); } catch (error) { console.error("Error running benchmark:", error); alert("性能测试失败"); } setLoading(false); }; const toggleAlgorithm = (algoId) => { setSelectedAlgorithms(prev => ({ ...prev, [algoId]: !prev[algoId] })); }; return (

最小路径和 (Minimum Path Sum)

目标:寻找从网格左上角到右下角的路径,使得路径上的数字总和最小。每次只能向下或向右移动。

{/* Algorithm Selection */}

算法选择

{algorithmsList.map(algo => ( ))}
{/* Section 1: Generate & Solve */}

1. 生成测试用例

setParams({ ...params, rows: parseInt(e.target.value) })} className="mt-1 block w-full border rounded-md p-2" />
setParams({ ...params, cols: parseInt(e.target.value) })} className="mt-1 block w-full border rounded-md p-2" />
setParams({ ...params, min: parseInt(e.target.value) })} className="mt-1 block w-full border rounded-md p-2" />
setParams({ ...params, max: parseInt(e.target.value) })} className="mt-1 block w-full border rounded-md p-2" />
{currentCase && (

网格预览:

{currentCase.map((row, rIdx) => ( {row.map((val, cIdx) => ( ))} ))}
{val}

规模: {currentCase.length} x {currentCase[0].length}

)}

2. 求解与验证

{solveResults && (
{solveResults.map((res, idx) => ( ))}
算法 最小路径和 耗时 (秒)
{res.algorithm} {res.min_path_sum} {res.time_seconds?.toFixed(6)}
)}
{/* Section 2: Benchmark */}

3. 性能对比测试

{benchmarkResults && (
)}
); }; export default MinPathSum;