2017-02-15 4 views
2

Я пробовал это сам и искал всюду для ответа и не мог найти подходящего обходного пути. Я нашел много ответов на этом сайте, прежде чем я зарегистрировался, чтобы задать свой вопрос. У меня есть программа, которая проходит через 6 пользователей и назначает их позиции. Пользователи: Alpha, bravo, charlie, delta, echo и frank. Позиции: 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

Существует два варианта 'shuffle' в' Collections'. Не могли бы вы просто использовать это? 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(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

Простым решением может быть случайная замена строк и столбцов исходной сетки.

Вот моя попытка для надежного решения без ошибок: откат: Строки изначально перетасовываются с использованием алгоритма Фишера-Йейта. Затем сетка проверяется сверху вниз с помощью обратного отслеживания.

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) даст вам перемешиваются сетку, которая удовлетворяет ограничения. Вы можете получить доступ к значениям с [numOfRotations-1][i-1] на каждой итерации внутри вашего цикла. Не требуется ArrayList_UsedOpers или ArrayList_MainOperatorHistory.

+0

Мне это нравится, но почему это простое решение низкого качества? – weston

+1

@weston Применение метода свопинга для sudokus приводит к плохо рандомизированной сетке. Однако это, по-видимому, только в случае, из-за дополнительного ограничения для ящиков 3x3. Таким образом, это действительно, вероятно, хорошее решение для этой более простой проблемы. На данный момент я попытался использовать backtracking. – Calculator

+0

Wow Calculator! Спасибо вам за тяжелую работу, это похоже на решение, которое мне придется использовать, я надеялся, что просто не вижу решения и надеюсь, что это всего лишь пара строк кода, чтобы исправить lol, но в этом случае обратное отслеживание лучший подход. Еще раз спасибо за сообщение. – theonedgo

Смежные вопросы