diff --git a/issue17a.lp b/issue17a.lp new file mode 100644 index 0000000..b271efd --- /dev/null +++ b/issue17a.lp @@ -0,0 +1,61 @@ +\Problem name: + +Minimize +OBJROW: 7740 item0_in_bin1 + 489 item1_in_bin1 + 152 item2_in_bin1 + 3410 item3_in_bin1 + 9948 item4_in_bin1 + 7862 item5_in_bin1 + 8519 item6_in_bin1 + 3212 item7_in_bin1 + 8798 item8_in_bin1 + 4979 item9_in_bin1 + + 2178 item10_in_bin1 + 5984 item11_in_bin1 + 2518 item12_in_bin1 + 3270 item13_in_bin1 + 7183 item14_in_bin1 +Subject To +constr(0): item0_in_bin0 >= 0 +constr(1): item1_in_bin0 >= 0 +constr(2): item2_in_bin0 >= 0 +constr(3): item3_in_bin0 >= 0 +constr(4): item4_in_bin0 >= 0 +constr(5): item5_in_bin0 >= 0 +constr(6): item6_in_bin0 >= 0 +constr(7): item7_in_bin0 >= 0 +constr(8): item8_in_bin0 >= 0 +constr(9): item9_in_bin0 >= 0 +constr(10): item10_in_bin0 >= 0 +constr(11): item11_in_bin0 >= 0 +constr(12): item12_in_bin0 >= 0 +constr(13): item13_in_bin0 >= 0 +constr(14): item14_in_bin0 >= 0 +constr(15): item0_in_bin1 >= 0 +constr(16): item1_in_bin1 >= 0 +constr(17): item2_in_bin1 >= 0 +constr(18): item3_in_bin1 >= 0 +constr(19): item4_in_bin1 >= 0 +constr(20): item5_in_bin1 >= 0 +constr(21): item6_in_bin1 >= 0 +constr(22): item7_in_bin1 >= 0 +constr(23): item8_in_bin1 >= 0 +constr(24): item9_in_bin1 >= 0 +constr(25): item10_in_bin1 >= 0 +constr(26): item11_in_bin1 >= 0 +constr(27): item12_in_bin1 >= 0 +constr(28): item13_in_bin1 >= 0 +constr(29): item14_in_bin1 >= 0 +constr(30): item0_in_bin0 + item0_in_bin1 = 1 +constr(31): item1_in_bin0 + item1_in_bin1 = 1 +constr(32): item2_in_bin0 + item2_in_bin1 = 1 +constr(33): item3_in_bin0 + item3_in_bin1 = 1 +constr(34): item4_in_bin0 + item4_in_bin1 = 1 +constr(35): item5_in_bin0 + item5_in_bin1 = 1 +constr(36): item6_in_bin0 + item6_in_bin1 = 1 +constr(37): item7_in_bin0 + item7_in_bin1 = 1 +constr(38): item8_in_bin0 + item8_in_bin1 = 1 +constr(39): item9_in_bin0 + item9_in_bin1 = 1 +constr(40): item10_in_bin0 + item10_in_bin1 = 1 +constr(41): item11_in_bin0 + item11_in_bin1 = 1 +constr(42): item12_in_bin0 + item12_in_bin1 = 1 +constr(43): item13_in_bin0 + item13_in_bin1 = 1 +constr(44): item14_in_bin0 + item14_in_bin1 = 1 +constr(45): -7740 item0_in_bin0 + 7740 item0_in_bin1 -489 item1_in_bin0 + 489 item1_in_bin1 -152 item2_in_bin0 + 152 item2_in_bin1 -3410 item3_in_bin0 + 3410 item3_in_bin1 -9948 item4_in_bin0 + 9948 item4_in_bin1 + -7862 item5_in_bin0 + 7862 item5_in_bin1 -8519 item6_in_bin0 + 8519 item6_in_bin1 -3212 item7_in_bin0 + 3212 item7_in_bin1 -8798 item8_in_bin0 + 8798 item8_in_bin1 -4979 item9_in_bin0 + 4979 item9_in_bin1 + -2178 item10_in_bin0 + 2178 item10_in_bin1 -5984 item11_in_bin0 + 5984 item11_in_bin1 -2518 item12_in_bin0 + 2518 item12_in_bin1 -3270 item13_in_bin0 + 3270 item13_in_bin1 -7183 item14_in_bin0 + 7183 item14_in_bin1 + >= -0 +Bounds +Integers +item0_in_bin0 item0_in_bin1 item1_in_bin0 item1_in_bin1 item2_in_bin0 item2_in_bin1 item3_in_bin0 item3_in_bin1 item4_in_bin0 item4_in_bin1 +item5_in_bin0 item5_in_bin1 item6_in_bin0 item6_in_bin1 item7_in_bin0 item7_in_bin1 item8_in_bin0 item8_in_bin1 item9_in_bin0 item9_in_bin1 +item10_in_bin0 item10_in_bin1 item11_in_bin0 item11_in_bin1 item12_in_bin0 item12_in_bin1 item13_in_bin0 item13_in_bin1 item14_in_bin0 item14_in_bin1 +End diff --git a/issue17a.sol b/issue17a.sol new file mode 100644 index 0000000..a13e1d1 --- /dev/null +++ b/issue17a.sol @@ -0,0 +1,30 @@ +item0_in_bin0 = 1 +item1_in_bin0 = 1 +item2_in_bin0 = 1 +item3_in_bin0 = 1 +item4_in_bin0 = 1 +item5_in_bin0 = 1 +item6_in_bin0 = 1 +item7_in_bin0 = 0 +item8_in_bin0 = 0 +item9_in_bin0 = 0 +item10_in_bin0 = 0 +item11_in_bin0 = 0 +item12_in_bin0 = 0 +item13_in_bin0 = 0 +item14_in_bin0 = 0 +item0_in_bin1 = 0 +item1_in_bin1 = 0 +item2_in_bin1 = 0 +item3_in_bin1 = 0 +item4_in_bin1 = 0 +item5_in_bin1 = 0 +item6_in_bin1 = 0 +item7_in_bin1 = 1 +item8_in_bin1 = 1 +item9_in_bin1 = 1 +item10_in_bin1 = 1 +item11_in_bin1 = 1 +item12_in_bin1 = 1 +item13_in_bin1 = 1 +item14_in_bin1 = 1 diff --git a/issue17b.lp b/issue17b.lp new file mode 100644 index 0000000..3aee537 --- /dev/null +++ b/issue17b.lp @@ -0,0 +1,61 @@ +\Problem name: + +Minimize +OBJROW: 152 item0_in_bin1 + 489 item1_in_bin1 + 2178 item2_in_bin1 + 2518 item3_in_bin1 + 3212 item4_in_bin1 + 3270 item5_in_bin1 + 3410 item6_in_bin1 + 4979 item7_in_bin1 + 5984 item8_in_bin1 + 7183 item9_in_bin1 + + 7740 item10_in_bin1 + 7862 item11_in_bin1 + 8519 item12_in_bin1 + 8798 item13_in_bin1 + 9948 item14_in_bin1 +Subject To +constr(0): item0_in_bin0 >= 0 +constr(1): item1_in_bin0 >= 0 +constr(2): item2_in_bin0 >= 0 +constr(3): item3_in_bin0 >= 0 +constr(4): item4_in_bin0 >= 0 +constr(5): item5_in_bin0 >= 0 +constr(6): item6_in_bin0 >= 0 +constr(7): item7_in_bin0 >= 0 +constr(8): item8_in_bin0 >= 0 +constr(9): item9_in_bin0 >= 0 +constr(10): item10_in_bin0 >= 0 +constr(11): item11_in_bin0 >= 0 +constr(12): item12_in_bin0 >= 0 +constr(13): item13_in_bin0 >= 0 +constr(14): item14_in_bin0 >= 0 +constr(15): item0_in_bin1 >= 0 +constr(16): item1_in_bin1 >= 0 +constr(17): item2_in_bin1 >= 0 +constr(18): item3_in_bin1 >= 0 +constr(19): item4_in_bin1 >= 0 +constr(20): item5_in_bin1 >= 0 +constr(21): item6_in_bin1 >= 0 +constr(22): item7_in_bin1 >= 0 +constr(23): item8_in_bin1 >= 0 +constr(24): item9_in_bin1 >= 0 +constr(25): item10_in_bin1 >= 0 +constr(26): item11_in_bin1 >= 0 +constr(27): item12_in_bin1 >= 0 +constr(28): item13_in_bin1 >= 0 +constr(29): item14_in_bin1 >= 0 +constr(30): item0_in_bin0 + item0_in_bin1 = 1 +constr(31): item1_in_bin0 + item1_in_bin1 = 1 +constr(32): item2_in_bin0 + item2_in_bin1 = 1 +constr(33): item3_in_bin0 + item3_in_bin1 = 1 +constr(34): item4_in_bin0 + item4_in_bin1 = 1 +constr(35): item5_in_bin0 + item5_in_bin1 = 1 +constr(36): item6_in_bin0 + item6_in_bin1 = 1 +constr(37): item7_in_bin0 + item7_in_bin1 = 1 +constr(38): item8_in_bin0 + item8_in_bin1 = 1 +constr(39): item9_in_bin0 + item9_in_bin1 = 1 +constr(40): item10_in_bin0 + item10_in_bin1 = 1 +constr(41): item11_in_bin0 + item11_in_bin1 = 1 +constr(42): item12_in_bin0 + item12_in_bin1 = 1 +constr(43): item13_in_bin0 + item13_in_bin1 = 1 +constr(44): item14_in_bin0 + item14_in_bin1 = 1 +constr(45): -152 item0_in_bin0 + 152 item0_in_bin1 -489 item1_in_bin0 + 489 item1_in_bin1 -2178 item2_in_bin0 + 2178 item2_in_bin1 -2518 item3_in_bin0 + 2518 item3_in_bin1 -3212 item4_in_bin0 + 3212 item4_in_bin1 + -3270 item5_in_bin0 + 3270 item5_in_bin1 -3410 item6_in_bin0 + 3410 item6_in_bin1 -4979 item7_in_bin0 + 4979 item7_in_bin1 -5984 item8_in_bin0 + 5984 item8_in_bin1 -7183 item9_in_bin0 + 7183 item9_in_bin1 + -7740 item10_in_bin0 + 7740 item10_in_bin1 -7862 item11_in_bin0 + 7862 item11_in_bin1 -8519 item12_in_bin0 + 8519 item12_in_bin1 -8798 item13_in_bin0 + 8798 item13_in_bin1 -9948 item14_in_bin0 + 9948 item14_in_bin1 + >= -0 +Bounds +Integers +item0_in_bin0 item0_in_bin1 item1_in_bin0 item1_in_bin1 item2_in_bin0 item2_in_bin1 item3_in_bin0 item3_in_bin1 item4_in_bin0 item4_in_bin1 +item5_in_bin0 item5_in_bin1 item6_in_bin0 item6_in_bin1 item7_in_bin0 item7_in_bin1 item8_in_bin0 item8_in_bin1 item9_in_bin0 item9_in_bin1 +item10_in_bin0 item10_in_bin1 item11_in_bin0 item11_in_bin1 item12_in_bin0 item12_in_bin1 item13_in_bin0 item13_in_bin1 item14_in_bin0 item14_in_bin1 +End diff --git a/issue17b.sol b/issue17b.sol new file mode 100644 index 0000000..9688956 --- /dev/null +++ b/issue17b.sol @@ -0,0 +1,30 @@ +item0_in_bin0 = 0 +item1_in_bin0 = 0 +item2_in_bin0 = 0 +item3_in_bin0 = 1 +item4_in_bin0 = 0 +item5_in_bin0 = 0 +item6_in_bin0 = 1 +item7_in_bin0 = 0 +item8_in_bin0 = 1 +item9_in_bin0 = 0 +item10_in_bin0 = 1 +item11_in_bin0 = 0 +item12_in_bin0 = 1 +item13_in_bin0 = 0 +item14_in_bin0 = 1 +item0_in_bin1 = 1 +item1_in_bin1 = 1 +item2_in_bin1 = 1 +item3_in_bin1 = 0 +item4_in_bin1 = 1 +item5_in_bin1 = 1 +item6_in_bin1 = 0 +item7_in_bin1 = 1 +item8_in_bin1 = 0 +item9_in_bin1 = 1 +item10_in_bin1 = 0 +item11_in_bin1 = 1 +item12_in_bin1 = 0 +item13_in_bin1 = 1 +item14_in_bin1 = 0 diff --git a/prtpy/binners.py b/prtpy/binners.py index a4cb832..96019c3 100644 --- a/prtpy/binners.py +++ b/prtpy/binners.py @@ -25,9 +25,11 @@ class Binner(ABC): All arrays created by the same binner share the following two variables: * numbins - the total number of bins. * valueof - a function that maps an item to its value. + * copiesof - a function that maps an item to the number of copies. """ - def __init__(self, valueof: Callable = lambda x:x): + def __init__(self, valueof: Callable = lambda x:x, copiesof: Callable=lambda x:1): self.valueof = valueof + self.copiesof = copiesof @abstractmethod def new_bins(self, numbins:int)->BinsArray: @@ -186,8 +188,8 @@ class BinnerKeepingSums(Binner): Bin #1: sum=3.0 """ - def __init__(self, valueof: Callable = lambda x:x): - super().__init__(valueof) + def __init__(self, valueof: Callable = lambda x:x, copiesof: Callable=lambda x:1): + super().__init__(valueof,copiesof) BinsArray = np.ndarray # Here, the bins-array is simply an array of the sums. @@ -330,8 +332,8 @@ class BinnerKeepingContents(BinnerKeepingSums): Bin #1: ['a'], sum=3.0 """ - def __init__(self, valueof: Callable = lambda x:x): - super().__init__(valueof) + def __init__(self, valueof: Callable = lambda x:x, copiesof: Callable=lambda x:1): + super().__init__(valueof, copiesof) BinsArray = Tuple[np.ndarray, List[List]] # Here, each bins-array is a tuple: sums,lists. sums is an array of sums; lists is a list of lists of items. @@ -451,7 +453,4 @@ def printbins(bins:BinsArray): if __name__ == "__main__": import doctest, sys - (failures, tests) = doctest.testmod(report=True, optionflags=doctest.FAIL_FAST) - print("{} failures, {} tests".format(failures, tests)) - if failures>0: - sys.exit(1) + print(doctest.testmod(report=True, optionflags=doctest.FAIL_FAST)) diff --git a/prtpy/outputtypes.py b/prtpy/outputtypes.py index 2153471..1334a3e 100644 --- a/prtpy/outputtypes.py +++ b/prtpy/outputtypes.py @@ -8,7 +8,7 @@ class OutputType(ABC): @classmethod - def create_binner(cls, valueof: Callable) -> Binner: + def create_binner(cls, valueof: Callable, copiesof: Callable=None) -> Binner: """ Construct and return a Bins structure. Used at the initialization phase of an algorithm. """ @@ -30,8 +30,8 @@ def extract_output_from_binsarray(cls, bins: BinsArray) -> List: class Sums(OutputType): """ Output the list of sums of all bins (but not the bins' contents). """ @classmethod - def create_binner(cls, valueof: Callable) -> List: - return BinnerKeepingSums(valueof) + def create_binner(cls, valueof: Callable, copiesof: Callable=None) -> List: + return BinnerKeepingSums(valueof,copiesof) @classmethod def extract_output_from_sums(cls, sums: List[float]) -> List: @@ -94,8 +94,8 @@ class Partition(OutputType): """ Output the set of all bins. """ @classmethod - def create_binner(cls, valueof: Callable) -> List: - return BinnerKeepingContents(valueof) + def create_binner(cls, valueof: Callable, copiesof: Callable=None) -> List: + return BinnerKeepingContents(valueof,copiesof) @classmethod def extract_output_from_sums_and_lists(cls, sums: List[float], lists: List[List[Any]]) -> List: diff --git a/prtpy/partitioning/adaptors.py b/prtpy/partitioning/adaptors.py index d397f07..785dd19 100644 --- a/prtpy/partitioning/adaptors.py +++ b/prtpy/partitioning/adaptors.py @@ -16,12 +16,14 @@ from prtpy import outputtypes as out, objectives as obj from prtpy.binners import Binner from typing import Callable, List, Any +from numbers import Number def partition( algorithm: Callable, numbins: int, items: Any, valueof: Callable[[Any], float] = None, + copies: Any = 1, outputtype: out.OutputType = out.Partition, **kwargs ): @@ -32,6 +34,7 @@ def partition( numbins (int), items (list), valueof (callable), + copiesof (callable), outputtype (OutputType). :param numbins: int - how many parts should be in the partition? @@ -42,6 +45,7 @@ def partition( * A list of strings (in this case, valueof should also be defined, and map each item name to its value); :param valueof: optional; required only if `items` is a list of item-names. + :param copiesof: optional; required only if `items` is a list of item-names. :param outputtype: what output to return. See `outputtypes.py'. @@ -73,11 +77,31 @@ def partition( item_names = items.keys() if valueof is None: valueof = items.__getitem__ - else: # items is a list + + # copiesof: + if isinstance(copies,dict): + copiesof = copies.__getitem__ + elif isinstance(copies,Number): + copiesof = lambda item: copies + else: + raise TypeError(f"copies parameter {copies} is of wrong type {type(copies)}") + else: # items is a list of values item_names = items if valueof is None: valueof = lambda item: item - binner = outputtype.create_binner(valueof) + + # copiesof: + if isinstance(copies,list): + if len(set(items))==len(items): + copies_dict = dict(zip(items,copies)) # Works only when each item appears once + copiesof = copies_dict.__getitem__ + else: + raise ValueError(f"copies argument can only be used when item names are unique, but they are not: {item_names}") + elif isinstance(copies,Number): + copiesof = lambda item: copies + else: + raise TypeError(f"copies parameter {copies} is of wrong type {type(copies)}") + binner = outputtype.create_binner(valueof,copiesof) bins = algorithm(binner, numbins, item_names, **kwargs) return outputtype.extract_output_from_binsarray(bins) diff --git a/prtpy/partitioning/integer_programming.py b/prtpy/partitioning/integer_programming.py index 235bcea..00fe715 100644 --- a/prtpy/partitioning/integer_programming.py +++ b/prtpy/partitioning/integer_programming.py @@ -21,7 +21,6 @@ def optimal( binner: Binner, numbins: int, items: List[any], objective: obj.Objective = obj.MinimizeDifference, - copies=1, time_limit=inf, additional_constraints:Callable=lambda sums:[], entitlements:List[float]=None, @@ -39,7 +38,6 @@ def optimal( :param valueof: a function that maps an item from the list `items` to a number representing its value. :param objective: whether to maximize the smallest sum, minimize the largest sum, etc. :param outputtype: whether to return the entire partition, or just the sums, etc. - :param copies: how many copies there are of each item. Default: 1. :param time_limit: stop the computation after this number of seconds have passed. :param additional_constraints: a function that accepts the list of sums in ascending order, and returns a list of possible additional constraints on the sums. :param entitlements: if given, must be of size bins.num. Divides each sum by its weight before applying the objective function. @@ -102,37 +100,44 @@ def optimal( Bin #2: [99, 129], sum=228.0 Bin #3: [62, 187], sum=249.0 Bin #4: [93, 158], sum=251.0 + + # Example with copies + >>> partition(algorithm=optimal, numbins=3, items=[1, 2, 3], copies=[2, 1, 4]) + [[2, 3], [1, 1, 3], [3, 3]] + >>> partition(algorithm=optimal, numbins=3, items={"a": 11, "b": 22, "c": 33}, copies={"a": 2, "b": 1, "c": 4}) + [['b', 'c'], ['a', 'a', 'c'], ['c', 'c']] """ if objective == obj.MinimizeDistAvg: from prtpy.partitioning.integer_programming_avg import optimal as optimal_avg - return optimal_avg(binner, numbins, items, entitlements=entitlements, copies=copies, time_limit=time_limit, verbose=verbose, solver_name=solver_name, model_filename=model_filename, solution_filename=solution_filename) - + return optimal_avg(binner, numbins, items, entitlements=entitlements, time_limit=time_limit, verbose=verbose, solver_name=solver_name, model_filename=model_filename, solution_filename=solution_filename) + ibins = range(numbins) items = list(items) - iitems = range(len(items)) - if isinstance(copies, Number): - copies = {iitem: copies for iitem in iitems} + # iitems = range(len(items)) # We need different indices for items with identical value if entitlements is None: entitlements = numbins*[1] model = mip.Model(name = '', solver_name=solver_name) counts: dict = { iitem: [model.add_var(var_type=mip.INTEGER, name=f'item{iitem}_in_bin{ibin}') for ibin in ibins] - for iitem in iitems + for iitem,item in enumerate(items) } # counts[i][j] is a variable that represents how many times item i appears in bin j. + logger.debug("counts: %s", counts) bin_sums = [ - sum([counts[iitem][ibin] * binner.valueof(items[iitem]) for iitem in iitems])/entitlements[ibin] + sum([counts[iitem][ibin] * binner.valueof(item) for iitem,item in enumerate(items)])/entitlements[ibin] for ibin in ibins ] # bin_sums[j] is a variable-expression that represents the sum of values in bin j. + logger.debug("bin_sums: %s", bin_sums) model.objective = mip.minimize( objective.value_to_minimize(bin_sums, are_sums_in_ascending_order=True) ) + logger.debug("Objective: %s", model.objective) # Construct the list of constraints: - counts_are_non_negative = [counts[iitem][ibin] >= 0 for ibin in ibins for iitem in iitems] + counts_are_non_negative = [counts[iitem][ibin] >= 0 for ibin in ibins for iitem,item in enumerate(items)] each_item_in_one_bin = [ - sum([counts[iitem][ibin] for ibin in ibins]) == copies[iitem] for iitem in iitems + sum([counts[iitem][ibin] for ibin in ibins]) == binner.copiesof(item) for iitem,item in enumerate(items) ] bin_sums_in_ascending_order = [ # a symmetry-breaker bin_sums[ibin + 1] >= bin_sums[ibin] for ibin in range(numbins - 1) @@ -152,16 +157,16 @@ def optimal( # Construct the output: output = binner.new_bins(numbins) for ibin in ibins: - for iitem in iitems: + for iitem,item in enumerate(items): count_item_in_bin = int(counts[iitem][ibin].x) for _ in range(count_item_in_bin): - binner.add_item_to_bin(output, items[iitem], ibin) + binner.add_item_to_bin(output, item, ibin) binner.sort_by_ascending_sum(output) if solution_filename is not None: with open(solution_filename,"w") as solution_file: for ibin in ibins: - for iitem in iitems: + for iitem,item in enumerate(items): count_item_in_bin = int(counts[iitem][ibin].x) # solution_file.write(f'item{binner.valueof(items[iitem]):05d}_in_bin{ibin} = {count_item_in_bin}\n') solution_file.write(f'item{iitem}_in_bin{ibin} = {count_item_in_bin}\n') @@ -170,7 +175,12 @@ def optimal( if __name__ == "__main__": import doctest, logging - logger.setLevel(logging.DEBUG) + logger.setLevel(logging.INFO) logger.addHandler(logging.StreamHandler()) - (failures, tests) = doctest.testmod(report=True, optionflags=doctest.FAIL_FAST) - print("{} failures, {} tests".format(failures, tests)) + + print(doctest.testmod(report=True, optionflags=doctest.FAIL_FAST)) + + from prtpy import BinnerKeepingContents, BinnerKeepingSums, partition + # print(partition(algorithm=optimal, numbins=3, items={"a": 11, "b": 22, "c": 33}, copies={"a": 2, "b": 1, "c": 4})) + # print(partition(algorithm=optimal, numbins=2, items=[11,11,11,11,22], objective=obj.MaximizeSmallestSum)) + diff --git a/prtpy/partitioning/integer_programming_avg.py b/prtpy/partitioning/integer_programming_avg.py index 52ed2af..3131297 100644 --- a/prtpy/partitioning/integer_programming_avg.py +++ b/prtpy/partitioning/integer_programming_avg.py @@ -16,7 +16,6 @@ def optimal( binner: Binner, numbins: int, items: List[any], entitlements: List[any] = None, - copies=1, time_limit=inf, # time limit in seconds verbose=0, solver_name=mip.CBC, # [or mip.GRB] passed to MIP. See https://docs.python-mip.com/en/latest/quickstart.html#creating-models. @@ -29,7 +28,6 @@ def optimal( :param numbins: number of bins. :param items: list of items. :param entitlements: list of relative values that sum up to 1 for the bins if there are any. - :param copies: how many copies there are of each item. Default: 1. :param time_limit: stop the computation after this number of seconds have passed. :param valueof: a function that maps an item from the list `items` to a number representing its value. :param solver_name: passed to MIP. See https://docs.python-mip.com/en/latest/quickstart.html#creating-models @@ -75,34 +73,27 @@ def optimal( >>> from prtpy import partition >>> partition(algorithm=optimal, numbins=3, items=[1, 2, 3], copies=[2, 1, 4]) [[2, 3], [1, 1, 3], [3, 3]] - + >>> partition(algorithm=optimal, numbins=3, items={"a": 11, "b": 22, "c": 33}, copies={"a": 2, "b": 1, "c": 4}) + [['a', 'a', 'c'], ['b', 'c'], ['c', 'c']] """ ibins = range(numbins) items = list(items) - iitems = range(len(items)) - if isinstance(copies, Number): - copies = {iitem: copies for iitem in iitems} model = mip.Model(name='', sense='MIN', solver_name=solver_name) counts: dict = { iitem: [model.add_var(var_type=mip.INTEGER) for ibin in ibins] - for iitem in iitems + for iitem,item in enumerate(items) } # counts[i][j] is a variable that represents how many times item i appears in bin j. bin_sums = [ - sum([counts[iitem][ibin] * binner.valueof(items[iitem]) for iitem in iitems]) + sum([counts[iitem][ibin] * binner.valueof(items[iitem]) for iitem,item in enumerate(items)]) for ibin in ibins ] - sum_items = 0 - if not copies: - sum_items = sum(items) - else: - for i in range (len(items)): - sum_items = sum_items + items[i] * copies[i] + sum_values = sum([binner.valueof(item)*binner.copiesof(item) for item in items]) effective_entitlements = entitlements or [1. / numbins for ibin in ibins] z_js = [ - bin_sums[ibin] - sum_items * effective_entitlements[ibin] + bin_sums[ibin] - sum_values * effective_entitlements[ibin] for ibin in ibins ] @@ -118,9 +109,9 @@ def optimal( # Construct the list of constraints: t_js_greater_than_z_js = [t_js[ibin] >= z_js[ibin] for ibin in ibins] t_js_greater_than_minus_z_js = [t_js[ibin] >= -z_js[ibin] for ibin in ibins] - counts_are_non_negative = [counts[iitem][ibin] >= 0 for ibin in ibins for iitem in iitems] + counts_are_non_negative = [counts[iitem][ibin] >= 0 for ibin in ibins for iitem,item in enumerate(items)] each_item_in_one_bin = [ - sum([counts[iitem][ibin] for ibin in ibins]) == copies[iitem] for iitem in iitems + sum([counts[iitem][ibin] for ibin in ibins]) == binner.copiesof(item) for iitem,item in enumerate(items) ] constraints = each_item_in_one_bin + t_js_greater_than_z_js + t_js_greater_than_minus_z_js + counts_are_non_negative for constraint in constraints: model += constraint @@ -144,7 +135,7 @@ def optimal( # Construct the output: output = binner.new_bins(numbins) for ibin in ibins: - for iitem in iitems: + for iitem,item in enumerate(items): count_item_in_bin = int(counts[iitem][ibin].x) for _ in range(count_item_in_bin): binner.add_item_to_bin(output, items[iitem], ibin) @@ -154,7 +145,7 @@ def optimal( if solution_filename is not None: with open(solution_filename,"w") as solution_file: for ibin in ibins: - for iitem in iitems: + for iitem,item in enumerate(items): count_item_in_bin = int(counts[iitem][ibin].x) # solution_file.write(f'item{binner.valueof(items[iitem]):05d}_in_bin{ibin} = {count_item_in_bin}\n') solution_file.write(f'item{iitem}_in_bin{ibin} = {count_item_in_bin}\n') diff --git a/tests/issue17/generate_test_ilp.py b/tests/issue17/generate_test_ilp.py new file mode 100644 index 0000000..065c018 --- /dev/null +++ b/tests/issue17/generate_test_ilp.py @@ -0,0 +1,25 @@ +from numpy.random import seed +from numpy.random import randint +import prtpy + +if __name__=="__main__": + + seed(1) + + for _ in range(1000): + for i in range(1, 10): + original_values = randint(0, 10000, i) + answer1 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=original_values, objective=prtpy.obj.MaximizeSmallestSum) + diff1 = abs(sum(answer1[0]) - sum(answer1[1])) + original_values.sort() + answer2 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=original_values, objective=prtpy.obj.MaximizeSmallestSum) + diff2 = abs(sum(answer2[0]) - sum(answer2[1])) + + if diff1 != diff2: + print("\n\nFound example at ", i, ":") + print("One answer with a diff of ", diff1, ":") + print(answer1[0]) + print(answer1[1]) + print("\nThe other answer with a diff of ", diff2, ":") + print(answer2[0]) + print(answer2[1]) diff --git a/tests/issue17/issue17a.lp b/tests/issue17/issue17a.lp index a3bef2a..b271efd 100644 --- a/tests/issue17/issue17a.lp +++ b/tests/issue17/issue17a.lp @@ -1,61 +1,61 @@ \Problem name: Minimize -OBJROW: 7740 item07740_in_bin1 + 489 item00489_in_bin1 + 152 item00152_in_bin1 + 3410 item03410_in_bin1 + 9948 item09948_in_bin1 + 7862 item07862_in_bin1 + 8519 item08519_in_bin1 + 3212 item03212_in_bin1 + 8798 item08798_in_bin1 + 4979 item04979_in_bin1 - + 2178 item02178_in_bin1 + 5984 item05984_in_bin1 + 2518 item02518_in_bin1 + 3270 item03270_in_bin1 + 7183 item07183_in_bin1 +OBJROW: 7740 item0_in_bin1 + 489 item1_in_bin1 + 152 item2_in_bin1 + 3410 item3_in_bin1 + 9948 item4_in_bin1 + 7862 item5_in_bin1 + 8519 item6_in_bin1 + 3212 item7_in_bin1 + 8798 item8_in_bin1 + 4979 item9_in_bin1 + + 2178 item10_in_bin1 + 5984 item11_in_bin1 + 2518 item12_in_bin1 + 3270 item13_in_bin1 + 7183 item14_in_bin1 Subject To -constr(0): item07740_in_bin0 >= 0 -constr(1): item00489_in_bin0 >= 0 -constr(2): item00152_in_bin0 >= 0 -constr(3): item03410_in_bin0 >= 0 -constr(4): item09948_in_bin0 >= 0 -constr(5): item07862_in_bin0 >= 0 -constr(6): item08519_in_bin0 >= 0 -constr(7): item03212_in_bin0 >= 0 -constr(8): item08798_in_bin0 >= 0 -constr(9): item04979_in_bin0 >= 0 -constr(10): item02178_in_bin0 >= 0 -constr(11): item05984_in_bin0 >= 0 -constr(12): item02518_in_bin0 >= 0 -constr(13): item03270_in_bin0 >= 0 -constr(14): item07183_in_bin0 >= 0 -constr(15): item07740_in_bin1 >= 0 -constr(16): item00489_in_bin1 >= 0 -constr(17): item00152_in_bin1 >= 0 -constr(18): item03410_in_bin1 >= 0 -constr(19): item09948_in_bin1 >= 0 -constr(20): item07862_in_bin1 >= 0 -constr(21): item08519_in_bin1 >= 0 -constr(22): item03212_in_bin1 >= 0 -constr(23): item08798_in_bin1 >= 0 -constr(24): item04979_in_bin1 >= 0 -constr(25): item02178_in_bin1 >= 0 -constr(26): item05984_in_bin1 >= 0 -constr(27): item02518_in_bin1 >= 0 -constr(28): item03270_in_bin1 >= 0 -constr(29): item07183_in_bin1 >= 0 -constr(30): item07740_in_bin0 + item07740_in_bin1 = 1 -constr(31): item00489_in_bin0 + item00489_in_bin1 = 1 -constr(32): item00152_in_bin0 + item00152_in_bin1 = 1 -constr(33): item03410_in_bin0 + item03410_in_bin1 = 1 -constr(34): item09948_in_bin0 + item09948_in_bin1 = 1 -constr(35): item07862_in_bin0 + item07862_in_bin1 = 1 -constr(36): item08519_in_bin0 + item08519_in_bin1 = 1 -constr(37): item03212_in_bin0 + item03212_in_bin1 = 1 -constr(38): item08798_in_bin0 + item08798_in_bin1 = 1 -constr(39): item04979_in_bin0 + item04979_in_bin1 = 1 -constr(40): item02178_in_bin0 + item02178_in_bin1 = 1 -constr(41): item05984_in_bin0 + item05984_in_bin1 = 1 -constr(42): item02518_in_bin0 + item02518_in_bin1 = 1 -constr(43): item03270_in_bin0 + item03270_in_bin1 = 1 -constr(44): item07183_in_bin0 + item07183_in_bin1 = 1 -constr(45): -7740 item07740_in_bin0 + 7740 item07740_in_bin1 -489 item00489_in_bin0 + 489 item00489_in_bin1 -152 item00152_in_bin0 + 152 item00152_in_bin1 -3410 item03410_in_bin0 + 3410 item03410_in_bin1 -9948 item09948_in_bin0 + 9948 item09948_in_bin1 - -7862 item07862_in_bin0 + 7862 item07862_in_bin1 -8519 item08519_in_bin0 + 8519 item08519_in_bin1 -3212 item03212_in_bin0 + 3212 item03212_in_bin1 -8798 item08798_in_bin0 + 8798 item08798_in_bin1 -4979 item04979_in_bin0 + 4979 item04979_in_bin1 - -2178 item02178_in_bin0 + 2178 item02178_in_bin1 -5984 item05984_in_bin0 + 5984 item05984_in_bin1 -2518 item02518_in_bin0 + 2518 item02518_in_bin1 -3270 item03270_in_bin0 + 3270 item03270_in_bin1 -7183 item07183_in_bin0 + 7183 item07183_in_bin1 +constr(0): item0_in_bin0 >= 0 +constr(1): item1_in_bin0 >= 0 +constr(2): item2_in_bin0 >= 0 +constr(3): item3_in_bin0 >= 0 +constr(4): item4_in_bin0 >= 0 +constr(5): item5_in_bin0 >= 0 +constr(6): item6_in_bin0 >= 0 +constr(7): item7_in_bin0 >= 0 +constr(8): item8_in_bin0 >= 0 +constr(9): item9_in_bin0 >= 0 +constr(10): item10_in_bin0 >= 0 +constr(11): item11_in_bin0 >= 0 +constr(12): item12_in_bin0 >= 0 +constr(13): item13_in_bin0 >= 0 +constr(14): item14_in_bin0 >= 0 +constr(15): item0_in_bin1 >= 0 +constr(16): item1_in_bin1 >= 0 +constr(17): item2_in_bin1 >= 0 +constr(18): item3_in_bin1 >= 0 +constr(19): item4_in_bin1 >= 0 +constr(20): item5_in_bin1 >= 0 +constr(21): item6_in_bin1 >= 0 +constr(22): item7_in_bin1 >= 0 +constr(23): item8_in_bin1 >= 0 +constr(24): item9_in_bin1 >= 0 +constr(25): item10_in_bin1 >= 0 +constr(26): item11_in_bin1 >= 0 +constr(27): item12_in_bin1 >= 0 +constr(28): item13_in_bin1 >= 0 +constr(29): item14_in_bin1 >= 0 +constr(30): item0_in_bin0 + item0_in_bin1 = 1 +constr(31): item1_in_bin0 + item1_in_bin1 = 1 +constr(32): item2_in_bin0 + item2_in_bin1 = 1 +constr(33): item3_in_bin0 + item3_in_bin1 = 1 +constr(34): item4_in_bin0 + item4_in_bin1 = 1 +constr(35): item5_in_bin0 + item5_in_bin1 = 1 +constr(36): item6_in_bin0 + item6_in_bin1 = 1 +constr(37): item7_in_bin0 + item7_in_bin1 = 1 +constr(38): item8_in_bin0 + item8_in_bin1 = 1 +constr(39): item9_in_bin0 + item9_in_bin1 = 1 +constr(40): item10_in_bin0 + item10_in_bin1 = 1 +constr(41): item11_in_bin0 + item11_in_bin1 = 1 +constr(42): item12_in_bin0 + item12_in_bin1 = 1 +constr(43): item13_in_bin0 + item13_in_bin1 = 1 +constr(44): item14_in_bin0 + item14_in_bin1 = 1 +constr(45): -7740 item0_in_bin0 + 7740 item0_in_bin1 -489 item1_in_bin0 + 489 item1_in_bin1 -152 item2_in_bin0 + 152 item2_in_bin1 -3410 item3_in_bin0 + 3410 item3_in_bin1 -9948 item4_in_bin0 + 9948 item4_in_bin1 + -7862 item5_in_bin0 + 7862 item5_in_bin1 -8519 item6_in_bin0 + 8519 item6_in_bin1 -3212 item7_in_bin0 + 3212 item7_in_bin1 -8798 item8_in_bin0 + 8798 item8_in_bin1 -4979 item9_in_bin0 + 4979 item9_in_bin1 + -2178 item10_in_bin0 + 2178 item10_in_bin1 -5984 item11_in_bin0 + 5984 item11_in_bin1 -2518 item12_in_bin0 + 2518 item12_in_bin1 -3270 item13_in_bin0 + 3270 item13_in_bin1 -7183 item14_in_bin0 + 7183 item14_in_bin1 >= -0 Bounds Integers -item07740_in_bin0 item07740_in_bin1 item00489_in_bin0 item00489_in_bin1 item00152_in_bin0 item00152_in_bin1 item03410_in_bin0 item03410_in_bin1 item09948_in_bin0 item09948_in_bin1 -item07862_in_bin0 item07862_in_bin1 item08519_in_bin0 item08519_in_bin1 item03212_in_bin0 item03212_in_bin1 item08798_in_bin0 item08798_in_bin1 item04979_in_bin0 item04979_in_bin1 -item02178_in_bin0 item02178_in_bin1 item05984_in_bin0 item05984_in_bin1 item02518_in_bin0 item02518_in_bin1 item03270_in_bin0 item03270_in_bin1 item07183_in_bin0 item07183_in_bin1 +item0_in_bin0 item0_in_bin1 item1_in_bin0 item1_in_bin1 item2_in_bin0 item2_in_bin1 item3_in_bin0 item3_in_bin1 item4_in_bin0 item4_in_bin1 +item5_in_bin0 item5_in_bin1 item6_in_bin0 item6_in_bin1 item7_in_bin0 item7_in_bin1 item8_in_bin0 item8_in_bin1 item9_in_bin0 item9_in_bin1 +item10_in_bin0 item10_in_bin1 item11_in_bin0 item11_in_bin1 item12_in_bin0 item12_in_bin1 item13_in_bin0 item13_in_bin1 item14_in_bin0 item14_in_bin1 End diff --git a/tests/issue17/issue17a.lp.txt b/tests/issue17/issue17a.lp.txt deleted file mode 100644 index a3bef2a..0000000 --- a/tests/issue17/issue17a.lp.txt +++ /dev/null @@ -1,61 +0,0 @@ -\Problem name: - -Minimize -OBJROW: 7740 item07740_in_bin1 + 489 item00489_in_bin1 + 152 item00152_in_bin1 + 3410 item03410_in_bin1 + 9948 item09948_in_bin1 + 7862 item07862_in_bin1 + 8519 item08519_in_bin1 + 3212 item03212_in_bin1 + 8798 item08798_in_bin1 + 4979 item04979_in_bin1 - + 2178 item02178_in_bin1 + 5984 item05984_in_bin1 + 2518 item02518_in_bin1 + 3270 item03270_in_bin1 + 7183 item07183_in_bin1 -Subject To -constr(0): item07740_in_bin0 >= 0 -constr(1): item00489_in_bin0 >= 0 -constr(2): item00152_in_bin0 >= 0 -constr(3): item03410_in_bin0 >= 0 -constr(4): item09948_in_bin0 >= 0 -constr(5): item07862_in_bin0 >= 0 -constr(6): item08519_in_bin0 >= 0 -constr(7): item03212_in_bin0 >= 0 -constr(8): item08798_in_bin0 >= 0 -constr(9): item04979_in_bin0 >= 0 -constr(10): item02178_in_bin0 >= 0 -constr(11): item05984_in_bin0 >= 0 -constr(12): item02518_in_bin0 >= 0 -constr(13): item03270_in_bin0 >= 0 -constr(14): item07183_in_bin0 >= 0 -constr(15): item07740_in_bin1 >= 0 -constr(16): item00489_in_bin1 >= 0 -constr(17): item00152_in_bin1 >= 0 -constr(18): item03410_in_bin1 >= 0 -constr(19): item09948_in_bin1 >= 0 -constr(20): item07862_in_bin1 >= 0 -constr(21): item08519_in_bin1 >= 0 -constr(22): item03212_in_bin1 >= 0 -constr(23): item08798_in_bin1 >= 0 -constr(24): item04979_in_bin1 >= 0 -constr(25): item02178_in_bin1 >= 0 -constr(26): item05984_in_bin1 >= 0 -constr(27): item02518_in_bin1 >= 0 -constr(28): item03270_in_bin1 >= 0 -constr(29): item07183_in_bin1 >= 0 -constr(30): item07740_in_bin0 + item07740_in_bin1 = 1 -constr(31): item00489_in_bin0 + item00489_in_bin1 = 1 -constr(32): item00152_in_bin0 + item00152_in_bin1 = 1 -constr(33): item03410_in_bin0 + item03410_in_bin1 = 1 -constr(34): item09948_in_bin0 + item09948_in_bin1 = 1 -constr(35): item07862_in_bin0 + item07862_in_bin1 = 1 -constr(36): item08519_in_bin0 + item08519_in_bin1 = 1 -constr(37): item03212_in_bin0 + item03212_in_bin1 = 1 -constr(38): item08798_in_bin0 + item08798_in_bin1 = 1 -constr(39): item04979_in_bin0 + item04979_in_bin1 = 1 -constr(40): item02178_in_bin0 + item02178_in_bin1 = 1 -constr(41): item05984_in_bin0 + item05984_in_bin1 = 1 -constr(42): item02518_in_bin0 + item02518_in_bin1 = 1 -constr(43): item03270_in_bin0 + item03270_in_bin1 = 1 -constr(44): item07183_in_bin0 + item07183_in_bin1 = 1 -constr(45): -7740 item07740_in_bin0 + 7740 item07740_in_bin1 -489 item00489_in_bin0 + 489 item00489_in_bin1 -152 item00152_in_bin0 + 152 item00152_in_bin1 -3410 item03410_in_bin0 + 3410 item03410_in_bin1 -9948 item09948_in_bin0 + 9948 item09948_in_bin1 - -7862 item07862_in_bin0 + 7862 item07862_in_bin1 -8519 item08519_in_bin0 + 8519 item08519_in_bin1 -3212 item03212_in_bin0 + 3212 item03212_in_bin1 -8798 item08798_in_bin0 + 8798 item08798_in_bin1 -4979 item04979_in_bin0 + 4979 item04979_in_bin1 - -2178 item02178_in_bin0 + 2178 item02178_in_bin1 -5984 item05984_in_bin0 + 5984 item05984_in_bin1 -2518 item02518_in_bin0 + 2518 item02518_in_bin1 -3270 item03270_in_bin0 + 3270 item03270_in_bin1 -7183 item07183_in_bin0 + 7183 item07183_in_bin1 - >= -0 -Bounds -Integers -item07740_in_bin0 item07740_in_bin1 item00489_in_bin0 item00489_in_bin1 item00152_in_bin0 item00152_in_bin1 item03410_in_bin0 item03410_in_bin1 item09948_in_bin0 item09948_in_bin1 -item07862_in_bin0 item07862_in_bin1 item08519_in_bin0 item08519_in_bin1 item03212_in_bin0 item03212_in_bin1 item08798_in_bin0 item08798_in_bin1 item04979_in_bin0 item04979_in_bin1 -item02178_in_bin0 item02178_in_bin1 item05984_in_bin0 item05984_in_bin1 item02518_in_bin0 item02518_in_bin1 item03270_in_bin0 item03270_in_bin1 item07183_in_bin0 item07183_in_bin1 -End diff --git a/tests/issue17/issue17a.sol b/tests/issue17/issue17a.sol index cf09794..a13e1d1 100644 --- a/tests/issue17/issue17a.sol +++ b/tests/issue17/issue17a.sol @@ -1,31 +1,30 @@ -item00152_in_bin0 = 1 -item00489_in_bin0 = 1 -item02178_in_bin0 = 0 -item02518_in_bin0 = 0 -item03212_in_bin0 = 0 -item03270_in_bin0 = 0 -item03410_in_bin0 = 1 -item04979_in_bin0 = 0 -item05984_in_bin0 = 0 -item07183_in_bin0 = 0 -item07740_in_bin0 = 1 -item07862_in_bin0 = 1 -item08519_in_bin0 = 1 -item08798_in_bin0 = 0 -item09948_in_bin0 = 1 - -item00152_in_bin1 = 0 -item00489_in_bin1 = 0 -item02178_in_bin1 = 1 -item02518_in_bin1 = 1 -item03212_in_bin1 = 1 -item03270_in_bin1 = 1 -item03410_in_bin1 = 0 -item04979_in_bin1 = 1 -item05984_in_bin1 = 1 -item07183_in_bin1 = 1 -item07740_in_bin1 = 0 -item07862_in_bin1 = 0 -item08519_in_bin1 = 0 -item08798_in_bin1 = 1 -item09948_in_bin1 = 0 \ No newline at end of file +item0_in_bin0 = 1 +item1_in_bin0 = 1 +item2_in_bin0 = 1 +item3_in_bin0 = 1 +item4_in_bin0 = 1 +item5_in_bin0 = 1 +item6_in_bin0 = 1 +item7_in_bin0 = 0 +item8_in_bin0 = 0 +item9_in_bin0 = 0 +item10_in_bin0 = 0 +item11_in_bin0 = 0 +item12_in_bin0 = 0 +item13_in_bin0 = 0 +item14_in_bin0 = 0 +item0_in_bin1 = 0 +item1_in_bin1 = 0 +item2_in_bin1 = 0 +item3_in_bin1 = 0 +item4_in_bin1 = 0 +item5_in_bin1 = 0 +item6_in_bin1 = 0 +item7_in_bin1 = 1 +item8_in_bin1 = 1 +item9_in_bin1 = 1 +item10_in_bin1 = 1 +item11_in_bin1 = 1 +item12_in_bin1 = 1 +item13_in_bin1 = 1 +item14_in_bin1 = 1 diff --git a/tests/issue17/issue17b.lp b/tests/issue17/issue17b.lp index 873c162..3aee537 100644 --- a/tests/issue17/issue17b.lp +++ b/tests/issue17/issue17b.lp @@ -1,61 +1,61 @@ \Problem name: Minimize -OBJROW: 152 item00152_in_bin1 + 489 item00489_in_bin1 + 2178 item02178_in_bin1 + 2518 item02518_in_bin1 + 3212 item03212_in_bin1 + 3270 item03270_in_bin1 + 3410 item03410_in_bin1 + 4979 item04979_in_bin1 + 5984 item05984_in_bin1 + 7183 item07183_in_bin1 - + 7740 item07740_in_bin1 + 7862 item07862_in_bin1 + 8519 item08519_in_bin1 + 8798 item08798_in_bin1 + 9948 item09948_in_bin1 +OBJROW: 152 item0_in_bin1 + 489 item1_in_bin1 + 2178 item2_in_bin1 + 2518 item3_in_bin1 + 3212 item4_in_bin1 + 3270 item5_in_bin1 + 3410 item6_in_bin1 + 4979 item7_in_bin1 + 5984 item8_in_bin1 + 7183 item9_in_bin1 + + 7740 item10_in_bin1 + 7862 item11_in_bin1 + 8519 item12_in_bin1 + 8798 item13_in_bin1 + 9948 item14_in_bin1 Subject To -constr(0): item00152_in_bin0 >= 0 -constr(1): item00489_in_bin0 >= 0 -constr(2): item02178_in_bin0 >= 0 -constr(3): item02518_in_bin0 >= 0 -constr(4): item03212_in_bin0 >= 0 -constr(5): item03270_in_bin0 >= 0 -constr(6): item03410_in_bin0 >= 0 -constr(7): item04979_in_bin0 >= 0 -constr(8): item05984_in_bin0 >= 0 -constr(9): item07183_in_bin0 >= 0 -constr(10): item07740_in_bin0 >= 0 -constr(11): item07862_in_bin0 >= 0 -constr(12): item08519_in_bin0 >= 0 -constr(13): item08798_in_bin0 >= 0 -constr(14): item09948_in_bin0 >= 0 -constr(15): item00152_in_bin1 >= 0 -constr(16): item00489_in_bin1 >= 0 -constr(17): item02178_in_bin1 >= 0 -constr(18): item02518_in_bin1 >= 0 -constr(19): item03212_in_bin1 >= 0 -constr(20): item03270_in_bin1 >= 0 -constr(21): item03410_in_bin1 >= 0 -constr(22): item04979_in_bin1 >= 0 -constr(23): item05984_in_bin1 >= 0 -constr(24): item07183_in_bin1 >= 0 -constr(25): item07740_in_bin1 >= 0 -constr(26): item07862_in_bin1 >= 0 -constr(27): item08519_in_bin1 >= 0 -constr(28): item08798_in_bin1 >= 0 -constr(29): item09948_in_bin1 >= 0 -constr(30): item00152_in_bin0 + item00152_in_bin1 = 1 -constr(31): item00489_in_bin0 + item00489_in_bin1 = 1 -constr(32): item02178_in_bin0 + item02178_in_bin1 = 1 -constr(33): item02518_in_bin0 + item02518_in_bin1 = 1 -constr(34): item03212_in_bin0 + item03212_in_bin1 = 1 -constr(35): item03270_in_bin0 + item03270_in_bin1 = 1 -constr(36): item03410_in_bin0 + item03410_in_bin1 = 1 -constr(37): item04979_in_bin0 + item04979_in_bin1 = 1 -constr(38): item05984_in_bin0 + item05984_in_bin1 = 1 -constr(39): item07183_in_bin0 + item07183_in_bin1 = 1 -constr(40): item07740_in_bin0 + item07740_in_bin1 = 1 -constr(41): item07862_in_bin0 + item07862_in_bin1 = 1 -constr(42): item08519_in_bin0 + item08519_in_bin1 = 1 -constr(43): item08798_in_bin0 + item08798_in_bin1 = 1 -constr(44): item09948_in_bin0 + item09948_in_bin1 = 1 -constr(45): -152 item00152_in_bin0 + 152 item00152_in_bin1 -489 item00489_in_bin0 + 489 item00489_in_bin1 -2178 item02178_in_bin0 + 2178 item02178_in_bin1 -2518 item02518_in_bin0 + 2518 item02518_in_bin1 -3212 item03212_in_bin0 + 3212 item03212_in_bin1 - -3270 item03270_in_bin0 + 3270 item03270_in_bin1 -3410 item03410_in_bin0 + 3410 item03410_in_bin1 -4979 item04979_in_bin0 + 4979 item04979_in_bin1 -5984 item05984_in_bin0 + 5984 item05984_in_bin1 -7183 item07183_in_bin0 + 7183 item07183_in_bin1 - -7740 item07740_in_bin0 + 7740 item07740_in_bin1 -7862 item07862_in_bin0 + 7862 item07862_in_bin1 -8519 item08519_in_bin0 + 8519 item08519_in_bin1 -8798 item08798_in_bin0 + 8798 item08798_in_bin1 -9948 item09948_in_bin0 + 9948 item09948_in_bin1 +constr(0): item0_in_bin0 >= 0 +constr(1): item1_in_bin0 >= 0 +constr(2): item2_in_bin0 >= 0 +constr(3): item3_in_bin0 >= 0 +constr(4): item4_in_bin0 >= 0 +constr(5): item5_in_bin0 >= 0 +constr(6): item6_in_bin0 >= 0 +constr(7): item7_in_bin0 >= 0 +constr(8): item8_in_bin0 >= 0 +constr(9): item9_in_bin0 >= 0 +constr(10): item10_in_bin0 >= 0 +constr(11): item11_in_bin0 >= 0 +constr(12): item12_in_bin0 >= 0 +constr(13): item13_in_bin0 >= 0 +constr(14): item14_in_bin0 >= 0 +constr(15): item0_in_bin1 >= 0 +constr(16): item1_in_bin1 >= 0 +constr(17): item2_in_bin1 >= 0 +constr(18): item3_in_bin1 >= 0 +constr(19): item4_in_bin1 >= 0 +constr(20): item5_in_bin1 >= 0 +constr(21): item6_in_bin1 >= 0 +constr(22): item7_in_bin1 >= 0 +constr(23): item8_in_bin1 >= 0 +constr(24): item9_in_bin1 >= 0 +constr(25): item10_in_bin1 >= 0 +constr(26): item11_in_bin1 >= 0 +constr(27): item12_in_bin1 >= 0 +constr(28): item13_in_bin1 >= 0 +constr(29): item14_in_bin1 >= 0 +constr(30): item0_in_bin0 + item0_in_bin1 = 1 +constr(31): item1_in_bin0 + item1_in_bin1 = 1 +constr(32): item2_in_bin0 + item2_in_bin1 = 1 +constr(33): item3_in_bin0 + item3_in_bin1 = 1 +constr(34): item4_in_bin0 + item4_in_bin1 = 1 +constr(35): item5_in_bin0 + item5_in_bin1 = 1 +constr(36): item6_in_bin0 + item6_in_bin1 = 1 +constr(37): item7_in_bin0 + item7_in_bin1 = 1 +constr(38): item8_in_bin0 + item8_in_bin1 = 1 +constr(39): item9_in_bin0 + item9_in_bin1 = 1 +constr(40): item10_in_bin0 + item10_in_bin1 = 1 +constr(41): item11_in_bin0 + item11_in_bin1 = 1 +constr(42): item12_in_bin0 + item12_in_bin1 = 1 +constr(43): item13_in_bin0 + item13_in_bin1 = 1 +constr(44): item14_in_bin0 + item14_in_bin1 = 1 +constr(45): -152 item0_in_bin0 + 152 item0_in_bin1 -489 item1_in_bin0 + 489 item1_in_bin1 -2178 item2_in_bin0 + 2178 item2_in_bin1 -2518 item3_in_bin0 + 2518 item3_in_bin1 -3212 item4_in_bin0 + 3212 item4_in_bin1 + -3270 item5_in_bin0 + 3270 item5_in_bin1 -3410 item6_in_bin0 + 3410 item6_in_bin1 -4979 item7_in_bin0 + 4979 item7_in_bin1 -5984 item8_in_bin0 + 5984 item8_in_bin1 -7183 item9_in_bin0 + 7183 item9_in_bin1 + -7740 item10_in_bin0 + 7740 item10_in_bin1 -7862 item11_in_bin0 + 7862 item11_in_bin1 -8519 item12_in_bin0 + 8519 item12_in_bin1 -8798 item13_in_bin0 + 8798 item13_in_bin1 -9948 item14_in_bin0 + 9948 item14_in_bin1 >= -0 Bounds Integers -item00152_in_bin0 item00152_in_bin1 item00489_in_bin0 item00489_in_bin1 item02178_in_bin0 item02178_in_bin1 item02518_in_bin0 item02518_in_bin1 item03212_in_bin0 item03212_in_bin1 -item03270_in_bin0 item03270_in_bin1 item03410_in_bin0 item03410_in_bin1 item04979_in_bin0 item04979_in_bin1 item05984_in_bin0 item05984_in_bin1 item07183_in_bin0 item07183_in_bin1 -item07740_in_bin0 item07740_in_bin1 item07862_in_bin0 item07862_in_bin1 item08519_in_bin0 item08519_in_bin1 item08798_in_bin0 item08798_in_bin1 item09948_in_bin0 item09948_in_bin1 +item0_in_bin0 item0_in_bin1 item1_in_bin0 item1_in_bin1 item2_in_bin0 item2_in_bin1 item3_in_bin0 item3_in_bin1 item4_in_bin0 item4_in_bin1 +item5_in_bin0 item5_in_bin1 item6_in_bin0 item6_in_bin1 item7_in_bin0 item7_in_bin1 item8_in_bin0 item8_in_bin1 item9_in_bin0 item9_in_bin1 +item10_in_bin0 item10_in_bin1 item11_in_bin0 item11_in_bin1 item12_in_bin0 item12_in_bin1 item13_in_bin0 item13_in_bin1 item14_in_bin0 item14_in_bin1 End diff --git a/tests/issue17/issue17b.lp.txt b/tests/issue17/issue17b.lp.txt deleted file mode 100644 index 873c162..0000000 --- a/tests/issue17/issue17b.lp.txt +++ /dev/null @@ -1,61 +0,0 @@ -\Problem name: - -Minimize -OBJROW: 152 item00152_in_bin1 + 489 item00489_in_bin1 + 2178 item02178_in_bin1 + 2518 item02518_in_bin1 + 3212 item03212_in_bin1 + 3270 item03270_in_bin1 + 3410 item03410_in_bin1 + 4979 item04979_in_bin1 + 5984 item05984_in_bin1 + 7183 item07183_in_bin1 - + 7740 item07740_in_bin1 + 7862 item07862_in_bin1 + 8519 item08519_in_bin1 + 8798 item08798_in_bin1 + 9948 item09948_in_bin1 -Subject To -constr(0): item00152_in_bin0 >= 0 -constr(1): item00489_in_bin0 >= 0 -constr(2): item02178_in_bin0 >= 0 -constr(3): item02518_in_bin0 >= 0 -constr(4): item03212_in_bin0 >= 0 -constr(5): item03270_in_bin0 >= 0 -constr(6): item03410_in_bin0 >= 0 -constr(7): item04979_in_bin0 >= 0 -constr(8): item05984_in_bin0 >= 0 -constr(9): item07183_in_bin0 >= 0 -constr(10): item07740_in_bin0 >= 0 -constr(11): item07862_in_bin0 >= 0 -constr(12): item08519_in_bin0 >= 0 -constr(13): item08798_in_bin0 >= 0 -constr(14): item09948_in_bin0 >= 0 -constr(15): item00152_in_bin1 >= 0 -constr(16): item00489_in_bin1 >= 0 -constr(17): item02178_in_bin1 >= 0 -constr(18): item02518_in_bin1 >= 0 -constr(19): item03212_in_bin1 >= 0 -constr(20): item03270_in_bin1 >= 0 -constr(21): item03410_in_bin1 >= 0 -constr(22): item04979_in_bin1 >= 0 -constr(23): item05984_in_bin1 >= 0 -constr(24): item07183_in_bin1 >= 0 -constr(25): item07740_in_bin1 >= 0 -constr(26): item07862_in_bin1 >= 0 -constr(27): item08519_in_bin1 >= 0 -constr(28): item08798_in_bin1 >= 0 -constr(29): item09948_in_bin1 >= 0 -constr(30): item00152_in_bin0 + item00152_in_bin1 = 1 -constr(31): item00489_in_bin0 + item00489_in_bin1 = 1 -constr(32): item02178_in_bin0 + item02178_in_bin1 = 1 -constr(33): item02518_in_bin0 + item02518_in_bin1 = 1 -constr(34): item03212_in_bin0 + item03212_in_bin1 = 1 -constr(35): item03270_in_bin0 + item03270_in_bin1 = 1 -constr(36): item03410_in_bin0 + item03410_in_bin1 = 1 -constr(37): item04979_in_bin0 + item04979_in_bin1 = 1 -constr(38): item05984_in_bin0 + item05984_in_bin1 = 1 -constr(39): item07183_in_bin0 + item07183_in_bin1 = 1 -constr(40): item07740_in_bin0 + item07740_in_bin1 = 1 -constr(41): item07862_in_bin0 + item07862_in_bin1 = 1 -constr(42): item08519_in_bin0 + item08519_in_bin1 = 1 -constr(43): item08798_in_bin0 + item08798_in_bin1 = 1 -constr(44): item09948_in_bin0 + item09948_in_bin1 = 1 -constr(45): -152 item00152_in_bin0 + 152 item00152_in_bin1 -489 item00489_in_bin0 + 489 item00489_in_bin1 -2178 item02178_in_bin0 + 2178 item02178_in_bin1 -2518 item02518_in_bin0 + 2518 item02518_in_bin1 -3212 item03212_in_bin0 + 3212 item03212_in_bin1 - -3270 item03270_in_bin0 + 3270 item03270_in_bin1 -3410 item03410_in_bin0 + 3410 item03410_in_bin1 -4979 item04979_in_bin0 + 4979 item04979_in_bin1 -5984 item05984_in_bin0 + 5984 item05984_in_bin1 -7183 item07183_in_bin0 + 7183 item07183_in_bin1 - -7740 item07740_in_bin0 + 7740 item07740_in_bin1 -7862 item07862_in_bin0 + 7862 item07862_in_bin1 -8519 item08519_in_bin0 + 8519 item08519_in_bin1 -8798 item08798_in_bin0 + 8798 item08798_in_bin1 -9948 item09948_in_bin0 + 9948 item09948_in_bin1 - >= -0 -Bounds -Integers -item00152_in_bin0 item00152_in_bin1 item00489_in_bin0 item00489_in_bin1 item02178_in_bin0 item02178_in_bin1 item02518_in_bin0 item02518_in_bin1 item03212_in_bin0 item03212_in_bin1 -item03270_in_bin0 item03270_in_bin1 item03410_in_bin0 item03410_in_bin1 item04979_in_bin0 item04979_in_bin1 item05984_in_bin0 item05984_in_bin1 item07183_in_bin0 item07183_in_bin1 -item07740_in_bin0 item07740_in_bin1 item07862_in_bin0 item07862_in_bin1 item08519_in_bin0 item08519_in_bin1 item08798_in_bin0 item08798_in_bin1 item09948_in_bin0 item09948_in_bin1 -End diff --git a/tests/issue17/issue17b.sol b/tests/issue17/issue17b.sol index bb51dab..9688956 100644 --- a/tests/issue17/issue17b.sol +++ b/tests/issue17/issue17b.sol @@ -1,31 +1,30 @@ -item00152_in_bin0 = 0 -item00489_in_bin0 = 0 -item02178_in_bin0 = 0 -item02518_in_bin0 = 1 -item03212_in_bin0 = 0 -item03270_in_bin0 = 0 -item03410_in_bin0 = 1 -item04979_in_bin0 = 0 -item05984_in_bin0 = 1 -item07183_in_bin0 = 0 -item07740_in_bin0 = 1 -item07862_in_bin0 = 0 -item08519_in_bin0 = 1 -item08798_in_bin0 = 0 -item09948_in_bin0 = 1 - -item00152_in_bin1 = 1 -item00489_in_bin1 = 1 -item02178_in_bin1 = 1 -item02518_in_bin1 = 0 -item03212_in_bin1 = 1 -item03270_in_bin1 = 1 -item03410_in_bin1 = 0 -item04979_in_bin1 = 1 -item05984_in_bin1 = 0 -item07183_in_bin1 = 1 -item07740_in_bin1 = 0 -item07862_in_bin1 = 1 -item08519_in_bin1 = 0 -item08798_in_bin1 = 1 -item09948_in_bin1 = 0 \ No newline at end of file +item0_in_bin0 = 0 +item1_in_bin0 = 0 +item2_in_bin0 = 0 +item3_in_bin0 = 1 +item4_in_bin0 = 0 +item5_in_bin0 = 0 +item6_in_bin0 = 1 +item7_in_bin0 = 0 +item8_in_bin0 = 1 +item9_in_bin0 = 0 +item10_in_bin0 = 1 +item11_in_bin0 = 0 +item12_in_bin0 = 1 +item13_in_bin0 = 0 +item14_in_bin0 = 1 +item0_in_bin1 = 1 +item1_in_bin1 = 1 +item2_in_bin1 = 1 +item3_in_bin1 = 0 +item4_in_bin1 = 1 +item5_in_bin1 = 1 +item6_in_bin1 = 0 +item7_in_bin1 = 1 +item8_in_bin1 = 0 +item9_in_bin1 = 1 +item10_in_bin1 = 0 +item11_in_bin1 = 1 +item12_in_bin1 = 0 +item13_in_bin1 = 1 +item14_in_bin1 = 0 diff --git a/tests/issue17/test_ilp.py b/tests/issue17/test_ilp.py index aace02d..6e1a556 100644 --- a/tests/issue17/test_ilp.py +++ b/tests/issue17/test_ilp.py @@ -1,15 +1,14 @@ -import prtpy - +import prtpy, mip # items = [3984, 9928, 3636, 2852, 4957, 5366, 4456, 5905] items = [7740, 489, 152, 3410, 9948, 7862, 8519, 3212, 8798, 4979, 2178, 5984, 2518, 3270, 7183] -answer1 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=items, objective=prtpy.obj.MinimizeLargestSum, model_filename="issue17a.lp", solution_filename="issue17a.sol") +answer1 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=items, objective=prtpy.obj.MinimizeLargestSum, model_filename="issue17a.lp", solution_filename="issue17a.sol", solver_name=mip.CBC) print(answer1) print([sum(bin) for bin in answer1]) print(sum(answer1[0]) - sum(answer1[1])) items.sort() -answer2 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=items, objective=prtpy.obj.MinimizeLargestSum, model_filename="issue17b.lp", solution_filename="issue17b.sol") +answer2 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=items, objective=prtpy.obj.MinimizeLargestSum, model_filename="issue17b.lp", solution_filename="issue17b.sol", solver_name=mip.CBC) print(answer2) print([sum(bin) for bin in answer2]) print(sum(answer2[0]) - sum(answer2[1])) diff --git a/tests/issue17/test_ilp_random.py b/tests/issue17/test_ilp_random.py deleted file mode 100644 index fe53c8a..0000000 --- a/tests/issue17/test_ilp_random.py +++ /dev/null @@ -1,23 +0,0 @@ -from numpy.random import seed -from numpy.random import randint -import prtpy - -seed(1) - -for _ in range(1000): - for i in range(1, 10): - original_values = randint(0, 10000, i) - answer1 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=original_values, objective=prtpy.obj.MaximizeSmallestSum) - diff1 = abs(sum(answer1[0]) - sum(answer1[1])) - original_values.sort() - answer2 = prtpy.partition(algorithm = prtpy.partitioning.ilp, numbins=2, items=original_values, objective=prtpy.obj.MaximizeSmallestSum) - diff2 = abs(sum(answer2[0]) - sum(answer2[1])) - - if diff1 != diff2: - print("\n\nFound example at ", i, ":") - print("One answer with a diff of ", diff1, ":") - print(answer1[0]) - print(answer1[1]) - print("\nThe other answer with a diff of ", diff2, ":") - print(answer2[0]) - print(answer2[1]) diff --git a/tests/issue17a.lp b/tests/issue17a.lp new file mode 100644 index 0000000..b271efd --- /dev/null +++ b/tests/issue17a.lp @@ -0,0 +1,61 @@ +\Problem name: + +Minimize +OBJROW: 7740 item0_in_bin1 + 489 item1_in_bin1 + 152 item2_in_bin1 + 3410 item3_in_bin1 + 9948 item4_in_bin1 + 7862 item5_in_bin1 + 8519 item6_in_bin1 + 3212 item7_in_bin1 + 8798 item8_in_bin1 + 4979 item9_in_bin1 + + 2178 item10_in_bin1 + 5984 item11_in_bin1 + 2518 item12_in_bin1 + 3270 item13_in_bin1 + 7183 item14_in_bin1 +Subject To +constr(0): item0_in_bin0 >= 0 +constr(1): item1_in_bin0 >= 0 +constr(2): item2_in_bin0 >= 0 +constr(3): item3_in_bin0 >= 0 +constr(4): item4_in_bin0 >= 0 +constr(5): item5_in_bin0 >= 0 +constr(6): item6_in_bin0 >= 0 +constr(7): item7_in_bin0 >= 0 +constr(8): item8_in_bin0 >= 0 +constr(9): item9_in_bin0 >= 0 +constr(10): item10_in_bin0 >= 0 +constr(11): item11_in_bin0 >= 0 +constr(12): item12_in_bin0 >= 0 +constr(13): item13_in_bin0 >= 0 +constr(14): item14_in_bin0 >= 0 +constr(15): item0_in_bin1 >= 0 +constr(16): item1_in_bin1 >= 0 +constr(17): item2_in_bin1 >= 0 +constr(18): item3_in_bin1 >= 0 +constr(19): item4_in_bin1 >= 0 +constr(20): item5_in_bin1 >= 0 +constr(21): item6_in_bin1 >= 0 +constr(22): item7_in_bin1 >= 0 +constr(23): item8_in_bin1 >= 0 +constr(24): item9_in_bin1 >= 0 +constr(25): item10_in_bin1 >= 0 +constr(26): item11_in_bin1 >= 0 +constr(27): item12_in_bin1 >= 0 +constr(28): item13_in_bin1 >= 0 +constr(29): item14_in_bin1 >= 0 +constr(30): item0_in_bin0 + item0_in_bin1 = 1 +constr(31): item1_in_bin0 + item1_in_bin1 = 1 +constr(32): item2_in_bin0 + item2_in_bin1 = 1 +constr(33): item3_in_bin0 + item3_in_bin1 = 1 +constr(34): item4_in_bin0 + item4_in_bin1 = 1 +constr(35): item5_in_bin0 + item5_in_bin1 = 1 +constr(36): item6_in_bin0 + item6_in_bin1 = 1 +constr(37): item7_in_bin0 + item7_in_bin1 = 1 +constr(38): item8_in_bin0 + item8_in_bin1 = 1 +constr(39): item9_in_bin0 + item9_in_bin1 = 1 +constr(40): item10_in_bin0 + item10_in_bin1 = 1 +constr(41): item11_in_bin0 + item11_in_bin1 = 1 +constr(42): item12_in_bin0 + item12_in_bin1 = 1 +constr(43): item13_in_bin0 + item13_in_bin1 = 1 +constr(44): item14_in_bin0 + item14_in_bin1 = 1 +constr(45): -7740 item0_in_bin0 + 7740 item0_in_bin1 -489 item1_in_bin0 + 489 item1_in_bin1 -152 item2_in_bin0 + 152 item2_in_bin1 -3410 item3_in_bin0 + 3410 item3_in_bin1 -9948 item4_in_bin0 + 9948 item4_in_bin1 + -7862 item5_in_bin0 + 7862 item5_in_bin1 -8519 item6_in_bin0 + 8519 item6_in_bin1 -3212 item7_in_bin0 + 3212 item7_in_bin1 -8798 item8_in_bin0 + 8798 item8_in_bin1 -4979 item9_in_bin0 + 4979 item9_in_bin1 + -2178 item10_in_bin0 + 2178 item10_in_bin1 -5984 item11_in_bin0 + 5984 item11_in_bin1 -2518 item12_in_bin0 + 2518 item12_in_bin1 -3270 item13_in_bin0 + 3270 item13_in_bin1 -7183 item14_in_bin0 + 7183 item14_in_bin1 + >= -0 +Bounds +Integers +item0_in_bin0 item0_in_bin1 item1_in_bin0 item1_in_bin1 item2_in_bin0 item2_in_bin1 item3_in_bin0 item3_in_bin1 item4_in_bin0 item4_in_bin1 +item5_in_bin0 item5_in_bin1 item6_in_bin0 item6_in_bin1 item7_in_bin0 item7_in_bin1 item8_in_bin0 item8_in_bin1 item9_in_bin0 item9_in_bin1 +item10_in_bin0 item10_in_bin1 item11_in_bin0 item11_in_bin1 item12_in_bin0 item12_in_bin1 item13_in_bin0 item13_in_bin1 item14_in_bin0 item14_in_bin1 +End diff --git a/tests/issue17a.sol b/tests/issue17a.sol new file mode 100644 index 0000000..a13e1d1 --- /dev/null +++ b/tests/issue17a.sol @@ -0,0 +1,30 @@ +item0_in_bin0 = 1 +item1_in_bin0 = 1 +item2_in_bin0 = 1 +item3_in_bin0 = 1 +item4_in_bin0 = 1 +item5_in_bin0 = 1 +item6_in_bin0 = 1 +item7_in_bin0 = 0 +item8_in_bin0 = 0 +item9_in_bin0 = 0 +item10_in_bin0 = 0 +item11_in_bin0 = 0 +item12_in_bin0 = 0 +item13_in_bin0 = 0 +item14_in_bin0 = 0 +item0_in_bin1 = 0 +item1_in_bin1 = 0 +item2_in_bin1 = 0 +item3_in_bin1 = 0 +item4_in_bin1 = 0 +item5_in_bin1 = 0 +item6_in_bin1 = 0 +item7_in_bin1 = 1 +item8_in_bin1 = 1 +item9_in_bin1 = 1 +item10_in_bin1 = 1 +item11_in_bin1 = 1 +item12_in_bin1 = 1 +item13_in_bin1 = 1 +item14_in_bin1 = 1 diff --git a/tests/issue17b.lp b/tests/issue17b.lp new file mode 100644 index 0000000..3aee537 --- /dev/null +++ b/tests/issue17b.lp @@ -0,0 +1,61 @@ +\Problem name: + +Minimize +OBJROW: 152 item0_in_bin1 + 489 item1_in_bin1 + 2178 item2_in_bin1 + 2518 item3_in_bin1 + 3212 item4_in_bin1 + 3270 item5_in_bin1 + 3410 item6_in_bin1 + 4979 item7_in_bin1 + 5984 item8_in_bin1 + 7183 item9_in_bin1 + + 7740 item10_in_bin1 + 7862 item11_in_bin1 + 8519 item12_in_bin1 + 8798 item13_in_bin1 + 9948 item14_in_bin1 +Subject To +constr(0): item0_in_bin0 >= 0 +constr(1): item1_in_bin0 >= 0 +constr(2): item2_in_bin0 >= 0 +constr(3): item3_in_bin0 >= 0 +constr(4): item4_in_bin0 >= 0 +constr(5): item5_in_bin0 >= 0 +constr(6): item6_in_bin0 >= 0 +constr(7): item7_in_bin0 >= 0 +constr(8): item8_in_bin0 >= 0 +constr(9): item9_in_bin0 >= 0 +constr(10): item10_in_bin0 >= 0 +constr(11): item11_in_bin0 >= 0 +constr(12): item12_in_bin0 >= 0 +constr(13): item13_in_bin0 >= 0 +constr(14): item14_in_bin0 >= 0 +constr(15): item0_in_bin1 >= 0 +constr(16): item1_in_bin1 >= 0 +constr(17): item2_in_bin1 >= 0 +constr(18): item3_in_bin1 >= 0 +constr(19): item4_in_bin1 >= 0 +constr(20): item5_in_bin1 >= 0 +constr(21): item6_in_bin1 >= 0 +constr(22): item7_in_bin1 >= 0 +constr(23): item8_in_bin1 >= 0 +constr(24): item9_in_bin1 >= 0 +constr(25): item10_in_bin1 >= 0 +constr(26): item11_in_bin1 >= 0 +constr(27): item12_in_bin1 >= 0 +constr(28): item13_in_bin1 >= 0 +constr(29): item14_in_bin1 >= 0 +constr(30): item0_in_bin0 + item0_in_bin1 = 1 +constr(31): item1_in_bin0 + item1_in_bin1 = 1 +constr(32): item2_in_bin0 + item2_in_bin1 = 1 +constr(33): item3_in_bin0 + item3_in_bin1 = 1 +constr(34): item4_in_bin0 + item4_in_bin1 = 1 +constr(35): item5_in_bin0 + item5_in_bin1 = 1 +constr(36): item6_in_bin0 + item6_in_bin1 = 1 +constr(37): item7_in_bin0 + item7_in_bin1 = 1 +constr(38): item8_in_bin0 + item8_in_bin1 = 1 +constr(39): item9_in_bin0 + item9_in_bin1 = 1 +constr(40): item10_in_bin0 + item10_in_bin1 = 1 +constr(41): item11_in_bin0 + item11_in_bin1 = 1 +constr(42): item12_in_bin0 + item12_in_bin1 = 1 +constr(43): item13_in_bin0 + item13_in_bin1 = 1 +constr(44): item14_in_bin0 + item14_in_bin1 = 1 +constr(45): -152 item0_in_bin0 + 152 item0_in_bin1 -489 item1_in_bin0 + 489 item1_in_bin1 -2178 item2_in_bin0 + 2178 item2_in_bin1 -2518 item3_in_bin0 + 2518 item3_in_bin1 -3212 item4_in_bin0 + 3212 item4_in_bin1 + -3270 item5_in_bin0 + 3270 item5_in_bin1 -3410 item6_in_bin0 + 3410 item6_in_bin1 -4979 item7_in_bin0 + 4979 item7_in_bin1 -5984 item8_in_bin0 + 5984 item8_in_bin1 -7183 item9_in_bin0 + 7183 item9_in_bin1 + -7740 item10_in_bin0 + 7740 item10_in_bin1 -7862 item11_in_bin0 + 7862 item11_in_bin1 -8519 item12_in_bin0 + 8519 item12_in_bin1 -8798 item13_in_bin0 + 8798 item13_in_bin1 -9948 item14_in_bin0 + 9948 item14_in_bin1 + >= -0 +Bounds +Integers +item0_in_bin0 item0_in_bin1 item1_in_bin0 item1_in_bin1 item2_in_bin0 item2_in_bin1 item3_in_bin0 item3_in_bin1 item4_in_bin0 item4_in_bin1 +item5_in_bin0 item5_in_bin1 item6_in_bin0 item6_in_bin1 item7_in_bin0 item7_in_bin1 item8_in_bin0 item8_in_bin1 item9_in_bin0 item9_in_bin1 +item10_in_bin0 item10_in_bin1 item11_in_bin0 item11_in_bin1 item12_in_bin0 item12_in_bin1 item13_in_bin0 item13_in_bin1 item14_in_bin0 item14_in_bin1 +End diff --git a/tests/issue17b.sol b/tests/issue17b.sol new file mode 100644 index 0000000..9688956 --- /dev/null +++ b/tests/issue17b.sol @@ -0,0 +1,30 @@ +item0_in_bin0 = 0 +item1_in_bin0 = 0 +item2_in_bin0 = 0 +item3_in_bin0 = 1 +item4_in_bin0 = 0 +item5_in_bin0 = 0 +item6_in_bin0 = 1 +item7_in_bin0 = 0 +item8_in_bin0 = 1 +item9_in_bin0 = 0 +item10_in_bin0 = 1 +item11_in_bin0 = 0 +item12_in_bin0 = 1 +item13_in_bin0 = 0 +item14_in_bin0 = 1 +item0_in_bin1 = 1 +item1_in_bin1 = 1 +item2_in_bin1 = 1 +item3_in_bin1 = 0 +item4_in_bin1 = 1 +item5_in_bin1 = 1 +item6_in_bin1 = 0 +item7_in_bin1 = 1 +item8_in_bin1 = 0 +item9_in_bin1 = 1 +item10_in_bin1 = 0 +item11_in_bin1 = 1 +item12_in_bin1 = 0 +item13_in_bin1 = 1 +item14_in_bin1 = 0