|
38 | 38 | from pydvl.utils.score import Scorer |
39 | 39 | from pydvl.utils.types import SupervisedModel |
40 | 40 |
|
41 | | -__all__ = ["Utility", "DataUtilityLearning", "MinerGameUtility", "GlovesGameUtility"] |
| 41 | +__all__ = ["Utility", "DataUtilityLearning"] |
42 | 42 |
|
43 | 43 | logger = logging.getLogger(__name__) |
44 | 44 |
|
@@ -356,120 +356,3 @@ def __call__(self, indices: Iterable[int]) -> float: |
356 | 356 | def data(self) -> Dataset: |
357 | 357 | """Returns the wrapped utility's [Dataset][pydvl.utils.dataset.Dataset].""" |
358 | 358 | return self.utility.data |
359 | | - |
360 | | - |
361 | | -class MinerGameUtility(Utility): |
362 | | - r"""Toy game utility that is used for testing and demonstration purposes. |
363 | | -
|
364 | | - Consider a group of n miners, who have discovered large bars of gold. |
365 | | -
|
366 | | - If two miners can carry one piece of gold, then the payoff of a |
367 | | - coalition $S$ is: |
368 | | -
|
369 | | - $${ |
370 | | - v(S) = \left\{\begin{array}{lll} |
371 | | - \mid S \mid / 2 & \text{, if} & \mid S \mid \text{ is even} \\ |
372 | | - ( \mid S \mid - 1)/2 & \text{, if} & \mid S \mid \text{ is odd} |
373 | | - \end{array}\right. |
374 | | - }$$ |
375 | | -
|
376 | | - If there are more than two miners and there is an even number of miners, |
377 | | - then the core consists of the single payoff where each miner gets 1/2. |
378 | | -
|
379 | | - If there is an odd number of miners, then the core is empty. |
380 | | -
|
381 | | - Taken from [Wikipedia](https://en.wikipedia.org/wiki/Core_(game_theory)) |
382 | | -
|
383 | | - Args: |
384 | | - n_miners: Number of miners that participate in the game. |
385 | | - """ |
386 | | - |
387 | | - def __init__(self, n_miners: int, **kwargs): |
388 | | - if n_miners <= 2: |
389 | | - raise ValueError(f"n_miners, {n_miners} should be > 2") |
390 | | - self.n_miners = n_miners |
391 | | - |
392 | | - x = np.arange(n_miners)[..., np.newaxis] |
393 | | - # The y values don't matter here |
394 | | - y = np.zeros_like(x) |
395 | | - |
396 | | - self.data = Dataset(x_train=x, y_train=y, x_test=x, y_test=y) |
397 | | - |
398 | | - def __call__(self, indices: Iterable[int]) -> float: |
399 | | - n = len(tuple(indices)) |
400 | | - if n % 2 == 0: |
401 | | - return n / 2 |
402 | | - else: |
403 | | - return (n - 1) / 2 |
404 | | - |
405 | | - def _initialize_utility_wrapper(self): |
406 | | - pass |
407 | | - |
408 | | - def exact_least_core_values(self) -> Tuple[NDArray[np.float_], float]: |
409 | | - if self.n_miners % 2 == 0: |
410 | | - values = np.array([0.5] * self.n_miners) |
411 | | - subsidy = 0.0 |
412 | | - else: |
413 | | - values = np.array( |
414 | | - [(self.n_miners - 1) / (2 * self.n_miners)] * self.n_miners |
415 | | - ) |
416 | | - subsidy = (self.n_miners - 1) / (2 * self.n_miners) |
417 | | - return values, subsidy |
418 | | - |
419 | | - def __repr__(self) -> str: |
420 | | - return f"{self.__class__.__name__}(n={self.n_miners})" |
421 | | - |
422 | | - |
423 | | -class GlovesGameUtility(Utility): |
424 | | - r"""Toy game utility that is used for testing and demonstration purposes. |
425 | | -
|
426 | | - In this game, some players have a left glove and others a right glove. |
427 | | - Single gloves have a worth of zero while pairs have a worth of 1. |
428 | | -
|
429 | | - The payoff of a coalition $S$ is: |
430 | | -
|
431 | | - $${ |
432 | | - v(S) = \min( \mid S \cap L \mid, \mid S \cap R \mid ) |
433 | | - }$$ |
434 | | -
|
435 | | - Where $L$, respectively $R$, is the set of players with left gloves, |
436 | | - respectively right gloves. |
437 | | -
|
438 | | - Args: |
439 | | - left: Number of players with a left glove. |
440 | | - right: Number of player with a right glove. |
441 | | -
|
442 | | - """ |
443 | | - |
444 | | - def __init__(self, left: int, right: int, **kwargs): |
445 | | - self.left = left |
446 | | - self.right = right |
447 | | - |
448 | | - x = np.empty(left + right)[..., np.newaxis] |
449 | | - # The y values don't matter here |
450 | | - y = np.zeros_like(x) |
451 | | - |
452 | | - self.data = Dataset(x_train=x, y_train=y, x_test=x, y_test=y) |
453 | | - |
454 | | - def __call__(self, indices: Iterable[int]) -> float: |
455 | | - left_sum = float(np.sum(np.asarray(indices) < self.left)) |
456 | | - right_sum = float(np.sum(np.asarray(indices) >= self.left)) |
457 | | - return min(left_sum, right_sum) |
458 | | - |
459 | | - def _initialize_utility_wrapper(self): |
460 | | - pass |
461 | | - |
462 | | - def exact_least_core_values(self) -> Tuple[NDArray[np.float_], float]: |
463 | | - if self.left == self.right: |
464 | | - subsidy = -0.5 |
465 | | - values = np.array([0.5] * (self.left + self.right)) |
466 | | - elif self.left < self.right: |
467 | | - subsidy = 0.0 |
468 | | - values = np.array([1.0] * self.left + [0.0] * self.right) |
469 | | - else: |
470 | | - subsidy = 0.0 |
471 | | - values = np.array([0.0] * self.left + [1.0] * self.right) |
472 | | - return values, subsidy |
473 | | - |
474 | | - def __repr__(self) -> str: |
475 | | - return f"{self.__class__.__name__}(L={self.left}, R={self.right})" |
0 commit comments