mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-14 11:08:40 +00:00
Finish knapsack implementation
This commit is contained in:
parent
5ee0e67512
commit
4e3678d498
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knappsack
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
|
|
@ -13,12 +13,12 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Algorithm\Knappsack;
|
||||
namespace phpOMS\Algorithm\Knapsack;
|
||||
|
||||
/**
|
||||
* Backpack for the Knappsack problem
|
||||
* Backpack for the Knapsack problem
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knappsack
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
|
|
@ -93,6 +93,18 @@ class Backpack
|
|||
return $this->cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the max allowed costs for the items
|
||||
*
|
||||
* @return float
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getMaxCost() : float
|
||||
{
|
||||
return $this->maxCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items
|
||||
*
|
||||
|
|
@ -108,16 +120,17 @@ class Backpack
|
|||
/**
|
||||
* Add item to backpack
|
||||
*
|
||||
* @param Item $item Item
|
||||
* @param Item $item Item
|
||||
* @param mixed $quantity Quantity of the item
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function addItem(Item $item) : void
|
||||
public function addItem(Item $item, $quantity = 1) : void
|
||||
{
|
||||
$this->items[] = $item;
|
||||
$this->value += $item->getValue();
|
||||
$this->cost += $item->getCost();
|
||||
$this->items[] = ['item' => $item, 'quantity' => $quantity];
|
||||
$this->value += $item->getValue() * $quantity;
|
||||
$this->cost += $item->getCost() * $quantity;
|
||||
}
|
||||
}
|
||||
87
Algorithm/Knapsack/Bounded.php
Normal file
87
Algorithm/Knapsack/Bounded.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Algorithm\Knapsack;
|
||||
|
||||
/**
|
||||
* Bounded knapsack algorithm
|
||||
*
|
||||
* This algorithm only works for integer cost, values and quantities!
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Bounded
|
||||
{
|
||||
/**
|
||||
* Fill the backpack with items
|
||||
*
|
||||
* This algorithm only works for integer cost, values and quantities!
|
||||
*
|
||||
* @param array $items Items to fill the backpack with ['item' => Item, 'quantity' => ?]
|
||||
* @param Backpack $backpack Backpack to fill
|
||||
*
|
||||
* @return Backpack
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function solve(array $items, Backpack $backpack) : Backpack
|
||||
{
|
||||
$n = \count($items);
|
||||
$maxCost = (int) $backpack->getMaxCost();
|
||||
$mm = \array_fill(0, ($maxCost + 1), 0);
|
||||
$m = [];
|
||||
$m[0] = $mm;
|
||||
|
||||
for ($i = 1; $i <= $n; ++$i) {
|
||||
$m[$i] = $mm;
|
||||
|
||||
for ($j = 0; $j <= $maxCost; ++$j) {
|
||||
$m[$i][$j] = $m[$i - 1][$j];
|
||||
|
||||
for ($k = 1; $k <= $items[$i - 1]['quantity']; $k++) {
|
||||
if ($k * ((int) $items[$i - 1]['item']->getCost()) > $j) {
|
||||
break;
|
||||
}
|
||||
|
||||
$v = $m[$i - 1][$j - $k * ((int) $items[$i - 1]['item']->getCost())] + $k * ((int) $items[$i - 1]['item']->getValue());
|
||||
|
||||
if ($v > $m[$i][$j]) {
|
||||
$m[$i][$j] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$s = 0;
|
||||
for ($i = $n, $j = $maxCost; $i > 0; --$i) {
|
||||
$s = 0;
|
||||
$v = $m[$i][$j];
|
||||
|
||||
for ($k = 0; $v !== $m[$i - 1][$j] + $k * ((int) $items[$i - 1]['item']->getValue()); ++$k) {
|
||||
$s++;
|
||||
$j -= (int) $items[$i - 1]['item']->getCost();
|
||||
}
|
||||
|
||||
if ($s > 0) {
|
||||
$backpack->addItem($items[$i - 1]['item'], $s);
|
||||
}
|
||||
}
|
||||
|
||||
return $backpack;
|
||||
}
|
||||
}
|
||||
61
Algorithm/Knapsack/Continuous.php
Normal file
61
Algorithm/Knapsack/Continuous.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Algorithm\Knapsack;
|
||||
|
||||
/**
|
||||
* Continuous knapsack algorithm
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Continuous
|
||||
{
|
||||
/**
|
||||
* Fill the backpack with items
|
||||
*
|
||||
* @param array $items Items to fill the backpack with ['item' => Item, 'quantity' => ?]
|
||||
* @param Backpack $backpack Backpack to fill
|
||||
*
|
||||
* @return Backpack
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function solve(array $items, Backpack $backpack) : Backpack
|
||||
{
|
||||
usort($items, function($a, $b) {
|
||||
return $a['item']->getValue() / $a['item']->getCost() < $b['item']->getValue() / $b['item']->getCost();
|
||||
});
|
||||
|
||||
$availableSpace = $backpack->getMaxCost();
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($availableSpace <= 0.0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$backpack->addItem(
|
||||
$item['item'],
|
||||
$quantity = \min($item['quantity'], $availableSpace / $item['item']->getCost())
|
||||
);
|
||||
|
||||
$availableSpace -= $quantity * $item['item']->getCost();
|
||||
}
|
||||
|
||||
return $backpack;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knappsack
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
|
|
@ -12,12 +12,12 @@
|
|||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Algorithm\Knappsack;
|
||||
namespace phpOMS\Algorithm\Knapsack;
|
||||
|
||||
/**
|
||||
* Item in the knappsack
|
||||
* Item in the Knapsack
|
||||
*
|
||||
* @package phpOMS\Algorithm\Knappsack
|
||||
* @package phpOMS\Algorithm\Knapsack
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
|
|
@ -30,7 +30,7 @@ class Item
|
|||
* @var float
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $value = 0.0;
|
||||
private float $value = 0.0;
|
||||
|
||||
/**
|
||||
* Cost of the item
|
||||
|
|
@ -38,7 +38,15 @@ class Item
|
|||
* @var float
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $cost = 0.0;
|
||||
private float $cost = 0.0;
|
||||
|
||||
/**
|
||||
* Name of the item
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private string $name = '';
|
||||
|
||||
/**
|
||||
* Cosntructor.
|
||||
|
|
@ -48,10 +56,11 @@ class Item
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function __construct(float $value, float $cost)
|
||||
public function __construct(float $value, float $cost, string $name = '')
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->cost = $cost;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,4 +86,16 @@ class Item
|
|||
{
|
||||
return $this->cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the item
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getName() : string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user