道歉,但这将是一个比代码更多的逻辑布局……
我不太清楚阵列(1,2,3,4)是第一道菜还是第一道菜的得分,但是我可能会使用这样的阵列
$array[$cook_id][$dish_number] = $score;
asort()每个数组使$array [$cook_id] = array($lowest_scored_dish,…,$highest);
考虑对特定厨师的加权偏好,使菜肴成为最佳菜肴与另一菜肴得分之间的差异.
作为一个非常简单的例子,烹饪a,b,c和菜肴0,1,2
$array['a'] = array(0=>100, 1=>50, 2=>0); // cook a prefers 0 over 1 with weight 50, over 2 with weight 100
$array['b'] = array(0=>100, 1=>100, 2=>50); // cook b prefers 0,1 over 2 with weight 50
$array['c'] = array(0=>50, 1=>50, 2=>100); // cook c prefers 2 with weight 50
在asort()之后:
$array [‘a’] = array(0 => 100,1 => 50,2> 0);
$array [‘b’] = array(0 => 100,1 => 100,2 => 50);
$array [‘c’] = array(2 => 100,0 => 50,1 => 50);
从烹饪’a’开始,他喜欢在他的下一道菜中获得50分(重量)的菜0. Cook’b’也喜欢dih 0,但是在下一道菜中重量为0.因此,它很可能(虽然还不确定烹饪’a’应该制作菜0.
考虑保留菜0并继续烹调’b’.不包括菜0,烹饪’b’更喜欢菜1.没有其他厨师喜欢菜1,所以烹饪’b’被指定为菜1.
Cook’c’默认为2.
这是一个非常方便的例子,每个厨师都可以烹饪一些个人最大的东西,但我希望它能说明一些可以解决的问题.
让它不那么方便:
$array['a'] = array(0=>75, 1=>50, 2=>0);
$array['b'] = array(0=>100, 1=>50, 2=>50);
$array['c'] = array(0=>100, 1=>25, 2=>25);
再次尝试烹饪’a’并看到0是首选,但这次重量为25. Cook’b’喜欢重量为50而烹饪’c’更喜欢重量为75. Cook’c’赢得菜0 .
回到可用的厨师名单,’a’喜欢1,体重50,但’b’更喜欢它的重量为0.’a’得到菜1,’b’得到菜2.
这仍然没有解决所有复杂问题,但它是朝着正确方向迈出的一步.有时,第一个烹饪/菜肴组合的假设是错误的.
方便不太方便:
$array['a'] = array(0=>200, 1=>148, 2=>148, 3=>0);
$array['b'] = array(0=>200, 1=>149, 2=>0, 3=>0);
$array['c'] = array(0=>200, 1=>150, 2=>147, 3=>147);
$array['d'] = array(0=>69, 1=>18, 2=>16, 3=>15);
‘a’得到0,因为那是最大值,没有其他人喜欢0有更高的权重
‘b’赢得1,体重149
‘d’胜2,因为’c’没有可用选项的偏好
‘c’得3分
得分:200 149 147 16 = 512
虽然这是一个很好的猜测,没有检查每个排列,但它可能是错误的.从这里开始,问:“如果一个厨师与其他任何一个厨师交易,那么总量会增加吗?”
答案是YES,a(0)d(2)= 200 16 = 216,但a(2)d(0)= 148 69 = 217.
我会留给你用加权方法编写“最佳猜测”的代码,但在那之后,这是一个很好的开始:
// a totally uneducated guess...
$picks = array(0=>'a', 1=>'b', 2=>'c', 3=>'d');
do {
$best_change = false;
$best_change_weight = 0;
foreach ($picks as $dish1 => $cook1) {
foreach ($picks as $dish2 => $cook2) {
if (($array[$cook1][$dish1] + $array[$cook2][$dish2]) <
($array[$cook1][$dish2] + $array[$cook2][$dish1]))
{
$old_score = $array[$cook1][$dish1] + $array[$cook2][$dish2];
$new_score = $array[$cook1][$dish2] + $array[$cook2][$dish1];
if (($new_score - $old_score) > $best_change_weight) {
$best_change_weight = $new_score - $old_score;
$best_change = $dish2;
}
}
}
if ($best_change !== false) {
$cook2 = $picks[$best_change];
$picks[$dish1] = $cook2;
$picks[$dish2] = $cook1;
break;
}
}
} while ($best_change !== false);
我找不到一个反例来证明这不起作用,但我怀疑这种情况
($array [$cook1] [$dish1] $array [$cook2] [$dish2])
==
($array [$cook1] [$dish2] $array [$cook2] [$dish1])
也许其他人会跟进这个“怎么回事?”的答案.
给定这个矩阵,括号中的项目是“选择”
[a1] a2 a3
b1 [b2] b3
c1 c2 [c3]
如果a1 b2 == a2 b1,那么’a’和’b’将不会切换菜肴.我不是100%肯定的情况是,如果存在矩阵,这是一个更好的选择:
a1 [a2] a3
b1 b2 [b3]
[c1] c2 c3
从第一个状态到第二个状态需要两个开关,第一个看起来是任意的,因为它不会改变总数.但是,只有通过这种任意改变才能进行最后一次切换.
我试图找到一个例子3×3这样,基于我上面写的“加权偏好”模型,第一个将被选中,但也使得真正的最佳选择由第二个给出.我无法找到一个例子,但这并不意味着它不存在.我现在不想做更多矩阵代数,但也许有人会在我离开的地方继续学习.哎呀,也许这个案子不存在,但我想我应该指出这个问题.
如果它确实有效,并且你从正确的选择开始,上面的代码将只循环64次(8×8)8个厨师/菜.如果选择不正确并且第一个厨师有变化,那么它将达到72.如果第8个厨师有变化,则最多为128.这可能会多次循环,但我怀疑它会接近所有40k组合所需的CPU周期.