PHPackages                             ozdemir/subset-finder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. ozdemir/subset-finder

ActiveLibrary

ozdemir/subset-finder
=====================

A simple package to find the subset of a given set.

2.1.2(8mo ago)28MITPHPPHP ^8.1CI passing

Since Feb 6Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/n1crack/subset-finder)[ Packagist](https://packagist.org/packages/ozdemir/subset-finder)[ Docs](https://github.com/ozdemir/subset-finder)[ GitHub Sponsors](https://github.com/n1crack)[ RSS](/packages/ozdemir-subset-finder/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (7)Versions (8)Used By (0)

SubsetFinder PHP Package
========================

[](#subsetfinder-php-package)

[![Latest Version on Packagist](https://camo.githubusercontent.com/91ec2a98be009ab96db94f6746c8386448bde29aeab60e4f33adcf2ded030f21/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f7a64656d69722f7375627365742d66696e646572)](https://packagist.org/packages/ozdemir/subset-finder)[![GitHub Tests Action Status](https://camo.githubusercontent.com/076a1a6be4bd11b56fae4cbdecd140bd4db02c723aaedff14ef79d7e6ffd68da/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6e31637261636b2f7375627365742d66696e6465722f72756e2d74657374732e796d6c)](https://github.com/n1crack/subset-finder/actions)[![GitHub](https://github.com/n1crack/subset-finder/raw/main/LICENSE.md)](https://github.com/n1crack/subset-finder/blob/main/LICENSE.md)

A powerful and flexible PHP package for efficiently finding subsets within collections based on quantity criteria. Built with Laravel collections and optimized for performance, memory efficiency, and developer experience.

Features
--------

[](#features)

- **High Performance**: Optimized algorithms with configurable memory limits
- **Flexible Configuration**: Multiple configuration profiles for different use cases
- **Performance Monitoring**: Built-in metrics and logging capabilities
- **Robust Error Handling**: Comprehensive validation and meaningful error messages
- **Type Safety**: Full PHP 8.1+ type support with strict validation
- **Comprehensive Testing**: 100% test coverage with Pest PHP
- **Laravel Integration**: Service provider, facade, and trait support
- **Memory Efficient**: Optional lazy evaluation for large datasets

Installation
------------

[](#installation)

```
composer require ozdemir/subset-finder
```

### Laravel Integration

[](#laravel-integration)

The package automatically registers with Laravel. If you need to publish the configuration:

```
php artisan vendor:publish --tag=subset-finder-config
```

Quick Start
-----------

[](#quick-start)

### Basic Usage

[](#basic-usage)

```
use Ozdemir\SubsetFinder\Subset;
use Ozdemir\SubsetFinder\SubsetCollection;
use Ozdemir\SubsetFinder\SubsetFinder;
use Ozdemir\SubsetFinder\SubsetFinderConfig;

// Define your collection and subset criteria
$collection = collect([
    new Product(id: 1, quantity: 11, price: 15),
    new Product(id: 2, quantity: 6, price: 5),
    new Product(id: 3, quantity: 6, price: 5),
]);

$subsetCollection = new SubsetCollection([
    Subset::of([1, 2])->take(5),  // Find 5 items from products 1 and 2
    Subset::of([3])->take(2),      // Find 2 items from product 3
]);

// Create and configure SubsetFinder
$config = new SubsetFinderConfig(
    idField: 'id',
    quantityField: 'quantity',
    sortField: 'price',        // Sort by price (ascending)
    sortDescending: false
);

$subsetFinder = new SubsetFinder($collection, $subsetCollection, $config);
$subsetFinder->solve();

// Get results
$foundSubsets = $subsetFinder->getFoundSubsets();
$remaining = $subsetFinder->getRemaining();
$maxSubsets = $subsetFinder->getSubsetQuantity();
```

### Using Configuration Profiles

[](#using-configuration-profiles)

```
// For large datasets (512MB memory, lazy evaluation enabled)
$subsetFinder = new SubsetFinder(
    $collection,
    $subsetCollection,
    SubsetFinderConfig::forLargeDatasets()
);

// For performance (64MB memory, lazy evaluation disabled)
$subsetFinder = new SubsetFinder(
    $collection,
    $subsetCollection,
    SubsetFinderConfig::forPerformance()
);

// For balanced approach (256MB memory, lazy evaluation enabled)
$subsetFinder = new SubsetFinder(
    $collection,
    $subsetCollection,
    SubsetFinderConfig::forBalanced()
);
```

### Using the Facade

[](#using-the-facade)

```
use Ozdemir\SubsetFinder\Facades\SubsetFinder;

// Create with default configuration
$subsetFinder = SubsetFinder::create($collection, $subsetCollection);

// Create with specific profile
$subsetFinder = SubsetFinder::forLargeDatasets($collection, $subsetCollection);
$subsetFinder = SubsetFinder::forPerformance($collection, $subsetCollection);
```

### Using the Trait

[](#using-the-trait)

```
use Ozdemir\SubsetFinder\Traits\HasSubsetOperations;

class ProductCollection extends Collection
{
    use HasSubsetOperations;
}

$products = new ProductCollection([...]);

// Find subsets directly on the collection
$subsetFinder = $products->findSubsets($subsetCollection);

// Use profiles
$subsetFinder = $products->findSubsetsWithProfile($subsetCollection, 'large_datasets');

// Check feasibility
if ($products->canSatisfySubsets($subsetCollection)) {
    // Proceed with subset creation
}
```

Use Cases
---------

[](#use-cases)

### E-commerce Bundle Creation

[](#e-commerce-bundle-creation)

```
$products = collect([
    new Product(id: 1, quantity: 100, price: 10),  // T-shirt
    new Product(id: 2, quantity: 50, price: 5),    // Socks
    new Product(id: 3, quantity: 25, price: 20),   // Hat
]);

$bundles = new SubsetCollection([
    Subset::of([1, 2])->take(2),  // T-shirt + Socks bundle
    Subset::of([1, 3])->take(1),  // T-shirt + Hat bundle
]);

$subsetFinder = new SubsetFinder($products, $bundles);
$subsetFinder->solve();

// Create 25 T-shirt + Socks bundles
// Create 25 T-shirt + Hat bundles
// Remaining: 25 T-shirts, 0 socks, 0 hats
```

### Inventory Management

[](#inventory-management)

```
$inventory = collect([
    new Item(id: 'A', quantity: 100, category: 'electronics'),
    new Item(id: 'B', quantity: 200, category: 'clothing'),
    new Item(id: 'C', quantity: 150, category: 'books'),
]);

$orders = new SubsetCollection([
    Subset::of(['A', 'B'])->take(10),  // Electronics + Clothing order
    Subset::of(['C'])->take(5),        // Books order
]);

$subsetFinder = new SubsetFinder($inventory, $orders);
$subsetFinder->solve();
```

Configuration
-------------

[](#configuration)

### Environment Variables

[](#environment-variables)

```
SUBSET_FINDER_MAX_MEMORY=256M
SUBSET_FINDER_LAZY_EVALUATION=true
SUBSET_FINDER_LOGGING=true
SUBSET_FINDER_LOG_CHANNEL=subset-finder
SUBSET_FINDER_LOG_LEVEL=info
```

### Configuration File

[](#configuration-file)

```
// config/subset-finder.php
return [
    'defaults' => [
        'id_field' => 'id',
        'quantity_field' => 'quantity',
        'sort_field' => 'id',
        'sort_descending' => false,
        'max_memory_usage' => env('SUBSET_FINDER_MAX_MEMORY', 128 * 1024 * 1024),
        'enable_lazy_evaluation' => env('SUBSET_FINDER_LAZY_EVALUATION', true),
        'enable_logging' => env('SUBSET_FINDER_LOGGING', false),
    ],

    'profiles' => [
        'large_datasets' => [
            'max_memory_usage' => 512 * 1024 * 1024,
            'enable_lazy_evaluation' => true,
            'enable_logging' => true,
        ],
        'performance' => [
            'max_memory_usage' => 64 * 1024 * 1024,
            'enable_lazy_evaluation' => false,
            'enable_logging' => false,
        ],
    ],
];
```

Performance Monitoring
----------------------

[](#performance-monitoring)

```
$subsetFinder = new SubsetFinder($collection, $subsetCollection);
$subsetFinder->solve();

// Get performance metrics
$metrics = $subsetFinder->getPerformanceMetrics();
// [
//     'execution_time_ms' => 45.23,
//     'memory_peak_mb' => 12.5,
//     'memory_increase_mb' => 8.2,
//     'collection_size' => 1000,
//     'subset_count' => 5,
//     'found_subsets_count' => 5,
//     'remaining_items_count' => 50
// ]

// Check solution quality
$isOptimal = $subsetFinder->isOptimal();           // true if no remaining items
$efficiency = $subsetFinder->getEfficiencyPercentage(); // 95.2%
```

Error Handling
--------------

[](#error-handling)

```
use Ozdemir\SubsetFinder\Exceptions\InvalidArgumentException;
use Ozdemir\SubsetFinder\Exceptions\InsufficientQuantityException;

try {
    $subsetFinder = new SubsetFinder($collection, $subsetCollection);
    $subsetFinder->solve();
} catch (InvalidArgumentException $e) {
    // Handle invalid input (empty collection, invalid items, etc.)
    Log::error('Invalid subset finder input: ' . $e->getMessage());
} catch (InsufficientQuantityException $e) {
    // Handle insufficient quantities
    Log::warning('Cannot create subsets: ' . $e->getMessage());
}
```

Testing
-------

[](#testing)

```
# Run tests
composer test

# Run tests with coverage
composer test-coverage

# Run static analysis
composer analyse
```

Performance Tips
----------------

[](#performance-tips)

1. **Use appropriate configuration profiles** for your dataset size
2. **Enable lazy evaluation** for large collections to reduce memory usage
3. **Monitor memory usage** and adjust `max_memory_usage` accordingly
4. **Use meaningful sort fields** to optimize subset selection
5. **Consider batch processing** for very large datasets

Advanced Usage
--------------

[](#advanced-usage)

### Custom Logging

[](#custom-logging)

```
use Psr\Log\LoggerInterface;

class CustomLogger implements LoggerInterface
{
    // Implement logger methods
}

$subsetFinder = new SubsetFinder(
    $collection,
    $subsetCollection,
    $config,
    new CustomLogger()
);
```

### Memory Management

[](#memory-management)

```
// Check memory before processing
if (memory_get_usage(true) > $config->maxMemoryUsage) {
    throw new \Exception('Insufficient memory for processing');
}

// Process in batches for very large datasets
$batchSize = 1000;
foreach ($collection->chunk($batchSize) as $batch) {
    // Process batch
}
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT License](LICENSE.md).

Support
-------

[](#support)

- **Documentation**: [GitHub Wiki](https://github.com/n1crack/subset-finder/wiki)
- **Issues**: [GitHub Issues](https://github.com/n1crack/subset-finder/issues)
- **Discussions**: [GitHub Discussions](https://github.com/n1crack/subset-finder/discussions)

Roadmap
-------

[](#roadmap)

### ✅ **Redis Caching Support**

[](#-redis-caching-support)

- **High-performance caching** with Redis integration
- **Memory-based fallback** when Redis is unavailable
- **Smart cache key generation** based on input data
- **Configurable TTL** and cache management
- **Automatic fallback** to memory cache on Redis failure

### ✅ **Parallel Processing**

[](#-parallel-processing)

- **Multi-process subset finding** for large datasets
- **Intelligent chunking** with optimal size calculation
- **System-aware process limits** based on CPU and memory
- **Simulated parallel processing** for development environments
- **Performance metrics** for parallel operations

### ✅ **Weighted Subset Selection**

[](#-weighted-subset-selection)

- **Multi-criteria optimization** with configurable weights
- **Advanced constraint handling** (ranges, custom functions)
- **Efficiency scoring** and ranking algorithms
- **Statistical analysis** with quartiles and distributions
- **Real-world optimization** scenarios (e-commerce, inventory)

### 🔄 **In Development**

[](#-in-development)

- Machine learning-based optimization
- GraphQL integration
- Performance benchmarking tools
- More configuration profiles

###  Health Score

41

—

FairBetter than 88% of packages

Maintenance82

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 73.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~111 days

Recently: every ~139 days

Total

6

Last Release

266d ago

Major Versions

1.0.3 → v2.1.12025-08-16

### Community

Maintainers

![](https://www.gravatar.com/avatar/0124f2d35be25c3386c1b0614c41112c20313f7b4acc46a502b475d5f6308403?d=identicon)[n1crack](/maintainers/n1crack)

---

Top Contributors

[![n1crack](https://avatars.githubusercontent.com/u/712404?v=4)](https://github.com/n1crack "n1crack (44 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (11 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")

---

Tags

collectiondiscountecommercephpsubset-selectionlaravelcollectionssubsetozdemir

###  Code Quality

TestsPest

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ozdemir-subset-finder/health.svg)

```
[![Health](https://phpackages.com/badges/ozdemir-subset-finder/health.svg)](https://phpackages.com/packages/ozdemir-subset-finder)
```

###  Alternatives

[grumpydictator/firefly-iii

Firefly III: a personal finances manager.

22.8k69.3k](/packages/grumpydictator-firefly-iii)[laravel/nightwatch

The official Laravel Nightwatch package.

3486.1M13](/packages/laravel-nightwatch)[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11320.2M21](/packages/anourvalar-eloquent-serialize)[api-platform/laravel

API Platform support for Laravel

59126.4k6](/packages/api-platform-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
