如何在数组中生成N个数字,这些数字之和等于0

时间:2018-09-21 15:26:09

标签: javascript arrays algorithm

我有这样的代码:

function myArr(N){

    let arr = [];

    function randomNumber(min,max) {
        if (min > max) {
            let vMin = min;
            min = parseInt(max,10);
            max = parseInt(vMin,10);
        }
        return Math.floor(Math.random()*(max-min+1)+min);
    }

    for(let i = 0; i < N; i++) {
        arr.push(randomNumber(100,-100));
    }
    return arr;
}

此函数生成具有N个数字的数组。但是我希望这些生成的数字的总和等于0。如何实现?我当时正在考虑有条件的“如果”,但我不完全知道,在这种情况下如何使用它……也许有些人知道,该怎么做?感谢您的提示!

4 个答案:

答案 0 :(得分:1)

在生成数字时,必须确保数字保持接近零,然后生成N-1个数字并计算最后一个:

 const arr = [];
 let sum = 0;

 for(let i = 0; i < N - 2; i++) {
   let number;
   if(sum >= 100) {
     number = randomNumber(100 - sum, -100);
   } else if(sum <= -100) {
     number = randomNumber(100, -100 - sum);
   } else {
     number = randomNumber(100, -100);
   }
   sum += number;
   arr.push(number);
 }
 arr.push(Math.floor(-sum / 2), Math ceil(-sum / 2));

Try it

(不适用于N <4)

答案 1 :(得分:1)

有很多方法可以生成随机产生的值加起来为零的数组,但是它们对值的分布都有不同的含义。

例如,一种简单的方法是首先生成值并计算它们的平均值,然后从每个值中减去该平均值。这样的结果是,这些值可能最终超出了您最初想要的范围。例如,如果您随机生成[100,100,100,-100],则平均值为50,因此最终会得到[50,50,50,-150]。您可以从比实际需要的范围更窄的范围开始,以弥补这一不足;但这意味着,在更窄范围内或附近的值比在整个范围末尾的值更有可能出现。

另一种简单的方法是仅生成 n / 2 值,并为您生成的每个值同时包含该值和(例如,如果生成37,则结果将同时包含37和-37)。然后,您可以随机混洗结果;因此,例如,如果您随机生成[17,-84,12],则最终数组可能是[-12,17,-84,-17,84,12]。

。 。 。所有这一切都意味着您需要弄清楚自己的确切要求。随机性很复杂!

答案 2 :(得分:1)

这是另一种方式。从零开始,将随机数组元素拆分N-1次:

function myArr(N){
    let arr = [0];
    
    function randomNumber(min,max) {
        if (min > max) {
            let vMin = min;
            min = parseInt(max,10);
            max = parseInt(vMin,10);
        }
        return Math.floor(Math.random()*(max-min+1)+min);
    }
    
    function split(n){
        let low = Math.max(-100, n - 100);
        let high = Math.min(100, n + 100);
        let r = randomNumber(low, high);
  
        return [r, n - r]
    }
    
    for(let i = 0; i < N-1; i++) {
      let idx = ~~(Math.random() * arr.length);
      let newNums = split(arr[idx]);
      
      arr[idx] = newNums[0];
      arr.push(newNums[1]);
    }
    return arr;
}

console.log(myArr(5));

答案 3 :(得分:0)

这是我的解决方案,基本上,您需要进行for循环并开始添加元素。

无论何时添加元素,只需添加相同的元素* -1

您最终将得到一个总和为0的元素数组。

def fold_unfold(img_path):
    transt = transforms.Compose([transforms.ToTensor(),
    # transforms.Normalize(mean=[0.5,0.5, 0.5], std=[0.5, 0.5, 0.5])
        ])

    transp = transforms.Compose([
        # transforms.Normalize(mean=[0.5,0.5, 0.5], std=[0.5, 0.5, 0.5]),
        transforms.ToPILImage()
    ])
    img_t = transt(Image.open(img_path))
    img_t = img_t.unsqueeze(0)
    kernel = 300
    stride = 200
    img_shape = img_t.shape
    B, C, H, W = img_shape
    # number of pixels missing:
    pad_w = W % kernel
    pad_h = H % kernel
    # Padding the **INPUT** image with missing pixels:
    img_t = F.pad(input=img_t, pad=(pad_w//2, pad_w-pad_w//2, pad_h//2, pad_h-pad_h//2), mode='constant', value=0)
    img_shape = img_t.shape
    B, C, H, W = img_shape
    print("\n-----input shape: ", img_shape)

    patches = img_t.unfold(3, kernel, stride).unfold(2, kernel, stride).permute(0,1,2,3,5,4)

    print("\n-----patches shape:", patches.shape)
    # reshape output to match F.fold input
    patches = patches.contiguous().view(B, C, -1, kernel*kernel)
    print("\n", patches.shape) # [B, C, nb_patches_all, kernel_size*kernel_size]
    patches = patches.permute(0, 1, 3, 2) 
    print("\n", patches.shape) # [B, C, kernel_size*kernel_size, nb_patches_all]
    patches = patches.contiguous().view(B, C*kernel*kernel, -1)
    print("\n", patches.shape) # [B, C*prod(kernel_size), L] as expected by Fold
    # https://pytorch.org/docs/stable/nn.html#torch.nn.Fold

    output = F.fold(patches, output_size=(H, W), kernel_size=kernel, stride=stride)
    # mask that mimics the original folding:
    recovery_mask = F.fold(torch.ones_like(patches), output_size=(H,W), kernel_size=kernel, stride=stride)
    output = output/recovery_mask

    print(output.shape) # [B, C, H, W]
    aspil = transp(output[0])
    aspil.show()