Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Pol Dellaiera
authored and
Pol Dellaiera
committed
Dec 19, 2016
0 parents
commit b9b00fe
Showing
19 changed files
with
1,311 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
build: | ||
environment: | ||
php: '5.6' | ||
|
||
filter: | ||
paths: | ||
- 'src/*' | ||
|
||
tools: | ||
external_code_coverage: | ||
timeout: 600 | ||
php_mess_detector: | ||
config: | ||
code_size_rules: { cyclomatic_complexity: true, npath_complexity: true, excessive_method_length: true, excessive_class_length: true, excessive_parameter_list: true, excessive_public_count: true, too_many_fields: true, too_many_methods: true, excessive_class_complexity: true } | ||
design_rules: { number_of_class_children: true, depth_of_inheritance: true, coupling_between_objects: true } | ||
unused_code_rules: { unused_local_variable: true, unused_private_method: true, unused_formal_parameter: true } | ||
naming_rules: { short_variable: true, long_variable: true, short_method: true, boolean_method_name: true } | ||
controversial_rules: { camel_case_class_name: true, camel_case_property_name: true, camel_case_method_name: true, camel_case_parameter_name: true, camel_case_variable_name: true } | ||
php_cs_fixer: | ||
config: | ||
level: all | ||
fixers: { unused_use: true, phpdoc_params: true, braces: true, php_closing_tag: true } | ||
php_analyzer: | ||
config: | ||
suspicious_code: { enabled: true, overriding_parameter: true, overriding_closure_use: true, parameter_closure_use_conflict: true, parameter_multiple_times: true, non_existent_class_in_instanceof_check: true, non_existent_class_in_catch_clause: true, assignment_of_null_return: true, non_commented_switch_fallthrough: true, non_commented_empty_catch_block: true, overriding_private_members: true, use_statement_alias_conflict: true, precedence_in_condition_assignment: true } | ||
verify_php_doc_comments: { enabled: true, parameters: true, return: true, suggest_more_specific_types: true, ask_for_return_if_not_inferrable: true, ask_for_param_type_annotation: true } | ||
loops_must_use_braces: { enabled: true } | ||
simplify_boolean_return: { enabled: true } | ||
phpunit_checks: { enabled: true } | ||
reflection_fixes: { enabled: true } | ||
use_statement_fixes: { enabled: true, order_alphabetically: true, remove_unused: true, preserve_multiple: false, preserve_blanklines: false } | ||
parameter_reference_check: { enabled: false } | ||
checkstyle: { enabled: false, no_trailing_whitespace: true, naming: { enabled: true, local_variable: '^[a-z][a-zA-Z0-9]*$', abstract_class_name: ^Abstract|Factory$, utility_class_name: 'Utils?$', constant_name: '^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$', property_name: '^[a-z][a-zA-Z0-9]*$', method_name: '^(?:[a-z]|__)[a-zA-Z0-9]*$', parameter_name: '^[a-z][a-zA-Z0-9]*$', interface_name: '^[A-Z][a-zA-Z0-9]*Interface$', type_name: '^[A-Z][a-zA-Z0-9]*$', exception_name: '^[A-Z][a-zA-Z0-9]*Exception$', isser_method_name: '^(?:is|has|should|may|supports)' } } | ||
unreachable_code: { enabled: false } | ||
check_access_control: { enabled: false } | ||
typo_checks: { enabled: false } | ||
check_variables: { enabled: false } | ||
check_calls: { enabled: true, too_many_arguments: true, missing_argument: true, argument_type_checks: lenient } | ||
dead_assignments: { enabled: false } | ||
check_usage_context: { enabled: true, foreach: { value_as_reference: true, traversable: true } } | ||
reflection_checks: { enabled: false } | ||
precedence_checks: { enabled: true, assignment_in_condition: true, comparison_of_bit_result: true } | ||
basic_semantic_checks: { enabled: false } | ||
unused_code: { enabled: false } | ||
deprecation_checks: { enabled: false } | ||
useless_function_calls: { enabled: false } | ||
metrics_lack_of_cohesion_methods: { enabled: false } | ||
metrics_coupling: { enabled: true, stable_code: { namespace_prefixes: { }, classes: { } } } | ||
doctrine_parameter_binding: { enabled: false } | ||
doctrine_entity_manager_injection: { enabled: false } | ||
symfony_request_injection: { enabled: false } | ||
doc_comment_fixes: { enabled: false } | ||
php_code_sniffer: | ||
config: | ||
standard: PSR2 | ||
sniffs: { psr2: { classes: { property_declaration_sniff: true }, methods: { method_declaration_sniff: true } } } | ||
sensiolabs_security_checker: true | ||
php_loc: true | ||
php_pdepend: true | ||
php_sim: true | ||
php_changetracking: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
language: php | ||
|
||
git: | ||
depth: 1 | ||
|
||
cache: | ||
directories: | ||
- $HOME/.cache/composer | ||
- $HOME/.composer/cache | ||
|
||
php: | ||
- 5.6 | ||
- 7.1 | ||
|
||
install: | ||
- composer install | ||
|
||
script: | ||
- composer phpunit | ||
|
||
after_success: | ||
- composer scrutinizer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
## PHPartition | ||
[![Build Status](https://travis-ci.org/drupol/phpartition.svg?branch=master)](https://travis-ci.org/drupol/phpartition) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/drupol/phpartition/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/drupol/phpartition/?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/58551f4d4d6466004c28cc8f/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/58551f4d4d6466004c28cc8f) | ||
|
||
In number theory and computer science, the partition problem is the task of deciding whether a given multiset S of items can be partitioned into multiple balanced subsets. | ||
|
||
## Requirements | ||
|
||
* PHP >= 5.6, | ||
* (optional) [PHPUnit](https://phpunit.de/) to run tests. | ||
|
||
## Example | ||
|
||
```php | ||
<?php | ||
|
||
include "./vendor/autoload.php"; | ||
|
||
$data = array(1, 5, 5, 11, 6, 7, 9, 3); | ||
$size = 3; | ||
|
||
$greedy = new \drupol\phpartition\Algorithm\Greedy(); | ||
$greedy->setData($data); | ||
$greedy->setPartition($size); | ||
$result = $greedy->getResult(); | ||
|
||
// $result is: | ||
/* | ||
* Array | ||
( | ||
[0] => Array | ||
( | ||
[0] => 9 | ||
[1] => 5 | ||
[2] => 1 | ||
) | ||
|
||
[1] => Array | ||
( | ||
[0] => 7 | ||
[1] => 6 | ||
[2] => 3 | ||
) | ||
|
||
[2] => Array | ||
( | ||
[0] => 11 | ||
[1] => 5 | ||
) | ||
) | ||
*/ | ||
|
||
|
||
$simple = new \drupol\phpartition\Algorithm\Simple(); | ||
$simple->setData($data); | ||
$simple->setPartition($size); | ||
$result = $simple->getResult(); | ||
|
||
// $result is: | ||
/* | ||
* Array | ||
( | ||
[0] => Array | ||
( | ||
[0] => 5 | ||
[1] => 11 | ||
) | ||
|
||
[1] => Array | ||
( | ||
[0] => 1 | ||
[1] => 7 | ||
[2] => 3 | ||
) | ||
|
||
[2] => Array | ||
( | ||
[0] => 5 | ||
[1] => 6 | ||
[2] => 9 | ||
) | ||
) | ||
*/ | ||
``` | ||
You may also pass objects or array but then, you'll have to define how to access their value. | ||
|
||
```php | ||
<?php | ||
|
||
include "./vendor/autoload.php"; | ||
|
||
$data = array( | ||
array( | ||
'item' => 'anything A', | ||
'weight' => 1, | ||
), | ||
array( | ||
'item' => 'anything B', | ||
'weight' => 2, | ||
), | ||
array( | ||
'item' => 'anything C', | ||
'weight' => 3, | ||
), | ||
array( | ||
'item' => 'anything D', | ||
'weight' => 4, | ||
), | ||
); | ||
$size = 2; | ||
|
||
$greedy = new \drupol\phpartition\Algorithm\Greedy(); | ||
$greedy->setData($data); | ||
$greedy->setPartition($size); | ||
$greedy->setItemAccessCallback(function($item) { | ||
return $item['weight']; | ||
}); | ||
$result = $greedy->getResult(); | ||
|
||
// $result is | ||
/* | ||
* Array | ||
( | ||
[0] => Array | ||
( | ||
[0] => Array | ||
( | ||
[item] => anything C | ||
[weight] => 3 | ||
) | ||
|
||
[1] => Array | ||
( | ||
[item] => anything B | ||
[weight] => 2 | ||
) | ||
|
||
) | ||
|
||
[1] => Array | ||
( | ||
[0] => Array | ||
( | ||
[item] => anything D | ||
[weight] => 4 | ||
) | ||
|
||
[1] => Array | ||
( | ||
[item] => anything A | ||
[weight] => 1 | ||
) | ||
|
||
) | ||
|
||
) | ||
*/ | ||
``` | ||
|
||
## TODO | ||
|
||
- Implement Complete Karmarkar-Karp (CKK) algorithm, | ||
- Tests, | ||
- Documentation, | ||
- Tests coverage. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"name": "drupol/phpartition", | ||
"description": "Partition problem for balanced arrays splitting made easy.", | ||
"type": "library", | ||
"homepage": "https://github.com/drupol/phpartition", | ||
"keywords": ["math", "numbers", "statistics", "partition", "greedy", "karmarkar", "karp"], | ||
"license": "GPL-2.0+", | ||
"support": { | ||
"issues": "https://github.com/drupol/phpartition/issues", | ||
"source": "https://github.com/drupol/phpartition" | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Pol Dellaiera", | ||
"email": "pol.dellaiera@protonmail.com" | ||
} | ||
], | ||
"require-dev": { | ||
"phpunit/phpunit": "^5.6", | ||
"mockery/mockery": "^0.9", | ||
"squizlabs/php_codesniffer": "^2.0", | ||
"satooshi/php-coveralls": "^1.0", | ||
"phpunit/php-code-coverage": "^4.0", | ||
"codacy/coverage": "dev-master", | ||
"scrutinizer/ocular": "^1.3" | ||
}, | ||
"scripts": { | ||
"phpcs": "./vendor/bin/phpcs --ignore=vendor .", | ||
"phpcbf": "./vendor/bin/phpcbf --ignore=vendor .", | ||
"phpunit": "./vendor/bin/phpunit --coverage-clover build/logs/clover.xml -c tests/phpunit.xml tests", | ||
"codacy": "./vendor/bin/codacycoverage clover build/logs/clover.xml", | ||
"coveralls": "./vendor/bin/coveralls", | ||
"scrutinizer": "./vendor/bin/ocular code-coverage:upload --format=php-clover build/logs/clover.xml" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"drupol\\phpartition\\": "src/", | ||
"drupol\\phpartition\\Tests\\": "tests/src/" | ||
} | ||
}, | ||
"require": { | ||
"alphazygma/combinatorics": "^1.0", | ||
"oefenweb/statistics": "^1.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
|
||
namespace drupol\phpartition\Algorithm; | ||
|
||
use drupol\phpartition\BasePartitionAlgorithm; | ||
use drupol\phpartition\PartitionAlgorithmInterface; | ||
use drupol\phpartition\Subset; | ||
use Math\Combinatorics\Permutation; | ||
|
||
/** | ||
* Class BruteForce. | ||
* | ||
* @package drupol\phpartition\Algorithm | ||
*/ | ||
class BruteForce extends BasePartitionAlgorithm implements PartitionAlgorithmInterface { | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function getResult() { | ||
$permutation = new Permutation(); | ||
$this->dataset->sortByValue('ASC'); | ||
|
||
$partitionSize = ($this->getPartition() > $this->dataset->count()) ? $this->dataset->count() : $this->getPartition(); | ||
|
||
for ($p=$partitionSize; $p > 1; $p--) { | ||
$best = $this->dataset->getWeight(); | ||
$target = ($best)/ $p; | ||
$goodSubset = array(); | ||
$maxSize = floor($this->dataset->count() / $p); | ||
|
||
for ($i = 1; $i <= $maxSize; $i++) { | ||
foreach ($permutation->getPermutations($this->dataset->getItems(), $i) as $subset) { | ||
$x = 0; | ||
foreach ($subset as $item) { | ||
$x += $item->getValue(); | ||
if (abs($x - $target) - abs($best - $target) < 0) { | ||
$best = $x; | ||
$goodSubset = $subset; | ||
} | ||
} | ||
} | ||
} | ||
|
||
$subset = new Subset(); | ||
$subset->setAlgo($this); | ||
$subset->addItems($goodSubset); | ||
$this->getSubsetContainer()->insert($subset); | ||
$this->dataset->deleteItems($goodSubset); | ||
} | ||
|
||
$subset = new Subset(); | ||
$subset->setAlgo($this); | ||
$subset->addItems($this->dataset->getItems()); | ||
$this->getSubsetContainer()->insert($subset); | ||
|
||
return $this->getSubsetContainer()->getSubsetsAndItemsAsArray(); | ||
} | ||
|
||
/** | ||
* @param \drupol\phpartition\Subset $subset | ||
* | ||
* @return int|mixed | ||
*/ | ||
public function getSubsetWeight(Subset $subset) { | ||
$sum = 0; | ||
|
||
foreach ($subset->getItems() as $item) { | ||
$sum += $item->getValue(); | ||
} | ||
|
||
return $sum; | ||
} | ||
|
||
} |
Oops, something went wrong.