使用权重数组平衡比例

时间:2016-09-12 07:24:53

标签: javascript arrays algorithm recursion combinations

我收到了以下提示: 假设你在秤的一侧有一个重量。给定一系列其他权重,看看比例是否会平衡。您可以在任一侧使用权重,而不必使用所有权重。

我正在尝试使用javascript实现解决方案,并且能够通过累积权重来解决其中一个条件的问题,直到匹配为止。最终,这仅适用于添加到刻度左侧的情况,但考虑到权重也可以添加到右侧,这不是最佳的。以下是我到目前为止的实施情况。

protected function schedule(Schedule $schedule)
    {
         $schedule->command('dbTS:demo')
                  ->everyMinute();
    }

  protected $commands = [
         Commands\Inspire::class,
         Commands\dbTS::class,
    ];

3 个答案:

答案 0 :(得分:0)

如果我正确理解你的问题,可以使用一些基本的递归来完成所有组合。假设您有3个选项:

1. include the weight on the left
2. include the weight on the right
3. dont include the weight 

总体思路如下:

f(A[],k,n){
  if(weights on both sides are euqal) return 
  if(k==n) return
  A[k]=0 //not included 
  f(A,k+1,n)
  A[k]=1 // included on the left
  f(A,k+1,n)
  A[k]=2 // included on the right
  f(A,k+1,n)
}

其中0表示k未包含的权重,1表示左侧k的权重,2表示权重位于右侧的k。这就是我在java中所做的(不太了解javascript):

static void print(int A[],int B[]) {
        for (int i = 0; i < A.length; i++) {
            if(A[i]==1) System.out.println(B[i]+" is on the left");
            else if(A[i]==2) System.out.println(B[i]+" is on the right");
        }
        System.out.println();
    }
    static boolean sum(int A[],int B[],int[] w){
        int left=0;
        int right=0;
        if(w[1]==1) left+= w[0];
        else if (w[1]==2) right+= w[0];

        for(int i=0;i<A.length;i++){
            if(A[i]==1) left+= B[i];
            if(A[i]==2) right+= B[i];
        }
        if(right==left) return true;

        return false;
    }


    static void g(int A[],int B[],int k,int n,int[] w){

        if(sum(B,A,w)){//works
            print(B,A);
            return;
        }
        if(k==n) return;//doesnt work

        B[k]=0;//not included
        g(A,B,k+1,n,w);
        B[k]=1;//included on the left
        g(A,B,k+1,n,w);
        B[k]=2;//included on the right
        g(A,B,k+1,n,w);

    }
    public static void main(String[] args) {
        int A[] = {4,5,6,7};//array of weights

        // put 0 if ith element not included 
        // put 1 if ith element is on the left  
        // put 2 if ith element is on the right
        int B[] = new int[A.length];

        // weight you start with: 
        // w[0] is weight amount w[1]
        // is whether its on the left right or neither (1,2,0)
        int[] w = {6,1};
        g(A,B,0,A.length,w);
    }

答案 1 :(得分:0)

这是一个用java编写的解决方案,如果需要,它将使用一两个石头来平衡可用重量。

public class scaleBalancing {
    
    public static void main(String args[]){
        int weights[] = {1,6,4,9};
        int balance[] = {6,4};
        ArrayList stoneA = new ArrayList();
        ArrayList stoneB = new ArrayList();
        boolean stone1 = false;
        boolean stone2 = false;
        for(int j=0;j<weights.length;j++){
            if(j==weights.length&&(weights[j]+balance[0]==weights[j-1]+balance[1]||weights[j]+balance[1]==weights[j-1]+balance[0])){
                stone1=true;
                stone2=true;
                stoneA.add(weights[j]);
                stoneB.add(weights[j-1]);
            }  
            else if(j<weights.length-1&&(weights[j]+balance[0]==weights[j+1]+balance[1]||weights[j]+balance[1]==weights[j+1]+balance[0])){
                stone1=true;
                stone2=true;
                stoneA.add(weights[j]);
                stoneB.add(weights[j+1]);
            }
            else if(weights[j]+balance[0]==balance[1]){
                stone1 =true;
                stoneA.add(weights[j]);
            }
            else if(weights[j]+balance[1]==balance[0]){
                stone2 = true;
                stoneB.add(weights[j]);
            }
        }
        if(stone1&&stone2){
            for(int i=0;i<stoneA.size();i++){
                System.out.println("{"+stoneA.get(i)+","+stoneB.get(i)+"}");
            }
        }
        else if(stone1){
            for(int i=0;i<stoneA.size();i++){
                System.out.println("{"+stoneA.get(i)+"}");
            }
        }
        else if(stone2){
            for(int i=0;i<stoneB.size();i++){
                System.out.println("{"+stoneB.get(i)+"}");
            }
        }
    }
}

答案 2 :(得分:0)

这是一个老问题,最近又复活了。到目前为止给出的答案都没有尝试按照要求使用 Javascript 来做到这一点。这是一个应该有效但不会因效率而获得任何奖项的方法。几乎可以肯定有一些众所周知的算法会比这更好(在最坏的情况下是 library(car) #> Loading required package: carData res <- Anova(lm(cbind(Sepal.Width, Sepal.Length, Petal.Width) ~ Species + Petal.Length, iris)) res #> #> Type II MANOVA Tests: Pillai test statistic #> Df test stat approx F num Df den Df Pr(>F) #> Species 2 0.70215 26.149 6 290 < 2.2e-16 *** #> Petal.Length 1 0.63487 83.461 3 144 < 2.2e-16 *** #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 str(get_summary_for_print(res)) #> Classes 'anova' and 'data.frame': 2 obs. of 6 variables: #> $ Df : num 2 1 #> $ test stat: num 0.702 0.635 #> $ approx F : num 26.1 83.5 #> $ num Df : num 6 3 #> $ den Df : num 290 144 #> $ Pr(>F) : num 7.96e-25 2.41e-31 #> - attr(*, "heading")= chr "\nType II MANOVA Tests: Pillai test statistic" 。)但这至少相当优雅。

O (n ^ 2)

我们有两个简单的案例。如果秤已经平衡(并且不为空),我们返回 const canBalance = ([w, ...ws], left = 0, right = 0) => left == right && left + right > 0 ? true : w == undefined ? false : canBalance (ws, left, right) || canBalance (ws, left + w, right) || canBalance (ws, left, right + w) console .log (canBalance ([3, 6, 2, 5, 1])) //=> true console .log (canBalance ([1, 2, 4, 8, 16])) //=> false console .log (canBalance ([5, 5])) //=> true。如果没有剩余的权重,我们返回 true。 (请注意,这些检查必须按此顺序进行,否则我们会错过最后一个砝码平衡的情况。)

在主要情况下,我们测试三种可能性,如果其中一种为真则短路。情况是,如果我们排除第一个权重,将其放在左侧,或将其放在右侧,然后使用较短的一组权重重复。

因为这可能远非最佳,所以我没有费心进行一项明显的优化。我们可以检查所有剩余的权重是否小于边之间的差值,如果是,则返回 `false。这将涉及在最后一个案例之前添加它:

false

使用明显的 : w + sum (ws) < Math .abs (left - right) ? false 函数。