非平凡Java数学练习

非平凡Java数学练习,java,multithreading,math,recursion,geometry,Java,Multithreading,Math,Recursion,Geometry,我被问到这个问题是为了测试我的编程能力。虽然我觉得这和编程一样重要。我真的失败了,但我想知道是怎么做的,以供将来参考 理想的答案是使用递归和线程 你侄女的生日礼物是一套积木,她决定用3英寸×1英寸和4.5英寸×1英寸的积木做一块嵌板。对于结构完整性,块之间的空间不得在相邻行中对齐。例如,下面的13.5“×3”面板是不可接受的,因为前两行中的块之间的一些空间如虚线所示排列在一起 有2种方法可以构建7.5英寸×1英寸面板,2种方法可以构建7.5英寸×2英寸面板,4种方法可以构建12英寸×3英寸面板,

我被问到这个问题是为了测试我的编程能力。虽然我觉得这和编程一样重要。我真的失败了,但我想知道是怎么做的,以供将来参考

理想的答案是使用递归和线程

你侄女的生日礼物是一套积木,她决定用3英寸×1英寸和4.5英寸×1英寸的积木做一块嵌板。对于结构完整性,块之间的空间不得在相邻行中对齐。例如,下面的13.5“×3”面板是不可接受的,因为前两行中的块之间的一些空间如虚线所示排列在一起

有2种方法可以构建7.5英寸×1英寸面板,2种方法可以构建7.5英寸×2英寸面板,4种方法可以构建12英寸×3英寸面板,7958种方法可以构建27英寸×5英寸面板。你侄女有多少种不同的方法来制作一个48英寸×10英寸的面板?答案将符合64位整数。写一个程序来计算答案


这就是问题所在,我不知道从哪里开始学习数学。我知道我需要为第一行计算所有可能的组合。但我真的不知道怎么做。然后,您可以在特定线程上计算下一行的所有可能组合,以此类推。然后,每个第一行组合都可以获得自己的线程,并将其设置传递到递归算法中,该算法将当前行与最后一行进行比较,并找到可能的答案。但我不能真正编程,因为我不知道如何计算任何行的可能组合。如果我这样做了,那么也许我可以检查一下这是否是合法的一行,没有两个街区正好在彼此的顶部错开,然后移到下一个街区。可能每一行都是一个for循环,在代码方面围绕下一行嵌套。但再一次,我不知道在数学方面该怎么做

我认为你对这个问题有了很好的初步理解。如果我正确理解了你的想法,你应该在每个块的位置上递归,而不是在每个行的位置上-因为垂直方向的块将很快排除任何普通行

下面是我将采用的方法:您最终将在内存中显式或隐式地构建一棵树:树可以是在递归函数中传递的参数。树的节点将是树的状态-因此根没有放置块。你放第一个街区,我们会到达那里,那代表一个新的状态

目标是构造一组叶节点,这些叶节点在填充板时都是完整的,并且没有裂缝。那我们怎么去呢

对于每个块的放置,有4种替代现实:水平放置的3x1块、垂直放置的3x1块(称为1x3)、水平放置的4.5x1块和1x4.5块。对于这些选项中的每一个,您都将尝试合法地将块放置在行中的下一点。如果沿着块的线条进行的某些操作不与板边缘重叠,块不共享垂直边缘是合法的,那么您可以接受该板作为中间状态,并使用该新状态递归。如果它不合法,那么这个国家就必须被放弃

按照这种方式,前4个子节点将是左下角的一个块,如[3x1、1x3、4.5x1、1x4.5]。这四种状态中的每一种在四种配置中的一种配置的右侧都有一个块,依此类推

为了跨行移动,当你点击右边缘时,我会找到最低的空格,并在它们从左到右对齐时任意填充。当边缘参差不齐时,这足以修剪大型集合,但在级别平坦时(如刚开始时)仍然可以很好地进行修剪

本质上,对于每个中间状态,树最多有4个节点,边表示尝试的放置。如果无法合法地将块放置在该尝试放置的位置,则不会递归、修剪该可能性以及树的所有后代


这种蛮力方法应该可以得到一个完整的电路板,即使它的计算复杂度是天文数字。只有在这一点上,您才能正确地解决一些应该考虑与线程并行化的问题。递归问题往往很适合线程,因为每个递归通常可以并行化,而不会带来太多麻烦。请确保你先把它弄好。

这篇文章已经有将近5年的历史了,但也许我的答案对某些人有用。下面有两种解决方案。首先是没有多线程。第二个使用四个线程来解决问题。它计算48x4面板48x10的持续时间很长,但可以通过更改初始值轻松修改:

nbOfRows、nbOfCols、墙宽和墙宽

无多线程的解决方案:

import java.io.*;
import java.util.*;

class WallFlexOld
{
    static final float blocks[] = {3.0f, 4.5f};
    static final int nbOfRows = 4;
    static final int nbOfCols = 16;
    static final float wallWidth = 48.0f;
    static final float wall[][] = {
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                            };

    static long nbOfCombinations = 0;

    public static void main(String args[])
    {
        long startTime = System.currentTimeMillis();
        addBlock(0, 0);
        long workingTime = System.currentTimeMillis() - startTime;

        System.out.println("Working time: " + workingTime + "ms");
        System.out.println("noc: " + nbOfCombinations);
    }

    static void addBlock(int row, int col)
    {
        for(float b: blocks)
        {
            wall[row][col] = b;
            if(blockFit(row, col))
            {
                if(rowWidth(row) <= wallWidth)
                {
                    if(rowWidth(row) == wallWidth)
                    {
                        if(row == (nbOfRows - 1))
                            nbOfCombinations++;
                        else
                            addBlock(row + 1, 0);
                    }
                    else //rowWidth < wallWidth
                        addBlock(row, col + 1);

                }
            }   
            wall[row][col] = 0; 
        }
    }

    static float rowWidth(int row)
    {
        float width = 0;
        for(float b: wall[row])
            width = width + b;
        return width;
    }

    static boolean blockFit(int row, int col)
    {
        if(row == 0)
            return true;

        boolean fit = true;
        float currentLenght = 0;
        for(int i = 0; i < col; i++)
            currentLenght = currentLenght + wall[row][i];

        float lowerRowCurLenght = 0;
        for(float b: wall[row - 1])
        {
            lowerRowCurLenght = lowerRowCurLenght + b;
            if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
                fit = false;
        }

        return fit;
    }
}
import java.io.*;
import java.util.*;

class Wall implements Runnable
{
    private float blocks[];
    private int nbOfRows;
    private int nbOfCols;
    private float wallWidth;
    private float wall[][];
    private long nbOfCombinations = 0;
    private int row, col;

    public long getNbOfCombinations() { return this.nbOfCombinations; }

    Wall(float blocks[], int nbOfRows, int nbOfCols, float wallWidth, float wall[][], int row, int col)
    {
        this.blocks = blocks;
        this.nbOfRows = nbOfRows;
        this.nbOfCols = nbOfCols;
        this.wallWidth = wallWidth;
        this.wall = wall;
        this.row = row;
        this.col = col;
    }

    private boolean blockFit(int row, int col)
    {
        if(row == 0)
            return true;

        boolean fit = true;
        float currentLenght = 0;
        for(int i = 0; i < col; i++)
            currentLenght = currentLenght + wall[row][i];

        float lowerRowCurLenght = 0;
        for(float b: wall[row - 1])
        {
            lowerRowCurLenght = lowerRowCurLenght + b;
            if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
                fit = false;
        }

        return fit;
    }

    private float rowWidth(int row)
    {
        float width = 0;
        for(float b: wall[row])
            width = width + b;
        return width;
    }

    private void addBlock(int row, int col)
    {
        for(float b: blocks)
        {
            wall[row][col] = b;
            if(blockFit(row, col))
            {
                if(rowWidth(row) <= wallWidth)
                {
                    if(rowWidth(row) == wallWidth)
                    {
                        if(row == (nbOfRows - 1))
                            nbOfCombinations++;
                        else
                            addBlock(row + 1, 0);
                    }
                    else //rowWidth < wallWidth
                    {
                        addBlock(row, col + 1);
                    }
                }
            }
            wall[row][col] = 0;
        }
    }


    @Override
    public void run()
    {
        addBlock(row, col);
    }
}

class WallMT
{
    static final float blocks[] = {3.0f, 4.5f};
    static final int nbOfRows = 4;
    static final int nbOfCols = 16;
    static final float wallWidth = 48.0f;
    static final float wall[][] = {
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                            };

    public static void main(String args[])
    {
        wall[0][0] = blocks[0];
        wall[0][1] = blocks[0];
        Wall myWall1 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t1 = new Thread(myWall1);

        wall[0][0] = blocks[0];
        wall[0][1] = blocks[1];
        Wall myWall2 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t2 = new Thread(myWall2);

        wall[0][0] = blocks[1];
        wall[0][1] = blocks[0];
        Wall myWall3 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t3 = new Thread(myWall3);

        wall[0][0] = blocks[1];
        wall[0][1] = blocks[1];
        Wall myWall4 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t4 = new Thread(myWall4);

        long startTime = System.currentTimeMillis();
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        try
        {
            t1.join();  
            t2.join();
            t3.join();  
            t4.join();  
        }
        catch(InterruptedException ie)
        {
            System.out.println("Thread " + t1 + " interrupted.");
        }

        long workingTime = System.currentTimeMillis() - startTime;

        System.out.println("Working time: " + workingTime + "ms");
        System.out.println("noc: " + (myWall1.getNbOfCombinations() + myWall2.getNbOfCombinations() + myWall3.getNbOfCombinations() + myWall4.getNbOfCombinations()));
    }

    static private float[][] getWallCopy(float wall[][])
    {
        float tmpWall[][] = new float[nbOfRows][nbOfCols];

        for(int i = 0; i < nbOfRows; i++)
            for(int j = 0; j < nbOfCols; j++)
                tmpWall[i][j] = wall[i][j];

        return tmpWall;
    }
}
多线程解决方案:

import java.io.*;
import java.util.*;

class WallFlexOld
{
    static final float blocks[] = {3.0f, 4.5f};
    static final int nbOfRows = 4;
    static final int nbOfCols = 16;
    static final float wallWidth = 48.0f;
    static final float wall[][] = {
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                            };

    static long nbOfCombinations = 0;

    public static void main(String args[])
    {
        long startTime = System.currentTimeMillis();
        addBlock(0, 0);
        long workingTime = System.currentTimeMillis() - startTime;

        System.out.println("Working time: " + workingTime + "ms");
        System.out.println("noc: " + nbOfCombinations);
    }

    static void addBlock(int row, int col)
    {
        for(float b: blocks)
        {
            wall[row][col] = b;
            if(blockFit(row, col))
            {
                if(rowWidth(row) <= wallWidth)
                {
                    if(rowWidth(row) == wallWidth)
                    {
                        if(row == (nbOfRows - 1))
                            nbOfCombinations++;
                        else
                            addBlock(row + 1, 0);
                    }
                    else //rowWidth < wallWidth
                        addBlock(row, col + 1);

                }
            }   
            wall[row][col] = 0; 
        }
    }

    static float rowWidth(int row)
    {
        float width = 0;
        for(float b: wall[row])
            width = width + b;
        return width;
    }

    static boolean blockFit(int row, int col)
    {
        if(row == 0)
            return true;

        boolean fit = true;
        float currentLenght = 0;
        for(int i = 0; i < col; i++)
            currentLenght = currentLenght + wall[row][i];

        float lowerRowCurLenght = 0;
        for(float b: wall[row - 1])
        {
            lowerRowCurLenght = lowerRowCurLenght + b;
            if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
                fit = false;
        }

        return fit;
    }
}
import java.io.*;
import java.util.*;

class Wall implements Runnable
{
    private float blocks[];
    private int nbOfRows;
    private int nbOfCols;
    private float wallWidth;
    private float wall[][];
    private long nbOfCombinations = 0;
    private int row, col;

    public long getNbOfCombinations() { return this.nbOfCombinations; }

    Wall(float blocks[], int nbOfRows, int nbOfCols, float wallWidth, float wall[][], int row, int col)
    {
        this.blocks = blocks;
        this.nbOfRows = nbOfRows;
        this.nbOfCols = nbOfCols;
        this.wallWidth = wallWidth;
        this.wall = wall;
        this.row = row;
        this.col = col;
    }

    private boolean blockFit(int row, int col)
    {
        if(row == 0)
            return true;

        boolean fit = true;
        float currentLenght = 0;
        for(int i = 0; i < col; i++)
            currentLenght = currentLenght + wall[row][i];

        float lowerRowCurLenght = 0;
        for(float b: wall[row - 1])
        {
            lowerRowCurLenght = lowerRowCurLenght + b;
            if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
                fit = false;
        }

        return fit;
    }

    private float rowWidth(int row)
    {
        float width = 0;
        for(float b: wall[row])
            width = width + b;
        return width;
    }

    private void addBlock(int row, int col)
    {
        for(float b: blocks)
        {
            wall[row][col] = b;
            if(blockFit(row, col))
            {
                if(rowWidth(row) <= wallWidth)
                {
                    if(rowWidth(row) == wallWidth)
                    {
                        if(row == (nbOfRows - 1))
                            nbOfCombinations++;
                        else
                            addBlock(row + 1, 0);
                    }
                    else //rowWidth < wallWidth
                    {
                        addBlock(row, col + 1);
                    }
                }
            }
            wall[row][col] = 0;
        }
    }


    @Override
    public void run()
    {
        addBlock(row, col);
    }
}

class WallMT
{
    static final float blocks[] = {3.0f, 4.5f};
    static final int nbOfRows = 4;
    static final int nbOfCols = 16;
    static final float wallWidth = 48.0f;
    static final float wall[][] = {
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
                            };

    public static void main(String args[])
    {
        wall[0][0] = blocks[0];
        wall[0][1] = blocks[0];
        Wall myWall1 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t1 = new Thread(myWall1);

        wall[0][0] = blocks[0];
        wall[0][1] = blocks[1];
        Wall myWall2 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t2 = new Thread(myWall2);

        wall[0][0] = blocks[1];
        wall[0][1] = blocks[0];
        Wall myWall3 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t3 = new Thread(myWall3);

        wall[0][0] = blocks[1];
        wall[0][1] = blocks[1];
        Wall myWall4 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
        Thread t4 = new Thread(myWall4);

        long startTime = System.currentTimeMillis();
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        try
        {
            t1.join();  
            t2.join();
            t3.join();  
            t4.join();  
        }
        catch(InterruptedException ie)
        {
            System.out.println("Thread " + t1 + " interrupted.");
        }

        long workingTime = System.currentTimeMillis() - startTime;

        System.out.println("Working time: " + workingTime + "ms");
        System.out.println("noc: " + (myWall1.getNbOfCombinations() + myWall2.getNbOfCombinations() + myWall3.getNbOfCombinations() + myWall4.getNbOfCombinations()));
    }

    static private float[][] getWallCopy(float wall[][])
    {
        float tmpWall[][] = new float[nbOfRows][nbOfCols];

        for(int i = 0; i < nbOfRows; i++)
            for(int j = 0; j < nbOfCols; j++)
                tmpWall[i][j] = wall[i][j];

        return tmpWall;
    }
}
所以你试过什么了吗?我没有诚实地告诉我们你做了什么。