计算乘数和除数值的优化算法
Optimization algorithm for calculating multiplier and divisor values
我正在尝试优化一个算法,我想不出更好的方法。
有一个输入(时钟频率值)将通过乘数和除数的组合。
- 目标是在给定输入的情况下,找到能够产生期望输出值的乘数和除数值集合。
OutClk = (InClk * Mult1 * Mult2 * Mult3 * Mult4/Div1)/Div2
我当前的(幼稚的?)实现是:
#define PRE_MIN 10000000
#define PRE_MAX 20000000
// Available values of the multipliers and divisors.
uint8_t mult1_vals[] = {1, 2};
uint8_t mult2_vals[] = {1, 2, 4, 8};
uint8_t mult3_vals[] = {3, 5, 7};
uint8_t div1_vals[] = {1, 2, 4};
uint8_t div2_vals[] = {1, 2, 4, 8};
bool exists_mults_divs(uint32_t in_val, uint32_t out_val)
{
uint8_t i_m1, i_m2, i_m3, i_d1, i_d2;
uint32_t calc_val;
for (i_m1 = 0; i_m1 < sizeof(mult1_vals); i_m1++) {
for (i_m2 = 0; i_m2 < sizeof(mult2_vals); i_m2++) {
for (i_m3 = 0; i_m3 < sizeof(mult3_vals); i_m3++) {
for (i_div1 = 0; i_div1 < sizeof(div1_vals); i_div1++) {
calc_val = in_val * (mult1_vals[i_m1] * mult2_vals[i_m2] *
mult3_vals[i_m3] / div1_vals[i_div1]);
if ((calc_val <= PRE_MIN) || (calc_val > PRE_MAX))
continue; // Can this be refactored?
for (i_div2 = 0; i_div2 < sizeof(div2_vals); i_div2++) {
calc_val /= div2_vals[i_div2];
if (calc_val == out_val)
return true;
}
}
}
}
}
// No multiplier/divisor values found to produce the desired out_val.
return false;
}
有什么方法可以优化这个吗?或者使用一些算法方法?
我使用C,但任何类型的伪代码对我来说都是可以的。
编辑:一些例子来说明。这将返回true
:
exists_mults_divs(2000000, 7000000); // in=2000000, out=7000000
// Iterating over the values internally:
// 1. in * 1 * 1 * 3 / 1 = 6000000
// 6000000 is not within PRE_MIN/MAX range of 10-20000000.
// 2. in * 1 * 1 * 5 / 1 = 10000000 is within range, try varying div2
// 2a. div2=1 => 10000000 / 1 = 10000000 != 7000000 not desired out
// 2b. div2=2 => 10000000 / 2 = 50000000 != 7000000
// etc.
// 3. in * 1 * 1 * 7 / 1 = 7000000 not within range
// etc.
// 4. in * 1 * 2 * 7 / 1 = 14000000 is within range, try varying div2
// 4a. div2=1 => 14000000 / 1 != 7000000
// 4b. div2=2 => 14000000 / 2 == 7000000 IS desired out
//
// RETURN RESULT:
// TRUE since a 2000000 in can generate a 7000000 out with
// mult1=1, mult2=2, mult3=7, div1=1, div2=2
这将返回false
:
exists_mults_divs(2000000, 999999999);
因为没有可用值的除数和乘数的组合将导致得到999999999
重新排序公式,我们有
OutClk/(Mult1*Mult2*Mult3) = InClk/(Div1*Div2);
看
Mult1 = {1, 2}
和Mult2 = {1, 2, 4, 8}
,它们都是2的幂。同样,
Div1
和Div2
也是2的幂。Mult3 = {3,5,7}
,均为素数
那么,我们需要做的是将InClk和OutClk同时除以它们的最大公约数(GCD)
int g = gcd(InClk, OutClk);
InClk /= g;
OutClk/= g;
为了InClk == OutClk
,我们需要使InClk/g
和OutClk/g
都等于1。
然后在clk中除法后剩下的部分,我们试着用每个div_vals
中clk可以被除法的最大元素来除以它。(因为div_vals
中的每个元素都是2的幂,所以我们需要选择最大的)
for(int i = sizeof(div1_vals) - 1; i>= 0; i--)
if(InClk % div1_vals[i] == 0){
InClk/= div1_vals[i];
break;
}
for(int i = sizeof(div2_vals) - 1; i>= 0; i--)
if(InClk % div2_vals[i] == 0){
InClk/= div2_vals[i];
break;
}
同样适用于OutClk
for(int i = sizeof(mul1_vals) - 1; i>= 0; i--)
if(OutClk % mul1_vals[i] == 0){
OutClk/= mul1_vals[i];
break;
}
....
最后,如果InClk == 1 and OutClk == 1
,返回true,否则返回false。
时间复杂度O(n)其中n为mul1_vals中元素的最大个数,…
相关文章:
- std::stable_sort: 如何选择内存优化算法而不是时间优化算法?
- 解析参数后内联以优化算法速度
- 如何优化标准::设置交集算法(C++)
- 优化的图像卷积算法
- 优化德劳奈三角测量算法
- 优化查找特定斐波那契数的算法
- 基本算法优化
- "Neighbor function"优化以使用A*算法解决8难题
- 优化算法以查找满足某些属性的六位数字的数量
- 利用优先级队列C++优化了从O(n^2)到O(n)的Huffman树算法
- STL算法是否针对速度进行了优化
- 优化最近邻居大小调整算法以提高速度
- 优化算法"binary_fold"并使其左(或右)关联
- 优化算法以检查"Whether for a given directed graph there is only one way to sort the graph using topological
- 优化算法
- 非常简单的优化算法产生一个函数参数误差
- 使用正确的优化算法C++在三维空间中查找点之间的距离
- 需要优化 - 算法实现占用太多内存
- 计算乘数和除数值的优化算法
- 我如何优化算法和条件在这个for循环