我有一个成本优化请求,我不知道是否有相关文献。这有点难以解释,所以我提前为问题的长度道歉。
我正在访问的服务器以这种方式工作:
- 对记录 (r1, ...rn) 和字段 (f1, ...fp) 发出请求
- 您只能请求笛卡尔积 (r1, ..., rp) x (f1,...fp)
- 与此类请求相关的成本(时间和金钱)与请求的大小相关:
T((r1, ..., rn)x(f1, ..., fp) = a + b * n * p
不失一般性(仅通过归一化),我们可以假设b=1
成本为:
T((r1, ...,rn)x(f1,...fp)) = a + n * p
- 我只需要请求 pair 的一个子集
(r1, f(r1)), ... (rk, f(rk))
,一个来自用户的请求。我的程序充当用户和服务器(外部)之间的中间人。我有很多这样的请求(每天数万个)。
从图形上看,我们可以将其视为一个 nxp 稀疏矩阵,为此我想用一个矩形子矩阵覆盖非零值:
r1 r2 r3 ... rp ------ ___ f1 |xx| |x| f2 |x | --- ------ f3 .. ______ fn |xx| ------
有:
- 由于成本不变,子矩阵的数量保持合理
- 所有的 'x' 必须位于子矩阵内
- 由于线性成本,覆盖的总面积不能太大
我将 g 命名为我的问题的稀疏系数(所需对的数量超过可能的对总数,g = k / (n * p)
。我知道系数a
。
有一些明显的观察结果:
- 如果 a 很小,最好的解决方案是独立请求每个 (record, field) 对,总成本为:
k * (a + 1) = g * n * p * (a + 1)
- 如果 a 很大,最好的解决方案是请求整个笛卡尔积,总成本为:
a + n * p
- 第二种解决方案更好
g > g_min = 1/ (a+1) * (1 + 1 / (n * p))
- 当然笛卡尔积中的顺序并不重要,因此我可以转置矩阵的行和列以使其更容易覆盖,例如:
f1 f2 f3 r1 xx r2 x r3 xx
可以重新排序为
f1 f3 f2 r1 xx r3 xx r2 x
并且有一个最佳的解决方案是要求(f1,f3) x (r1,r3) + (f2) x (r2)
- 尝试所有解决方案并寻找更低的成本不是一种选择,因为组合学爆炸了:
对于行上的每个排列:(n!) 对于列上的每个排列:(p!) 对于 nxp 矩阵的每个可能覆盖:(时间未知,但很大......) 计算覆盖成本
所以我正在寻找一个近似的解决方案。我已经有某种贪心算法,可以在给定矩阵的情况下找到覆盖(它从单一单元格开始,如果合并中空单元格的比例低于某个阈值,则合并它们)。
记住一些数字,我的 n 介于 1 和 1000 之间,而我的 p 介于 1 和 200 之间。覆盖模式真的是“块状”,因为记录来自所要求的字段相似的类。不幸的是,我无法访问记录类...
问题 1:有人有什么想法、一个巧妙的简化或可能有用的论文参考吗?由于我有很多请求,因此我正在寻找一种平均运行良好的算法(但我无法承受它在某些极端情况下运行不佳,例如当 n 和 p 很大时请求整个矩阵,并且请求确实非常稀疏)。
问题2:其实问题更复杂:cost其实更像是这样的形式:a + n * (p^b) + c * n' * p'
,其中b是一个常数<1(一个记录一旦求一个字段,再求其他也不算太贵字段)并且n' * p' = n * p * (1 - g)
是我不想请求的单元格的数量(因为它们是无效的,并且请求无效的东西需要额外的费用)。我什至无法想到一个快速解决这个问题的方法,但仍然......任何人的想法?