Math 哪个二进制运算符或函数导致的冲突最少?

Math 哪个二进制运算符或函数导致的冲突最少?,math,Math,假设我们有两条龙,x和y。涉及x和y的哪个操作符或函数会产生另一个长z,它最不可能等于将同一操作符或函数应用于x和y的不同部分的结果 例:添加是个糟糕的选择。1+4=5,但2+3也等于5 编辑:让我解释一下我为什么问这个问题。我正在制作一个太空rpg游戏。游戏环境(solarsystems)将由两个种子按程序生成。这些种子由宇宙中系统的x和y坐标组成。因此,玩家在冒险过程中很有可能在(500501)和(501500)处遇到系统。我需要一种方法来解决这些太阳能系统产生的独特问题。而且,我想确保尽可

假设我们有两条龙,x和y。涉及x和y的哪个操作符或函数会产生另一个长z,它最不可能等于将同一操作符或函数应用于x和y的不同部分的结果

例:添加是个糟糕的选择。1+4=5,但2+3也等于5

编辑:让我解释一下我为什么问这个问题。我正在制作一个太空rpg游戏。游戏环境(solarsystems)将由两个种子按程序生成。这些种子由宇宙中系统的x和y坐标组成。因此,玩家在冒险过程中很有可能在(500501)和(501500)处遇到系统。我需要一种方法来解决这些太阳能系统产生的独特问题。而且,我想确保尽可能多的坐标对将产生独特的种子

编辑2:我测试了给我的两个解决方案。阿克皮特里科的答案远远优于阿尔特利乌斯的答案。下面是测试解决方案的代码:

HashSet<Long> set = new HashSet<Long>();

 for(int x=0; x<1000; x++)
  for(int y=0; y<1000; y++)
   //I commented out one of the solutions at a time
   set.add((long)(((x&0x7FFFFFFF) << 33) | ((y&0x7FFFFFFF) << 2) |   ((x>>>62) & 2) | (y>>>63)));//Artelius
   set.add((long)(x - y * 7046029254386353131l));//Accipitridae

 System.out.println(set.size());
HashSet=newhashset();
对于(intx=0;x>>63))//Artelius
加上((长)(x-y*70460292543863531L))//鸡科
System.out.println(set.size());
从散列集的大小,我可以知道通过每个方法生成了多少个独特的种子。对于这些参数,Artelius的解决方案生成了2048个唯一的long,而Accipitridae的解决方案生成了1000000个,这意味着根本没有碰撞


谢谢大家为解决这个问题所做的努力。:)

只要将可能的输出值集限制为与用作操作数的操作数相同的一组值,那么除了加法之外就没有更好的方法了。此外,事实上,可能是最好的选择,因为它是最简单的。(见下文分析)

有2^64个可能的长度,因此有2^127个可能的无序长度对,对于一个答案只有2^64个可能的长度对,所以最好的可能分布比率是有2^63个不同的长度对,它们给出相同的答案,实际上,(滚动)相加就可以了

编辑:根据下面的评论

不管一个long有多少个(比如N位),都有2^N个不同的long,因此有2^N x 2^N个有序的long对,但是为了进行分析,使用两个long x,y与使用y和x完全相同(二进制op被假定为可通信的),因此有2^(2N-1)个无序的long对

因此,使用无序对(数量的一半)有2^nx(2^N-1)或2^(2N-1)对没有重复的长序列。(如果N=64,则为2^127)因此,对无序操作数对(较大的2^127对集)的答案赋值(从较小的2^64长集)的最大“分布”是指它们是否均匀分布。这就是加法的作用,因为对于所有多头集合中的每一个可能的多头,它与每一个其他多头(带滚动)的总和将是一组。。。每隔一段时间

使用有序对所做的唯一一件事是允许您也使用非通信操作数,但是您必须处理所有情况,即答案不在您用于操作数的集合中(如5/4),但即使您只是假设四舍五入,对分析的唯一影响是,通过使用有序对,可以得到2^2N个不同的操作数对,而不是2^(2N-1)

您可以做的是将用作操作数的整数集限制为小于可能长数的平方根(因此,如果您使用64位长数,请将输入值限制为32位长数),然后,如果您绝对不希望重叠或重复(在任何情况下,op B=与任何其他C op D相同的值),可以使用乘法运算符,但对于较小的潜在操作数集中的每个值X,请选择第X个素数作为乘法操作数。这样,无论你随机选取哪两个值A和B(从1到最大值),操作都是两个不同素数的乘法。这意味着可能的操作数集必须小于等于或小于操作数最大可能值的素数集(如果是64位无符号长整数,则为2^64)

第二次编辑:根据您的具体问题,可能的操作数集仅限于计算机屏幕的尺寸,远小于长数(无论您在哪个平台上)因此,保证每对可能的屏幕坐标将生成一个不同的种子键的一个非常简单和明显的方法是简单地左移一个坐标的值,以确保与另一个坐标没有按位重叠,然后按位或结果与另一个坐标

所以如果你的屏幕是3000x3000,那么长lngVal=(x如果
(x1,y1)
(x2,y2)
是两个随机的输入对,那么让
f1=f(x1,y1)
f2=f(x2,y2)

你想做的是最小化

P( f(x1,y1) = f(x2,y2) )
 = P(f1 = f2)
 = sum for i in [LONG_MIN ... LONG_MAX]
        of P(f1 = i) * P(f2 = i)
 = sum for i in [LONG_MIN ... LONG_MAX]
        of P(f1 = i)^2
所以你想最小化每个函数输出概率的平方和。因为概率之和必须是1,我们知道:

sum for i in [LONG_MIN ... LONG_MAX]
     of P(f1 = i)
  = 1
我们也知道,对于所有的i,
p(f1=i)
在0和1之间(包括1)。直观地说,最小化
p(f1=f2)
是一个使
f1
的概率分布尽可能均匀的问题。(这可以从数学上证明,但对问题来说并不重要。)理想情况下,
p(f1=i)
P(f1=j)
对于所有长度
i
j
都应相同

现在让我们来看看x和y的性质的一些不同的可能性

首先是一般情况,其中x和y均匀分布在long的范围内。(换句话说,x同样可能是long可以是的任何东西。y也是)。在这种情况下,我们可以让
f(x,y)=x+y
,或者
f(x,y)=x
f(x,y) = ((x&0x7FFF) << 17) | ((y&0x7FFF) << 2) | ((x>>30) & 2) | (y>>31)