简体   繁体   English

php有内置的数组函数,可以为布尔结果排序/赋值吗?

[英]does php have built-in array functions that can sort/assign values for boolean result?

I have an array of orders, key represents order#. 我有一系列订单,key代表订单#。 each element contains an array of employees that can fulfill those orders represented by employee number. 每个元素都包含一系列员工,可以履行员工编号所代表的订单。

example

[0] =>         // <-- order#
    [0] => 0,
    [1] => 1,
    [2] => 2

[1] =>
    [0] => 0,
    [1] => 1,
    [2] => 2

[2] =>
    [0] => 3

[3] =>
    [0] => 3

so order 0 can be fulfilled by employee 0,1, or 2. order 1 as well. 所以订单0可以由员工0,1或2.订单1来履行。 orders 2 and 3 can only be fulfilled by employee 3. 订单2和3只能由员工3履行。

i need to return bool which is true if each order has one unique employee to fulfill it. 我需要返回bool,如果每个订单都有一个唯一的员工来实现它,那就是真的。 so in this case return false because only one employee is available to fulfill orders 2 and 3 and cant be assigned to both. 因此,在这种情况下返回false,因为只有一名员工可以履行订单2和3,并且无法分配给他们。

i hope that makes sense. 我希望这是有道理的。 tapping this out on my phone agh 在我的手机上轻拍这个

This is a php function I wrote quickly that does what you want, I have quickly tested it and it seems to work properly. 这是一个我快速编写的php函数,可以完成你想要的,我已经快速测试了它,它似乎正常工作。

<?php

function compare($orders){

    if(sizeof($orders) == 0){
        return 1;
    }
    $quantity = array();
    foreach ($orders as $order) {
        if(sizeof($order) == 0){
            return 0;
        }
        foreach ($order as $employee) {
            if(array_key_exists($employee, $quantity)){
                $quantity[$employee]++;
            }
            else{
                $quantity[$employee] = 1;
            }
        }
    }
    $chosenEmployees = array_keys($quantity, min($quantity));
    $chosenEmployee = $chosenEmployees[0];

    $length = array();
    foreach ($orders as $key => $order) {
        $length[$key] = sizeof($order);
    }
    for ($i=0; $i < sizeof($orders); $i++) {
        $chosenOrders = array_keys($length, min($length));
        foreach ($chosenOrders as $orderKey) {
            if(in_array($chosenEmployee, $orders[$orderKey])){
                unset($orders[$orderKey]);
                foreach ($orders as $key1 => $order) {
                    foreach ($order as $key2 => $employee) {
                        if($employee == $chosenEmployee){
                            unset($orders[$key1][$key2]);
                        }           

                    }
                }
                return compare($orders);
            }
            else{
                unset($length[$orderKey]);
            }
        }
    }

}
$out = compare($orders);
?>

To use it, type compare($your_array_name), and the function will return 0 (false) or 1 (true). 要使用它,请键入compare($ your_array_name),该函数将返回0(false)或1(true)。
Hope it helps. 希望能帮助到你。

Edit: 编辑:
I doubt you'll find this code anywhere else because I wrote it for this question. 我怀疑你会在其他任何地方找到这个代码,因为我是为这个问题写的。
I have been working on proof and can prove that when the function returns true, it is true. 我一直在研究证明,并且可以证明当函数返回true时,它是真的。

The function returned true. 该函数返回true。
=> The orders array is empty. => orders数组为空。
=> Before that, the orders array contained one order that can be done by at least employee one. =>在此之前,orders数组包含一个订单,该订单至少可由一个员工完成。
=> Before that, the orders array contained two orders that can be done respectively by at least employee one and employee two. =>在此之前,orders数组包含两个订单,分别至少由员工1和员工2完成。
Via recurrence, we can deduce that n steps before the end, there were n orders, all doeable by at least one unique employee. 通过重复,我们可以在结束之前推断出n个步骤,有n个订单,所有订单都由至少一个唯一的员工执行。
If n = size of initial array, we can conclude that if the function returns true, it is correct. 如果n =初始数组的大小,我们可以得出结论,如果函数返回true,则它是正确的。

If this proof is not correct, please let me know. 如果此证明不正确,请告诉我。 I will edit my post again if I find proof for the second half. 如果我找到下半场的证据,我会再次编辑我的帖子。

One solution is to use array_reduce and array_diff to speculatively assign employees to orders. 一种解决方案是使用array_reducearray_diff来推测性地将员工分配给订单。

//Each step tries to add another employee id to the $carry array
function calc($carry, $item) 
{
    if (!$carry) {
        $carry = array();
    }
    $diff = array_diff($item, $carry);
    if (count($diff) > 0) {
        array_push($carry, reset($diff));
    }
    return $carry;
}

function cmp($a, $b)
{
    return count($a) - count($b);
}

function checkCondition($arrayToCheck) 
{
    uasort($arrayToCheck, 'cmp');
    $reduced = array_reduce($arrayToCheck, "calc");

    //If we have a shorter array than the number of orders, we have a problem
    return count($reduced) == count($arrayToCheck);
}

$o = array(
    array(0,1,2),
    array(0,1,2),
    array(3),
    array(3),
);

$result = checkCondition($o);

echo $result + " " + $result ? "Good" : "Bad";  //Should be Bad

$o = array(
    array(0,1,2),
    array(0,1,2),
    array(1),
    array(3),
);

$result = checkCondition($o);

echo $result + " " + $result ? "Good" : "Bad";  //Should be Good

Sorting the array first avoids the problem of "assigning" a worker to an order who MUST be assigned to a later order. 首先对数组进行排序可以避免将工作人员“分配”给必须分配给以后订单的订单的问题。

Algorithm 算法

Your main issue is about the algorithm. 您的主要问题是关于算法。 As discussed, the language is of secondary importance. 如上所述,该语言具有次要意义。

What you want is to 你想要的是什么

check if each order can be assigned one employee and each employee assigned one or no order 检查每个订单是否可以分配一个员工,每个员工是否分配了一个订单

You can draw it like a graph: 您可以像图表一样绘制它:

  • nodes are orders and employees 节点是订单和员工
  • links are possible assignments 链接是可能的分配

So you want to remove all necessary links so that 所以你想要删除所有必要的链接

  • each employee node has one or no link left, and 每个员工节点都有一个或没有链接,和
  • each order node still has one (or more) link left 每个订单节点仍然有一个 (或多个)链接

If you succeed, you have a solution and want the algorithm to return true . 如果您成功,您有一个解决方案,并希望算法返回true Otherwise, it should return false . 否则,它应该返回false


EDIT: J. Quick found an incredibly simple implementation that works. 编辑:J。Quick发现一个非常简单的实现工作。 I would love to get a proof of it or a reference of where he found it though. 我很想得到它的证明或参考他发现它的地方。

So I explain it here: 所以我在这里解释一下:

  1. If orders is empty, return true 如果订单为空,则返回true
  2. If any order of orders has no employee, return false 如果订单的任何订单没有员工,则返回false
  3. Get employee e with least number of orders 以最少的订单获得员工e
  4. Get e 's order o with least number of employees 获得E“的订单Ø与员工数最少
  5. Remove e and o from orders 订单中删除eo
  6. Repeat from 1. 从1开始重复。

JavaScript implementation JavaScript实现

function areAllOrdersFulfilled(orders) {
    while (orders.length !== 0) {
        if (undefined !== orders.find( o => o.length === 0))
            // An order has no employee to fulfill it
            return false;
        // Get employee and order to remove
        let employees = [];
        orders.forEach( order => {
            order.forEach( employee => {
                employees[employee] = (employees[employee] || 0) + 1;
            });
        });
        let employeeToRemove = employees.indexOf(employees.slice().sort()[0]), // Employee with less orders
            orderToRemove = orders
                .sort( (o1, o2) => o1.length - o2.length ) // In-place sort orders
                .findIndex( o => o.includes(employeeToRemove)); // Order with less employees
        // Remove
        orders.splice(orderToRemove,1);
        orders = orders.map( o => o.filter(e => e !== employeeToRemove) )
    }
    return true;
}

You can run it like that: 你可以像这样运行它:

const orders = [
    [0,1,2],
    [0,1,2],
    [3],
    [3]
];

console.log(areAllOrdersFulfilled(orders));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 内置函数是否会添加到调用堆栈中? - Does built-in functions add in a call stack? Angular Bootstrap-ui 是否有任何内置函数来处理打开或关闭的东西? - Does Angular Bootstrap-ui have any built-in functions to handle opening or closing things? Chrome有内置的调用堆栈吗? - Does Chrome have a built-in Call Stack? localStorage 可以为与它的内置方法同名的键赋值,我的 object 怎么做? - localStorage can assign values to keys of the same name as its built-in methods, how to do the same with my object? javascript规范是否保证可以将所有内置静态方法称为函数(没有接收器) - does the javascript spec guaratee that all built-in static methods can be called as functions (without the receiver) 为什么内置函数没有原型属性? - Why do built-in functions not have a prototype property? 方法链可以按照 Javascript 中内置函数的实现方式实现吗? - Can method chaining be implemented the way built-in functions in Javascript are implemented? sequelize是否有跟踪内置机制的任何变化? - Does sequelize have any change tracking built-in mechanism? Javascript中是否有内置的算术函数? - Are there built-in arithmetic functions in Javascript? 为什么这段代码没有将我的消息记录到 conosle 5 次(我使用了内置的 javascript 函数)? - Why is this code not logging my message 5 times to conosle (I have used built-in javascript functions)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM