我自己尝试过,并且到处寻找答案,但似乎无法找到合适的解决方法。我之前在这个网站上找到了很多答案,所以我已经注册了问我的问题。我有一个程序循环通过6个用户并将它们分配到一个位置。用户:Alpha,bravo,charlie,delta,echo和frank。职位:1,2,3,4,5,6。我正在生成随机数以将用户分配到他们的位置。我有一个我要检查的规则;没有用户可以被分配到相同的位置两次。由于该规则以及用户到站的随机分配,有时用于位置6的唯一用户是已经在先前旋转中被分配到位置6的用户。当发生这种情况时,我的程序崩溃并且理所当然。我该如何克服这个问题?我有过这样的实例,程序将做出正确的选择,我有6次成功轮换。我希望每次都有6次成功轮换。我花了两周时间试图解决这个问题。我能得到的任何帮助将不胜感激。谢谢。我在下面粘贴了我的代码。我正在使用Java。
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
}
}
}
答案 0 :(得分: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
一个简单的解决方案可能是随机交换初始网格的行和列。
这是我尝试一种有希望无障碍的解决方案,其特点是回溯: 最初使用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_UsedOpers
或ArrayList_MainOperatorHistory
。
答案 1 :(得分:0)
我认为你的逻辑似乎是正确的。但是,数组是基于零的,所以这就是你遇到问题的原因。尝试改变你的两个循环,如下所示:
for(int i=0; i<6; i++){
答案 2 :(得分: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;
}
}
}