You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中C#实现单纯形法时While循环致编辑器崩溃求助

问题排查与修复方案

一、核心无限循环原因:单纯形法迭代逻辑错误

你的Unity编辑器冻结本质是迭代后目标行(第0行)始终存在负数,导致count永远不为0,无法触发break,根源是表格更新的核心公式和比率测试逻辑写错了:

1. 非Pivot行更新公式完全错误

当前代码里非Pivot行的更新逻辑不符合单纯形法规则:

simplexTable[i, pivotValueIndex] = 0;
for (int j = 0; j <= numberOfConstraints + 3; j++)
{
    if (j != pivotValueIndex)
    {
        simplexTable[i, j] = simplexTable[i, j] - simplexTable[i, j] * (simplexTable[pivotRow, j] / pivotCell);
    }
}

正确逻辑:非Pivot行的每个元素应该是 新值 = 原值 - (该行Pivot列的原始值) * (标准化后的Pivot行对应列值),而且不能提前把Pivot列设为0,要先保存原始值再计算:

else
{
    // 先保存当前行Pivot列的原始值,避免被覆盖后无法计算
    float rowPivotOriginal = simplexTable[i, pivotValueIndex];
    for (int j = 0; j <= numberOfConstraints + 3; j++)
    {
        // Pivot行已经除以pivotCell标准化过,直接相乘即可
        simplexTable[i, j] = simplexTable[i, j] - rowPivotOriginal * simplexTable[pivotRow, j];
    }
}

2. 比率测试(Ratio Test)逻辑漏洞

当前ratioTestArr只初始化了第0位为0,其余元素默认是0,会导致程序错误选中目标行(第0行)作为Pivot行——而Pivot行必须从约束行(i≥1)中选择,这会彻底破坏迭代逻辑,导致永远无法收敛。

修复方案:

float[] ratioTestArr = new float[numberOfConstraints];
// 初始化所有元素为无穷大,确保只会从约束行中选Pivot行
Array.Fill(ratioTestArr, float.PositiveInfinity);

for (int i = 1; i < pivotColumn.Length; i++)
{
    if (simplexTable[i, pivotValueIndex] > 0)
    {
        ratioTestArr[i] = simplexTable[i, numberOfConstraints + 3] / simplexTable[i, pivotValueIndex];
    }                
}

// 此时最小比率对应的行一定是约束行
int pivotRow = Array.IndexOf(ratioTestArr, ratioTestArr.Min());

二、数组越界问题修复

你标记的IndexOutOfRangeException,大概率是pivotValueArr的长度不匹配表格列数导致的。当前pivotValueArr长度是numberOfConstraints +4,但如果表格实际列数超过这个值,就会越界,建议直接用表格的列数初始化:

float[] pivotValueArr = new float[simplexTable.GetColumns()];

同时检查simplexTable.GetColumns()的实现是否正确返回实际列数,避免循环条件失效。

三、其他优化与防护

  1. 恢复maximised变量的赋值,保持逻辑完整性:
if (count == 0)
{
    maximised = true;
    Debug.Log("已找到最优解");
    break;
}
  1. 添加迭代次数限制,避免极端情况的无限循环:
int iterationCount = 0;
int maxIterations = 100; // 可根据问题复杂度调整
while (!maximised && iterationCount < maxIterations)
{
    iterationCount++;
    // ... 原有循环逻辑
}
if (iterationCount >= maxIterations)
{
    Debug.LogError("达到最大迭代次数,可能存在无解或逻辑错误");
}
  1. 校验numberOfConstraints的正确性:它应该等于simplexTable.GetRows() -1(第0行是目标行,其余是约束行),如果两者不匹配,会导致循环逻辑混乱。

四、内存问题排查

4GB内存确实偏小,但Unity如果是内存不足,通常会先弹出警告而非直接无响应。优先修复上述逻辑错误后,若仍有问题,可通过Window > Analysis > Profiler查看CPU和内存占用,确认是否是循环导致的CPU满负载,或用简单测试用例(比如2个约束的线性规划问题)验证。

内容的提问来源于stack exchange,提问作者Avneet K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:08:23