架构:软件成本估算

本文提出了一种新颖的软件成本估算混合方法,该方法将软件离散为更小的任务,并使用专家判断和算法技术。通过使用基于体积和复杂性的双因素资格系统,我们提出了一种更具适应性和可扩展性的模型来估计软件项目持续时间,特别强调大型遗留迁移项目。

介绍
软件成本估算(SCE)是软件工程领域内的一个系统化、定量的过程,涉及分析、预测和分配软件系统的开发、维护和管理所需的财务、时间和资源投资。

这项重要工作使用不同的方法、模型和技术,为利益相关者提供对成功软件项目执行的预期财务、时间和资源需求的专业评估。

它是项目规划的重要组成部分,允许在软件开发生命周期中进行资源的逻辑分配并支持风险评估和管理。

算法方法
1、COCOMO
在软件工程和成本估算领域,构造成本模型(通常称为 COCOMO)是一个成熟且备受推崇的概念。COCOMO 由 Barry Boehm 博士开发,研究软件属性和开发成本之间的相互作用。

该模型在从基本到详细的层次结构上运行,每个级别提供不同程度的粒度 [1]。该模型仔细使用代码行和其他项目细节等因素,将它们与经验成本估算数据保持一致。

尽管如此,COCOMO 并不是过去停滞不前的遗迹。多年来它一直在进步,COCOMO II 涵盖了当代软件开发实践的复杂性,特别是在面向对象编程和敏捷方法等不断发展的范式中 [2]。

然而,尽管 COCOMO 的实证和系统方法提供了可信度,但其使用代码行数作为主要指标却招致了批评。对于功能属性更为重要的项目尤其如此。

2、功能点分析 (FPA)
功能点分析 (FPA) 摆脱了代码指标的严格限制,成为从功能角度评估软件的整体方法。

FPA 由 IBM 的 Allan Albrecht 在 20 世纪 70 年代末提出,旨在通过软件的功能及其为用户提供的价值来衡量软件,而不是通过代码行数来衡量。

通过对不同的用户功能(例如输入、输出、查询和接口)进行分类和评估,FPA 将软件复杂性简化为可测量的功能点 [3]。

这种方法在功能输出比底层代码更重要的项目中特别有效。FPA 采用以用户为中心的方法,很好地满足了客户的需求,并提供了对开发人员和利益相关者都有吸引力的具体指标。

但值得注意的是,FPA 的有效性取决于对用户需求的透彻理解,不确定性可能会导致估计的差异。

3、SLIM(软件生命周期管理)
SLIM(软件生命周期管理的缩写)植根于概率建模哲学,是由 Lawrence Putnam 设计的多方面工具 [4]。

SLIM 的本质围绕着一组非线性方程,当这些方程交织在一起时,可以追踪软件开发项目从开始到完成的轨迹。SLIM 结合历史数据和项目具体情况,呈现了一个概率图景,提供有关项目时间表、成本和潜在风险的见解。

SLIM 的独特之处在于它能够随着项目的进展进行调整和重新配置。通过持续吸收项目反馈,SLIM 动态完善其估算,以确保它们始终立足于项目实际情况。

这种持续的重新校准既是 SLIM 最大的资产,也是它的主要障碍。虽然它提供了灵活的适应性,但它​​也需要详细的数据记录和跟踪,这需要项目团队采取严格的方法。

非算法方法
1、专家的判断
漫步在软件评估方法的古老走廊中,我们不能忽视专家判断的持久智慧[5]。专家判断避免了其他技术的严格算法和形式,而是借鉴了行业资深人士积累的经验和直觉能力。

这些经验丰富的从业者从众多项目中积累了丰富的见解,具有评估新企业的范围、复杂性和可能困难的天生能力。他们细致入微的理解可以弥补更严格的数据驱动模型留下的差距。

专家判断巧妙地捕捉了项目的无形微妙之处,以定量指标可能被忽视的方式封装了软件开发工艺。然而,与任何艺术形式一样,专家判断也会受到其实践者的怪癖的影响。它很容易受到个人偏见和人类判断固有的可变性的影响。

2、类比估计(或历史数据)
历史数据估计,也称为类比估计,是一种通过回顾过去的项目来为未来项目提供估计的技术。这类似于凝视后视镜来导航前方的道路。

这种方法涉及推断以前类似项目的经验和结果,并将其与当前项目进行比较。通过这样做,它提供了一个经过现实世界结果调整的扎根视角,为估计提供信息。

它的有效性取决于其经验基础,过去的事件常常为未来的事业提供可靠的预测。然而,现有历史数据的质量和相关性是关键因素。

不匹配的比较或过时的数据可能会导致项目误入歧途,这凸显了仔细数据管理和谨慎实施的重要性[6]。

3、德尔菲法
该方法的名字来源于古老的德尔菲神谕,它协调了专家们的和谐融合。德尔菲技术是一种旨在通过收集专家组的匿名见解和预测来达成共识的方法[7]。

这种方法有利于集体智慧的研讨会,而不是依赖单一的观点。通过迭代轮次的反馈,根据集体输入对估计进行细化和重新校准。

德尔菲法是一个结构化但动态的过程,可以过滤掉异常值并趋向于更加平衡的集体判断。它本质上是迭代的,并强调匿名性,以减少群体思维和有影响力的偏见的潜在陷阱。

这提供了一个让每个专家的声音都能得到应有共鸣的环境。然而,德尔菲法需要细致的引导和耐心,因为它需要经过多轮审议才能达成共识。

基于人工智能的方法
1、SCE 中的机器学习
在快速发展的软件成本估算领域,机器学习 (ML) 成为变革的强大预兆 [8]。机器学习摆脱了传统方法的确定性限制,深入研究概率领域,利用大量历史数据来挖掘隐藏的模式和相关性。

通过对不同项目数据集进行训练,机器学习算法提高了预测能力,适应了经常被严格的基于规则的系统忽视的细微差别。这种适应性使机器学习成为动态软件生态系统中特别有效的工具,其中项目范围和挑战不断变化。

然而,机器学习在 SCE 中的有效性取决于训练数据的质量和全面性。稀疏或有偏差的数据集可能会导致算法误入歧途,这凸显了稳健数据管理和验证的重要性。

2、神经网络
神经网络 (NN) 深入研究计算建模的复杂神经通路,证明了人工智能的仿生愿望。神经网络的结构模仿人脑的神经元复杂性,部署节点和连接的分层架构来处理和解释信息。

在软件成本估算领域,神经网络从历史数据中编织出复杂的模式,捕获传统模型通常难以捉摸的非线性关系[9]、[10]。它们的深度学习能力,尤其是随着多层架构的出现,为 SCE 的复杂数据集带来了巨大的希望。

然而,赋予神经网络力量的深度有时也会使它们笼罩在不透明之中。它们的“黑匣子”性质,加上容易过度拟合,需要进行细致的培训和验证,以确保可靠的估计。此外,最近“Grokking”的发现表明该领域可能会产生令人着迷的新发现。

3、遗传算法
遗传算法 (GA) 从生命的本质中汲取灵感,将进化原理转移到计算画布上。遗传算法将软件成本估算视为优化难题,通过模仿自然选择、交叉和突变的过程寻找最合适的解决方案。

通过启动不同群体的估计策略并通过进化周期迭代地完善它们,遗传算法收敛到更优化的估计模型。它们固有的适应性和探索性使它们非常适合充满局部最优的 SCE 景观。

然而,遗传算法的随机本质意味着它们的结果虽然通常是稳健的,但可能并不总是保证运行之间的绝对一致性。其进化参数的校准对于在探索和开发之间取得平衡仍然至关重要。

敏捷估算技术
敏捷方法最初是为了解决传统软件开发流程的挑战而制定的,它引入了项目管理和产品交付方式的范式转变。

这种方法的一个组成部分是开发的迭代性质以及对跨职能团队之间协作的强调。这种协作方法扩展到敏捷中的估计过程。

敏捷估算技术不是试图从一开始就预见项目的全部复杂性,而是旨在随着团队收集更多信息而不断发展和适应。

1、故事点
许多敏捷团队不是用几小时或几天来估计任务,而是使用故事点来估计用户故事所需的相对工作量。故事点考虑任务的复杂性、风险和工作量。

通过关注相对努力而不是绝对时间,团队可以避免由于不可预见的挑战或依赖而导致低估或高估的陷阱。经过几次迭代,团队形成了一种对其“速度”的感觉——他们在一次迭代中完成的故事点的平均数量——这有助于预测[13]。

2、规划扑克
最流行的敏捷估算技术之一是规划扑克。团队成员(通常包括开发人员、测试人员和产品所有者)协作估计特定任务或用户故事所需的工作量。

使用一组具有预定义值(通常是斐波那契数列)的卡片,每个成员选择一张代表他们的估计的卡片。同时亮出他们的牌后,讨论估计的差异,从而达成共识。

Planning Poker 的美妙之处在于它能够结合个人专家的意见并得出反映整个团队集体智慧的估计。该过程还揭示了潜在的挑战或不确定性,从而做出更明智的决策。

3、持续重新评估
敏捷估算的一个标志是它的迭代性质。当团队进行冲刺或迭代时,他们会根据新的知识和之前周期中花费的实际工作不断重新评估和调整他们的估计。随着项目的进展,这种迭代反馈循环可以实现更准确的预测。

混合模型方法
我们的目标是提出一种结合了专家判断和算法方法的新颖模型。在考虑专家方法时,值得注意的是,它可能涉及主观评估,可能会表现出不同专家之间的不一致。

此外,它对专家经验和可用性的依赖有可能由于认知启发法和过度依赖最近的经验而引入偏差。

另一方面,算法方法可能需要大量的专业知识才能正确应用,并且可能关注某些可能不相关的参数,例如代码行数。

因此,这里的目的是提出一个独立于编程语言并考虑项目、硬件和人员属性等多种因素的模型。

任务离散化
在不断发展的软件工程领域,任务离散化实践已成为中流砥柱。这种方法强调将较大的软件目标分解为可管理的小型单元的重要性。

通过承认软件组件固有的谨慎性(从屏幕和 API 到 SQL 脚本),有条理的分解成为一种实际需求 [17]。这种方法允许您在由一致元素组成的一致模块中定义软件。拥有同质的估算元素至关重要,这样估算团队就能轻松了解他们正在估算的内容,并避免适应这些元素。这些元素在本文中将被称为“任务”。

此外,在个人层面上处理任务可以提高准确性,而它提供的细节可以提高灵活性,从而可以进行迭代调整以适应项目不断变化的需求。

这种方法保证了每个组件的独特特征得到适当和独立的考虑。这种离散化方法有几个优点。在个人层面上处理任务可以提高准确性,而它带来的粒度可以提高灵活性,从而实现迭代调整,以满足项目的流动需求。

相反,对每项任务复杂性的详细理解可以谨慎地分配资源并调整技能到最需要的地方。然而,这种详细程度并非没有缺点。

尽管提供了准确性,但将任务解构为其组成部分可能会导致管理挑战,特别是在大型项目中。忽略某些任务的可能性(尽管很小)却始终存在。此外,过于详细的方法有时会掩盖更广泛的项目目标,导致决策延迟,这通常被称为“分析瘫痪”。

双因素资格体系和努力计算任务离散化
随着任务的描述表现出同质属性,必须确定分配适当工作量的通用决定因素。

经过仔细审查,我们发现了两个关键因素:复杂性和体积[1],[18]。

复杂性是衡量任务执行所需技术敏锐度的指标。例如,在用户界面内,动态表的合并可以保证将任务分类为由于其复杂的要求而具有高复杂性。

体积法描述了所涉及的工作量或数量。为了说明这一点,在用户界面的上下文中,广泛的四十字段表单的存在可能表明由于其组件的庞大规模而具有大量体积的任务。

复杂性和体积 都在[1 − 5] 区间内,并且必须是整数。现在我们定义 Effort ( E),其计算如下:

E=C*V

我们在此计算中使用乘法,以便在高复杂性和高体积之间建立联系。这使我们能够在两个评估标准同时增加时考虑潜在风险,同时保持系数较低的任务的准确性。

算盘系统
现在已经获得了工作量,可以为每个工作量值确定相应的天数。此阶段至关重要,需要了解目标架构和技术的专家进行干预。
然而,该模型允许这一关键资源在建立这些值时仅干预一次。

算法的使用
为了建立这些值,我们建议使用一种算法来提高准确性并防止错误。它可用于使用三个不同的模型和两个起始标准来模拟数据集:

  • 最大天数(与 25 的努力相关)
  • 值之间的间隙填充

我们利用三种不同的模型,使专家和评估团队能够从不同的曲线轮廓中进行选择,这些曲线轮廓可能会产生不同的特性,例如精度、风险评估和填充尺寸,以理想地适应要求。假设了三种不同的数学模型来解释这种关系:线性、二次和指数。每个模型都假设了一种独特的“努力到天”的转变行为:
  • 线性模型假设工作量与天数之间成正比。
  • 二次模型 设想了加速的增长率,引用了多项式数学。
  • 指数模型 预测指数激增,意味着更高的努力值急剧升级。

可以调整这些模型以更准确地满足估计要求。最后我们得到如下代码:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd # Importing pandas for tabular display
# Fixed effort values
efforts = np.array([1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 20, 25])
# Parameters
Max_days = 25
Step_Days = 0.25
def linear_model(effort, max_effort, max_days, step_days):
 slope = (max_days - step_days) / max_effort
 return slope * effort + step_days - slope
def quadratic_model(effort, max_effort, max_days, step_days):
 scale = (max_days - step_days) / (max_effort + 0.05 * max_effort**2)
 return scale * (effort + 0.05 * effort**2)
def exponential_model(effort, max_effort, max_days, step_days):
 adjusted_max_days = max_days - step_days + 1
 base = np.exp(np.log(adjusted_max_days) / max_effort)
 return step_days + base ** effort - 1
def logarithmic_model(effort, max_effort, max_days, step_days):
 scale = (max_days - step_days) / np.log(max_effort + 1)
 return scale * np.log(effort + 1)
# Rounding to nearest step
def round_to_step(value, step):
 return round(value / step) * step
linear_days = np.array([round_to_step(linear_model(e, efforts[-1], Max_days, Step_Days), Step_Days) for e in efforts])
quadratic_days = np.array([round_to_step(quadratic_model(e, efforts[-1], Max_days, Step_Days), Step_Days) for e in efforts])
exponential_days = np.array([round_to_step(exponential_model(e, efforts[-1], Max_days, Step_Days), Step_Days) for e in efforts])
logarithmic_days = np.array([round_to_step(logarithmic_model(e, efforts[-1], Max_days, Step_Days), Step_Days) for e in efforts])
# Plot
plt.figure(figsize=(10,6))
plt.plot(efforts, linear_days, label="Linear Model", marker='o')
plt.plot(efforts, quadratic_days, label=
"Quadratic Model", marker='x')
plt.plot(efforts, exponential_days, label=
"Exponential Model", marker='.')
plt.plot(efforts, logarithmic_days, label=
"Logarithmic Model", marker='+')
plt.xlabel(
"Effort")
plt.ylabel(
"Days")
plt.title(
"Effort to Days Estimation Models")
plt.legend()
plt.grid(True)
plt.show()
# Displaying data in table format
df = pd.DataFrame({
 'Effort': efforts,
 'Linear Model (Days)': linear_days,
 'Quadratic Model (Days)': quadratic_days,
 'Exponential Model (Days)': exponential_days,
 'Logarithmic Model (Days)': logarithmic_days
})
display(df)


大型遗留迁移项目中的具体用例
现在已经描述了该模型,接下来将在迁移项目的背景下提出具体的应用程序。人们相信,该模型非常适合此类项目,在此类项目中,团队面临着似乎不适合现有标准模型的情况,如第一部分中所述。

SCE 在遗产迁移中的重要性
通常,迁移项目会受到成本的影响。迁移需求通常是由以下因素引起的:

  • 更频繁的回归和副作用
  • 难以为过时技术 找到新资源
  • 专业知识集中
  • 集成新功能的复杂性
  • 性能问题

上面列出的所有潜在原因都会增加成本和/或风险。可能有必要考虑有问题的技术构建模块的迁移。实施主要取决于所产生的成本,需要准确的估计。

然而,重要的是要认识到,在组织的迁移过程中,技术的变化必须伴随着人员和组织的调整。

通常,在定义目标架构和技术后,组织可能缺乏这些领域的必要专家。这可能会使“专家判断”方法变得复杂。算法方法似乎也不合适,因为它们需要知识和掌握,但也不一定考虑迁移在重绘要迁移的组件方面可能需要的所有微妙之处。

此外,初始代码行数并不始终是可靠的标准。最后,基于人工智能的方法似乎仍处于形成阶段,对于这些组织来说实施和掌握可能具有挑战性。

这就是为什么我们的模型看起来很合适,因为它使现有团队能够量化工作量,然后向目标技术专家寻求建议来创建估计,从而获得准确的数字。值得注意的是,这种估计仅涵盖开发本身,而忽略了规范阶段和相关的基础设施成本。

混合模型的应用
我们将概述实施我们的估计模型的整个过程。该过程包括三个阶段:初始化、估计和最终化。

1、初始化
在此阶段,必须首先解构要评估的技术构建块。它需要被分解为一组统一的任务。 
例如,具有调用 AS400 数据库的 GWT 前端的应用程序可以分为两个主要集:

  • 前端: 任务由屏幕表示。
  • 后端:任务由 API 表示。

然后我们可以组建估算团队。它不需要是目标技术的技术专家,但应该由现有项目的资源组成,最好是技术/功能对,他们可以评估每个任务与两个愿景的互补性。

该团队将能够开始列出离散化过程中确定的主要组件的任务。

2、预估
现在,我们有一个团队准备将复杂性和体积值分配给要识别的任务集。在进行关联工作的同时,我们可以开始设置与工作相关的天数。
这项工作可能需要目标技术方面的专家以及估算团队的成员来量化一些基准值,在此基础上专家可以进行批判性的审视并将结果扩展到整个图表。
在这个阶段结束时,我们有一个天/努力对应算盘和一个具有相关努力值的任务列表。

3、最终确定
最后一步是使用算盘计算工作量和天数之间的换算,以获得总天数。获得工作量值列表后,可以使用以下标准进行风险分析:

  • 努力概率密度曲线的标准差
  • 分析组件的某些“区域”是否集中高努力值
  • 工作量值大于 16 的任务数量

根据这些标准,可以在限制区域采取具体措施。

结论
总之,我们的模型提供了一种实用且灵活的方法来估计大型遗留迁移项目所涉及的成本。

通过将专家判断的要素与结构化算法分析相结合,该模型解决了迁移过时或复杂系统所带来的独特挑战。

它认识到准确衡量工作量和成本的重要性,不仅考虑技术方面,还考虑所需的人力和组织转变。

三个阶段的过程——初始化、估计和最终确定——确保了全面的评估,从将项目分解为可管理的任务到进行详细的风险分析。这种混合模型对于面临艰巨的迁移任务的团队特别有益,它提供了做出明智决策并有效为过渡做好准备的途径。

通过这种方法,组织可以应对错综复杂的迁移,确保更顺利地过渡到现代、更高效的系统。

根据所提出的讨论和发现,很明显遗留迁移项目提出了一系列独特的挑战,仅靠传统的软件成本估算方法无法解决这些挑战。

所提出的混合模型可以作为更具启发性的专家判断方法和更结构化的算法分析之间的桥梁,提供平衡和自适应的解决方案。该模型的主要优势在于其适应性以及利用目标技术方面的机构知识和特定专业知识的能力。

此外,该模型能够将问题解构为一组统一的任务,并以适当的粒度进行估计,确保了其在各种应用场景中的相关性。虽然混合模型的当前实施显示出潜力,但未来的研究和改进可以进一步推动其实用性:

  • 实证验证:与所有模型一样,对各种迁移项目进行实证验证至关重要。这不仅可以验证其有效性,还可以提高其准确性。
  • (我们已经在努力了。)
  • 与人工智能集成: 尽管基于人工智能的软件成本估算方法仍处于萌芽阶段,但其潜力不容忽视。混合模型的未来迭代可以集成机器学习以增强预测,特别是当可以使用过去项目的大型数据集时。
  • 改进的风险分析:拟议的风险分析标准提供了坚实的起点。然而,更复杂的风险模型(考虑了移民项目固有的不可预见的复杂性和不确定性)可以集成到模​​型中。
  • 工具和自动化:开发可以半自动化所描述的过程的工具将使模型更容易被组织访问和采用。

总之,混合模型在软件成本估算领域取得了显着的进步,特别是对于遗留迁移项目。然而,与所有模型一样,它是一个不断发展的实体,持续改进只会增强其适用性和有效性。