2017-02-15 44 views
2

我已經嘗試過這個,並且無處不在尋找答案,並且似乎找不到合適的解決方法。我在這個網站上發現了很多答案,所以我已經註冊問我的問題。我有一個程序可以循環6個用戶並將它們分配給一個位置。用戶:Alpha,bravo,charlie,delta,echo和坦率。職位:1,2,3,4,5,6。我正在生成隨機數字以將用戶分配到他們的位置。我有一條規則,我正在檢查;沒有用戶可以被分配到相同的位置兩次。由於這個規則以及用戶隨機分配給電臺,有時唯一留給位置6的用戶是已經在前一輪中被分配到位置6的用戶。當發生這種情況時,我的程序崩潰了,理所當然。我如何克服這一點?我曾經有過這樣的例子,即該計劃將會做出正確的選擇,並且我有6次成功的輪換。我希望每次都有6次成功的輪換。我花了兩個星期的時間試圖弄清楚這一點。任何幫助,我可以得到將不勝感激。謝謝。我在下面粘貼了我的代碼。我正在使用Java。如果最後一個條件失敗,我該如何重新啓動一個do-while循環?

import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.EmptyBorder; 
import java.awt.Color; 
import java.awt.CardLayout; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import javax.swing.JButton; 


public class test extends JFrame implements ActionListener { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private JPanel contentPane; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        test frame = new test(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 



    //TODO 
    int randnum[] = new int [7]; 
    int numOfRotations = 1; 
    String[] String_CurrentOperator = new String[7]; 
    Random rand_opers = new Random(); 

    List<Integer> ArrayList_UsedRandNums = new ArrayList<>(); 
    List<List<String>> ArrayList_MainOperatorHistory = new ArrayList<List<String>>(); 
    List<String> ArrayList_AllOpers = new ArrayList<>(); 
    List<String> ArrayList_UsedOpers = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory1 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory2 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory3 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory4 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory5 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory6 = new ArrayList<>(); 


    public test() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 450, 300); 
     contentPane = new JPanel(); 
     contentPane.setBackground(Color.DARK_GRAY); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 
     contentPane.setLayout(new CardLayout(0, 0)); 

     JButton btnShuffle = new JButton("SHUFFLE"); 
     contentPane.add(btnShuffle, "name_253561263644851"); 
     btnShuffle.addActionListener(this); 

     ArrayList_AllOpers.add("POSITION ZERO"); 
     ArrayList_AllOpers.add("Alpha"); 
     ArrayList_AllOpers.add("Bravo"); 
     ArrayList_AllOpers.add("Charlie"); 
     ArrayList_AllOpers.add("Delta"); 
     ArrayList_AllOpers.add("Echo"); 
     ArrayList_AllOpers.add("Frank"); 

     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory2); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory3); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory4); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory5); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory6); 
    } 


    public void actionPerformed(ActionEvent arg0) { 

     /******************************* 
     *****ASSIGN ALL OPERATORS****** 
     *******************************/ 
     System.out.println("THIS IS ROTATION "+numOfRotations); 
     genRandoms(); 

     for(int i=1; i<6+1; i++){ 
      do{ 
       //randnum[i] = rand_opers.nextInt(6)+1; 
       String_CurrentOperator[i] = ArrayList_AllOpers.get(randnum[i]); 
      } 
      while(ArrayList_UsedOpers.contains(String_CurrentOperator[i]) || ArrayList_MainOperatorHistory.get(i).contains(String_CurrentOperator[i])); 

      ArrayList_UsedOpers.add(String_CurrentOperator[i]); //add to used names thus far 
     } 


     for(int i=1; i<6+1; i++){ 
      System.out.println(String_CurrentOperator[i]);      //Prints the name of the operator working on the station    
      ArrayList_MainOperatorHistory.get(i).add(String_CurrentOperator[i]); //adds operator to list of all users who have been assigned to this station 
     } 

     //Perform cleanup actions for next iteration of the loop 
     numOfRotations++;    //increment the rotation count by 1 
     ArrayList_UsedRandNums.clear(); //clear the list of randum numbers used 
     ArrayList_UsedOpers.clear(); //clear the list of assigned operators 
     System.out.println(""); 
    } 


    public void genRandoms(){ 
     for(int i=1; i<6+1; i++){ 
      do{ 
       randnum[i] = rand_opers.nextInt(6)+1; 
      } 
      while (ArrayList_UsedRandNums.contains(randnum[i])); 

      ArrayList_UsedRandNums.add(randnum[i]); //add randnum[i] to list of random numbers used thus far 
     } 
    } 
} 
+1

'Collections'中有'shuffle'兩個變種。你能用這個嗎? http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html – Brick

+0

什麼是ArrayList_AllOpers.add(「POSITION ZERO」);'?看起來你試圖避免數組的基於零的特性。不要,你需要擁抱它。 – weston

+0

哇,所有這些迴應已經!驚人。我會審視並嘗試並報告。非常感謝!韋斯頓你是對的。這次我故意試圖避免零基本性質。但我傾向於更多地接受它。 – theonedgo

回答

0

我已經想出了這個每次都有效的解決方案。感謝您的所有反饋。它可能不是最有效的代碼,但肯定按預期工作。我已經包含了一些調整,以允許計算多達10次旋轉。儘管如此,它真的很掙扎。希望有人能找到這個有用的。

import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.EmptyBorder; 
import java.awt.Color; 
import java.awt.CardLayout; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import javax.swing.JButton; 


public class test extends JFrame implements ActionListener { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private JPanel contentPane; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        test frame = new test(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 



    //TODO 
    int numOfStations = 6; 
    boolean cleared[] = new boolean[21]; 
    boolean finalCleared = false; 
    int randnum[] = new int [numOfStations+1]; 
    int numOfRotations = 1; 
    String[] String_CurrentOperator = new String[numOfStations+1]; 
    Random rand_opers = new Random(); 

    List<Integer> ArrayList_UsedRandNums = new ArrayList<>(); 
    List<List<String>> ArrayList_MainOperatorHistory = new ArrayList<List<String>>(); 
    List<String> ArrayList_AllOpers = new ArrayList<>(); 
    List<String> ArrayList_CurrentRotationOperators = new ArrayList<>(); 
    List<String> ArrayList_UsedOpers = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory1 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory2 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory3 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory4 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory5 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory6 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory7 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory8 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory9 = new ArrayList<>(); 
    List<String> ArrayList_OperatorHistory10 = new ArrayList<>(); 


    public test() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 450, 300); 
     contentPane = new JPanel(); 
     contentPane.setBackground(Color.DARK_GRAY); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 
     contentPane.setLayout(new CardLayout(0, 0)); 

     JButton btnShuffle = new JButton("SHUFFLE"); 
     contentPane.add(btnShuffle, "name_253561263644851"); 
     btnShuffle.addActionListener(this); 

     ArrayList_AllOpers.add("POSITION ZERO"); 
     ArrayList_AllOpers.add("A"); 
     ArrayList_AllOpers.add("B"); 
     ArrayList_AllOpers.add("C"); 
     ArrayList_AllOpers.add("D"); 
     ArrayList_AllOpers.add("E"); 
     ArrayList_AllOpers.add("F"); 
     ArrayList_AllOpers.add("Greek"); 
     ArrayList_AllOpers.add("Hospital"); 
     ArrayList_AllOpers.add("Indigo"); 
     ArrayList_AllOpers.add("Juliette"); 

     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory1); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory2); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory3); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory4); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory5); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory6); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory7); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory8); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory9); 
     ArrayList_MainOperatorHistory.add(ArrayList_OperatorHistory10); 
    } 


    public void actionPerformed(ActionEvent arg0) { 
     finalCleared = false; 
     for(int j=1; j<numOfStations+1; j++){  
      cleared[j]=false;   
     } 

     for(int j=numOfStations+1; j<21; j++){ 
      cleared[j]=true;    
     } 

     /******************************* 
     *****ASSIGN ALL OPERATORS****** 
     *******************************/ 
     //System.out.println("THIS IS ROTATION "+numOfRotations); 

     for(int i=1; i<1+1; i++){ 
      do{ 
       //clears the list of operators used during last rotation     
       ArrayList_CurrentRotationOperators.clear(); 

       //Assign the operators 
       for(int j=1; j<numOfStations+1; j++){  
        String_CurrentOperator[j] = ArrayList_AllOpers.get(randnum[j]);  
       } 

       //1. Ensure assigned operators or unique else fail finalCleared check 
       //2. If finalCleared is true then exit do and for loops 
       for(int j=1; j<numOfStations+1; j++){  
        if (ArrayList_MainOperatorHistory.get(j).contains(String_CurrentOperator[j]) || ArrayList_CurrentRotationOperators.contains(String_CurrentOperator[j])){ 
         cleared[j]=false; 
        } 
        else{ 
         cleared[j]=true; 
         ArrayList_CurrentRotationOperators.add(String_CurrentOperator[j]); 
        }   
       } 


       if (cleared[1]==true && cleared[2]==true && cleared[3]==true && cleared[4]==true && cleared[5]==true && cleared[6]==true 
         && cleared[7]==true && cleared[8]==true && cleared[9]==true && cleared[10]==true){ 
        finalCleared=true; 
       } 
       else{ 
        genRandoms(); 
       } 
      } 
      while(finalCleared == false); 
     } 

     //1. Prints the name of the operator working on the station 
     //2. Adds operator to list of all users who have been assigned to station 
     for(int i=1; i<numOfStations+1; i++){ 
      System.out.print(String_CurrentOperator[i]+" ");          
      ArrayList_MainOperatorHistory.get(i).add(String_CurrentOperator[i]); 
     } 

     //Perform cleanup actions for next iteration of the loop 
     //1. increment the rotation count by 1 
     numOfRotations++;    
     System.out.println(""); 
    } 



    /********************* 
    **genRandoms Method** 
    *********************/ 
    public void genRandoms(){ 
     for(int i=1; i<numOfStations+1; i++){ 
      randnum[i] = rand_opers.nextInt(numOfStations)+1; 
     } 
    } 
} 
0

我認爲你的邏輯看起來是正確的。但是,數組基於零,所以這就是爲什麼你有這個問題。試着改變你的兩個for循環是這樣的:

for(int i=0; i<6; i++){ 
1

問題可以改寫如下:

你有一個6x6的網格/矩陣:

1 2 3 4 5 6 
r1 A B C D E F 
r2 F A B C D E 
r3 E F A B C D 
r4 D E F A B C 
r5 C D E F A B 
r6 B C D E F A 

與柱有座位位置,這些行是旋轉,單元格值是Alpha,Beta,Charlie,... 您想隨機混洗這個網格,而不違反約束條件,即在每一行和一列中只出現一次值。

這與洗牌數獨網格相似。

這個任務不是太簡單。這裏給出了一個使用回溯的解決方案:How to Generate a -complete- sudoku board

一個簡單的解決方案可以是隨機交換初始網格的行和列。

這裏是我試圖找到一個有望回溯的bugfree解決方案: 這些行最初使用Fisher-Yates算法進行混洗。然後使用回溯從上至下驗證網格。

public static int[][] fillGrid(Random random, int size){ 
    int[][] grid = new int[size][size]; 

    do{ 
     for(int row = 0; row < size; row++){ 
      grid[row] = IntStream.rangeClosed(1, size).toArray(); 
      shuffleArray(grid[row], random); //randomize row     
     } 
    }while(!validate(grid, 0, 0)); //defensive: reroll if failed to validate (should not happen) 

    return grid; 
} 

private static boolean validate(int[][] grid, int row, int col){   
    if(col == grid.length){  
     if(row == grid.length-1){ 
      //end of grid reached -> whole grid is valid 
      return true; 
     } 
     //end of valid row reached -> validate next row   
     return validate(grid, row + 1, 0); 
    }  
    //search for a value that makes the whole row valid 
    for(int i = col; i < grid.length; i++){ 
     swap(grid[row], i, col); //try next value 

     //check if the current column is valid 
     boolean validCol = true; 
     for(int j = 0; j < row; j++){ 
      if(grid[j][col] == grid[row][col]){ 
       validCol = false; 
       break; 
      } 
     } 

     if (validCol && validate(grid, row, col + 1)){ 
      //the whole row is valid 
      return true; 
     } 
     swap(grid[row], i, col); //value does not fit -> swap back 
    } 
    //the row is invalid   
    return false; 
} 

private static void shuffleArray(int[] array, Random random){ 
    for (int i1 = array.length - 1; i1 > 0; i1--){ 
     int i2 = random.nextInt(i1 + 1); 
     swap(array, i1, i2); 
    } 
} 

private static void swap(int[] array, int i1, int i2){ 
    int temp = array[i1]; 
    array[i1] = array[i2]; 
    array[i2] = temp; 
} 

該方法調用fillGrid(new Random(), 6)會給你一個混洗網格,滿足約束條件。您可以在for循環內的每個迭代中使用[numOfRotations-1][i-1]訪問值。需要使用ArrayList_UsedOpersArrayList_MainOperatorHistory

+0

我喜歡它,但爲什麼簡單的解決方案質量低? – weston

+1

@weston在sudokus上應用交換方法會導致嚴重的隨機化網格。但是,這似乎只是這種情況,因爲3x3盒子的附加限制。所以,這對於這個更簡單的問題確實可能是一個很好的解決方案。現在,我嘗試了使用回溯。 – Calculator

+0

哇計算器!感謝您的辛勤工作,這看起來像我將不得不使用的解決方案,我希望我只是看不到解決方案,並希望它只是幾行代碼來修復大聲笑,但在這種情況下的回溯是最好的方法。再次感謝您的發佈。 – theonedgo

相關問題