Skip to content

Commit 7e86668

Browse files
committed
Refactoring.
1 parent a5145ec commit 7e86668

27 files changed

Lines changed: 752 additions & 1226 deletions

src/Algorithm/BruteForce.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

src/Algorithm/BruteForceCustomA.php

Lines changed: 0 additions & 75 deletions
This file was deleted.

src/Algorithm/Greedy.php

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/Algorithm/Simple.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/Anytime.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace drupol\phpartition;
6+
7+
use drupol\phpartition\Partition\Partition;
8+
use drupol\phpartition\Partitions\Partitions;
9+
use drupol\phpermutations\Generators\Combinations;
10+
11+
/**
12+
* Class Anytime.
13+
*/
14+
class Anytime extends Partitioner
15+
{
16+
/**
17+
* @var \ArrayObject
18+
*/
19+
protected $dataset;
20+
21+
/**
22+
* @var int
23+
*/
24+
private $timeout;
25+
26+
/**
27+
* Linear constructor.
28+
*/
29+
public function __construct(int $timeout = 10)
30+
{
31+
$this->dataset = new \ArrayObject();
32+
$this->timeout = $timeout;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function add(...$values)
39+
{
40+
foreach ($values as $value) {
41+
$this->dataset->append($value);
42+
}
43+
44+
return $this;
45+
}
46+
47+
/**
48+
* @return int
49+
*/
50+
public function getTimeout()
51+
{
52+
return $this->timeout;
53+
}
54+
55+
/**
56+
* @param int $timeout
57+
*
58+
* @return $this
59+
*/
60+
public function setTimeout(int $timeout)
61+
{
62+
$this->timeout = $timeout;
63+
64+
return $this;
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
protected function fillPartitions(Partitions $partitions, array $dataset, int $chunks): void
71+
{
72+
$partition = new Partition($dataset);
73+
$partition->uasort(function ($left, $right) {
74+
return $left->getWeight() <=> $right->getWeight();
75+
});
76+
$dataset = $partition->getArrayCopy();
77+
78+
for ($p = $chunks; 1 < $p; --$p) {
79+
$partition = new Partition($dataset);
80+
81+
$best = $partition->getWeight();
82+
$target = $best / $p;
83+
$maxSize = \floor($partition->count() / $p);
84+
85+
$goodSubset = $this->getSubsets($maxSize, $dataset, $target, $best);
86+
87+
// We cannot use array_udiff() to compare objects because we only need
88+
// to remove one object at a time.
89+
foreach ($goodSubset as $item) {
90+
if (false !== $key = \array_search($item, $dataset, true)) {
91+
unset($dataset[$key]);
92+
}
93+
}
94+
95+
if (!empty($goodSubset)) {
96+
$partitionsArray[] = $goodSubset;
97+
}
98+
}
99+
100+
$partitionsArray[] = $dataset;
101+
102+
foreach ($partitionsArray as $key => $subset) {
103+
$partitions->partition($key)->exchangeArray($subset);
104+
}
105+
}
106+
107+
/**
108+
* @param float $maxSize
109+
* @param array $dataset
110+
* @param float $target
111+
* @param float $best
112+
*
113+
* @return array
114+
*/
115+
private function getSubsets($maxSize, $dataset, $target, $best)
116+
{
117+
$start_time = \time();
118+
$goodSubsets = $dataset;
119+
$timeout = $this->getTimeout();
120+
121+
for ($i = 1; $i <= $maxSize; ++$i) {
122+
$permutations = new Combinations($dataset, $i);
123+
foreach ($permutations->generator() as $subset) {
124+
if (\time() - $start_time > $timeout) {
125+
return $goodSubsets;
126+
}
127+
128+
$x = 0;
129+
foreach ($subset as $item) {
130+
$x += $item->getWeight();
131+
if (\abs($x - $target) < \abs($best - $target)) {
132+
$best = $x;
133+
$goodSubsets = $subset;
134+
}
135+
}
136+
}
137+
}
138+
139+
return $goodSubsets;
140+
}
141+
}

0 commit comments

Comments
 (0)