由于一些开发工具的限制,我正在寻找一个数学表达式:
If x>=1:
y = 1
else:
y = 0
如果简化,X必须是大于等于0的整数。
绝对允许的操作:+, -,/, *, ** (power)
不允许操作:不允许使用绝对值。使用祝辞,& lt; & lt; =,祝辞 ;=, !=, == 是不允许的。使用"if">
For instance不允许:Y =1 *(x>=1)
(由于使用了>=)
对于添加的信息,我试图添加一些约束到谷歌的or-tools,where if X>=0 then, y+=1…
编辑:我正在用python工作。
我想说,没有办法得到一个间断函数到处定义像y(x)
使用有限数量的连续函数与组合和连续算子。
你可以得到像abs(x)
和(x ** 2) ** 0.5
这样的东西,但我不知道你如何使用这个(它有一个不连续的一阶导数,但它仍然是连续的)来得到一个完美的阶跃函数,它在每个阶跃点都有指定的值。
像0.5 + 0.5 * abs(x-1)/(x-1)
这样的东西是你几乎到处都在寻找的,但你会遇到奇点x=1
的问题,0/0
将被评估。
编辑如果输入x
保证是整数,那么解决方案很简单:
def y(x):
return 0.5 + 0.5 * abs(x - 0.5) / (x - 0.5)
或者,使用power…定义abs
def y(x):
return 0.5 + 0.5 * ((x - 0.5) ** 2) ** 0.5 / (x - 0.5)
函数对于x=0.5
是未定义的,但如果它只对整数求值,这不是问题。
另一个选项是
def y(x):
return 0.5 + abs(x - 0.25) + (x - 0.25) - abs(abs(x-0.25) + (x-0.25) - 0.5)
是一个连续函数,在0.25之前为0,当x从0.25到0.75时线性地从0到1,在它之后保持为1。
标题>在这种情况下,我建议如下:由于x是整数且x>=0
,以下逻辑将为真:
ifx > 0
then0**x == 0
else0**x == 1
。这个等于ifx >=1
then0**x == 0
else0**x == 1
.
所以y = 1 - 0**x
会给出期望的结果。
让我们看看这里,你基本上有一个不等式x-1>=0
y = (x-1)/abs(x-1)
将为您提供除x=0以外的所有情况下您正在寻找的值。在这种情况下,将抛出一个异常,也许您可以使用它来设置y的值。比如:
try{
y=(x-1)/abs(x-1);
} catch(ArithmaticException e){
y = 1}
由于已知整数是非负的,因此可以简单地将整数的所有位逐一或在一起。结果是所需的谓词。如果一个简单的循环执行按位或运算,直到源操作数耗尽为止,则需要进行比较,这是不允许的。
在我现在可以看到的限制下,唯一可行的替代方案是使用直线代码,重复比特提取过程的步骤,因为整数有比特。这就是我在下面的ISO-C99代码中使用的。每个位用DIV和MOD提取,两个一元变量s
和t
的OR计算为s + t - s * t
。对32位整数的一个简单的详尽测试证实了这种方法是有效的,但是效率显然不是很高。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define OR1(s,t) (s + t - s * t)
// (x >= 1) ? 1 : 0
uint32_t ge1 (uint32_t x)
{
uint32_t y;
y = OR1 (
OR1 (
OR1 (OR1 (OR1 ((x / 0x00000001) % 2, (x / 0x00000002) % 2),
OR1 ((x / 0x00000004) % 2, (x / 0x00000008) % 2)),
OR1 (OR1 ((x / 0x00000010) % 2, (x / 0x00000020) % 2),
OR1 ((x / 0x00000040) % 2, (x / 0x00000080) % 2))),
OR1 (OR1 (OR1 ((x / 0x00000100) % 2, (x / 0x00000200) % 2),
OR1 ((x / 0x00000400) % 2, (x / 0x00000800) % 2)),
OR1 (OR1 ((x / 0x00001000) % 2, (x / 0x00002000) % 2),
OR1 ((x / 0x00004000) % 2, (x / 0x00008000) % 2)))),
OR1 (
OR1 (OR1 (OR1 ((x / 0x00010000) % 2, (x / 0x00020000) % 2),
OR1 ((x / 0x00040000) % 2, (x / 0x00080000) % 2)),
OR1 (OR1 ((x / 0x00100000) % 2, (x / 0x00200000) % 2),
OR1 ((x / 0x00400000) % 2, (x / 0x00800000) % 2))),
OR1 (OR1 (OR1 ((x / 0x01000000) % 2, (x / 0x02000000) % 2),
OR1 ((x / 0x04000000) % 2, (x / 0x08000000) % 2)),
OR1 (OR1 ((x / 0x10000000) % 2, (x / 0x20000000) % 2),
OR1 ((x / 0x40000000) % 2, (x / 0x80000000) % 2)))));
return y;
}
int main (void)
{
uint32_t x, res, ref;
x = 0;
do {
res = ge1 (x);
ref = x >= 1;
if (res != ref) {
printf ("error: x=%08x res=%08x ref=%08xn", x, res, ref);
return EXIT_FAILURE;
}
x++;
} while (x);
printf ("test passedn");
return EXIT_SUCCESS;
}
对于整数x,如果abs是OK的,那么我建议
y = (x + abs(x)) / (abs(x+1) + abs(x-1))
不受除零的约束,只要不发生溢出,除法对每个整数x都是精确的,无论是正的还是负的,因此可以用整数算术求值。
如果你不关心负x,它甚至更简单:
y = (abs(x+1) - abs(x-1)) / 2
如果函数需要在整个有界整数的域上操作,那么应该使用一些更大的int算法,或者您可以使用float(x)的浮点运算中使用相同的函数,或者同样可以返回到@6502的答案,在这种情况下更简单。
编辑如果你没有绝对值,你可以尝试1-(2.0**(-x))**n
,有足够大的n,以利用浮点下溢和/或有限的精度。N =2000应该足以导致每个正整数输入的下溢,但没有必要让N这么高,因为N =100应该足以导致大多数体系结构中的不精确舍入到1。即使使用浮点运算,也很容易有效地计算,您可以使用单次幂1.0-(2.0**(-100.0*x))
。对于负整数输入,将x替换为x*x。