如果 1+ 个实例具有相同(最小)值,如何从确定最小值的循环中随机选择一个对象?
How to randomly pick one object from a loop that determines smallest value, if 1+ instances have the same (smallest) value?
我写了一个Java程序,由三个相关的类组成;员工、客户和合同。在我的主要方法中,我创建了一个包含所有 3 类 的各种实例的数组;
// Create Clients
Client Client1 = new Client(1, "Client 1", 0);
Client Client2 = new Client(2, "Client 2", 0);
// Create Array of Clients
Client[] clients = new Client[] {Client1, Client2};
// Create Contracts
Contract Contract1 = new Contract("Contract 1", 1, 850, 4, 0, 1, 0);
Contract Contract2 = new Contract("Contract 2", 2, 500, 4, 0, 1, 0);
Contract Contract3 = new Contract("Contract 3", 3, 1500, 3, 0, 1, 0);
// Create Array of Contracts
Contract[] contracts = new Contract[] {Contract1, Contract2, Contract3};
// Create Employees
Employee Employee1 = new Employee(1, "Bradley", 0);
Employee Employee2 = new Employee(2, "Patrick", 0);
Employee Employee3 = new Employee(3, "Erin", 0);
Employee Employee4 = new Employee(4, "Jim", 0);
Employee Employee5 = new Employee(5, "Fredrick", 0);
// Create Array of Employees
Employee[] employees = new Employee[] {Employee1, Employee2, Employee3, Employee4, Employee5};
我在 Contract.Java 中有一个名为 assignContractToEmployeeWithLeastContracts 的函数,它接受 2 个参数、一组员工和合同。函数为:
// Assign contract to employee with least contracts
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
// Assign to employee with minimum contracts
int minContract = Integer.MAX_VALUE;
Employee employeeWithMinContracts = null;
for (Employee employee : employees) {
if (employee.getCurrentlyAssignedContracts() < minContract) {
// swap min and employee if true
employeeWithMinContracts = employee;
minContract = employeeWithMinContracts.getCurrentlyAssignedContracts();
}
}
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
我遇到的问题是我需要处理如果 2 名员工都分配了相同(最小)数量的合同会发生什么。如果发生这种情况,我如何随机挑选一名员工?我尝试在 foreach 循环中实现一个种子,但一直在破坏一切。
如有任何帮助,我们将不胜感激,
谢谢,
B
如果我理解正确,在您的 assignContractToEmployeeWithLeastContracts
方法中,如果他们有相同数量的合同,您希望将合同随机分配给任何一名员工。
因为目前您会将其分配给合同数量最少的第一位员工。
你的方法将变成这样:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Integer.MAX_VALUE;
List<Employee> employeesWithMinContracts = new ArrayList<Employee>();
for (Employee employee : employees) {
if (employee.getCurrentlyAssignedContracts() < minContract) {
employeesWithMinContracts.clear();
employeesWithMinContracts.add(employee);
minContract = employee.getCurrentlyAssignedContracts();
} else if (employee.getCurrentlyAssignedContracts() == minContract) {
employeesWithMinContracts.add(employee);
}
}
int randomIndex = (int)(Math.random() * employeesWithMinContracts.size());
employeesWithMinContracts.get(randomIndex).assignContract(contract);
}
我们将利用 Math.random
returns [0, 1] 之间的值这一事实,从而随机找到我们的 employeesWithMinContracts 列表索引。
备注:
请注意,我删除了 Employee
作为 assignContract
方法的参数。因为这个方法已经在有问题的 Employee
上调用了。
此外,您的实例名称应以小写字母开头以符合 Java 标准:
Contract1
变为 contract1
Employee1
变为 employee1
等...
如果您希望超过两名员工共享相同数量的最低合同,那么您需要在其中随机选择。您可以通过列出最低合同并随机选择一个来做到这一点。
// Assign contract to employee with least contracts
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
// Find the employees with the minimum contracts
int minContract = Integer.MAX_VALUE;
List <Employee> employeesWithMinContracts = new ArrayList<Employee>();
for (Employee employee : employees) {
//add duplicates to the list
if (employee.getCurrentlyAssignedContracts() == minContract) {
employeesWithMinContracts.add(employee);
}
// swap min and employee if true
if (employee.getCurrentlyAssignedContracts() < minContract) {
employeesWithMinContracts.clear();
employeesWithMinContracts.add(employee);
minContract = employee.getCurrentlyAssignedContracts();
}
}
//Randomly pick an employee from the group.
int random = (int)(Math.random() * employeesWithMinContracts.size() );
employeeWithMinContracts.assignContract(employeesWithMinContracts.get(random), contract);
}
如果您使用的是 Java 8 或更高版本,则以下内容可能更具可读性:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Arrays.stream(employees)
.mapToInt(Employee::getCurrentlyAssignedContracts)
.min()
.getAsInt();
Employee employeeWithMinContracts = Arrays.stream(employees)
.filter(e->e.getCurrentlyAssignedContracts() == minContract)
.findAny()
.get();
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
编辑
虽然上述解决方案中的 findAny()
表现出明确的不确定性,即它可以自由 select 流中的任何元素,让您无法控制元素被选择的可能性;你可能想要一个平均分布的概率。如果是这种情况,请参阅下面的第二个解决方案:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Arrays.stream(employees)
.mapToInt(Employee::getCurrentlyAssignedContracts)
.min()
.getAsInt();
List<Employee> minEmployees = Arrays.stream(employees)
.filter(e->e.getCurrentlyAssignedContracts() == minContract)
.collect(Collectors.toList());
Random r = new Random();
Employee employeeWithMinContracts = minEmployees.get(r.nextInt(minEmployees.size()));
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
我写了一个Java程序,由三个相关的类组成;员工、客户和合同。在我的主要方法中,我创建了一个包含所有 3 类 的各种实例的数组;
// Create Clients
Client Client1 = new Client(1, "Client 1", 0);
Client Client2 = new Client(2, "Client 2", 0);
// Create Array of Clients
Client[] clients = new Client[] {Client1, Client2};
// Create Contracts
Contract Contract1 = new Contract("Contract 1", 1, 850, 4, 0, 1, 0);
Contract Contract2 = new Contract("Contract 2", 2, 500, 4, 0, 1, 0);
Contract Contract3 = new Contract("Contract 3", 3, 1500, 3, 0, 1, 0);
// Create Array of Contracts
Contract[] contracts = new Contract[] {Contract1, Contract2, Contract3};
// Create Employees
Employee Employee1 = new Employee(1, "Bradley", 0);
Employee Employee2 = new Employee(2, "Patrick", 0);
Employee Employee3 = new Employee(3, "Erin", 0);
Employee Employee4 = new Employee(4, "Jim", 0);
Employee Employee5 = new Employee(5, "Fredrick", 0);
// Create Array of Employees
Employee[] employees = new Employee[] {Employee1, Employee2, Employee3, Employee4, Employee5};
我在 Contract.Java 中有一个名为 assignContractToEmployeeWithLeastContracts 的函数,它接受 2 个参数、一组员工和合同。函数为:
// Assign contract to employee with least contracts
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
// Assign to employee with minimum contracts
int minContract = Integer.MAX_VALUE;
Employee employeeWithMinContracts = null;
for (Employee employee : employees) {
if (employee.getCurrentlyAssignedContracts() < minContract) {
// swap min and employee if true
employeeWithMinContracts = employee;
minContract = employeeWithMinContracts.getCurrentlyAssignedContracts();
}
}
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
我遇到的问题是我需要处理如果 2 名员工都分配了相同(最小)数量的合同会发生什么。如果发生这种情况,我如何随机挑选一名员工?我尝试在 foreach 循环中实现一个种子,但一直在破坏一切。
如有任何帮助,我们将不胜感激,
谢谢, B
如果我理解正确,在您的 assignContractToEmployeeWithLeastContracts
方法中,如果他们有相同数量的合同,您希望将合同随机分配给任何一名员工。
因为目前您会将其分配给合同数量最少的第一位员工。
你的方法将变成这样:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Integer.MAX_VALUE;
List<Employee> employeesWithMinContracts = new ArrayList<Employee>();
for (Employee employee : employees) {
if (employee.getCurrentlyAssignedContracts() < minContract) {
employeesWithMinContracts.clear();
employeesWithMinContracts.add(employee);
minContract = employee.getCurrentlyAssignedContracts();
} else if (employee.getCurrentlyAssignedContracts() == minContract) {
employeesWithMinContracts.add(employee);
}
}
int randomIndex = (int)(Math.random() * employeesWithMinContracts.size());
employeesWithMinContracts.get(randomIndex).assignContract(contract);
}
我们将利用 Math.random
returns [0, 1] 之间的值这一事实,从而随机找到我们的 employeesWithMinContracts 列表索引。
备注:
请注意,我删除了
Employee
作为assignContract
方法的参数。因为这个方法已经在有问题的Employee
上调用了。此外,您的实例名称应以小写字母开头以符合 Java 标准:
Contract1
变为contract1
Employee1
变为employee1
等...
如果您希望超过两名员工共享相同数量的最低合同,那么您需要在其中随机选择。您可以通过列出最低合同并随机选择一个来做到这一点。
// Assign contract to employee with least contracts
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
// Find the employees with the minimum contracts
int minContract = Integer.MAX_VALUE;
List <Employee> employeesWithMinContracts = new ArrayList<Employee>();
for (Employee employee : employees) {
//add duplicates to the list
if (employee.getCurrentlyAssignedContracts() == minContract) {
employeesWithMinContracts.add(employee);
}
// swap min and employee if true
if (employee.getCurrentlyAssignedContracts() < minContract) {
employeesWithMinContracts.clear();
employeesWithMinContracts.add(employee);
minContract = employee.getCurrentlyAssignedContracts();
}
}
//Randomly pick an employee from the group.
int random = (int)(Math.random() * employeesWithMinContracts.size() );
employeeWithMinContracts.assignContract(employeesWithMinContracts.get(random), contract);
}
如果您使用的是 Java 8 或更高版本,则以下内容可能更具可读性:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Arrays.stream(employees)
.mapToInt(Employee::getCurrentlyAssignedContracts)
.min()
.getAsInt();
Employee employeeWithMinContracts = Arrays.stream(employees)
.filter(e->e.getCurrentlyAssignedContracts() == minContract)
.findAny()
.get();
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
编辑
虽然上述解决方案中的 findAny()
表现出明确的不确定性,即它可以自由 select 流中的任何元素,让您无法控制元素被选择的可能性;你可能想要一个平均分布的概率。如果是这种情况,请参阅下面的第二个解决方案:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Arrays.stream(employees)
.mapToInt(Employee::getCurrentlyAssignedContracts)
.min()
.getAsInt();
List<Employee> minEmployees = Arrays.stream(employees)
.filter(e->e.getCurrentlyAssignedContracts() == minContract)
.collect(Collectors.toList());
Random r = new Random();
Employee employeeWithMinContracts = minEmployees.get(r.nextInt(minEmployees.size()));
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}