Beispiel #1
0
 def code_to_consumption_graph(self, consumption_graph: ConsumptionGraph,
                               code) -> ConsumptionGraph:
     """
     this function take code that represent new graph and convert
     it to that consumption_graph
     the calculation of the properties of each agent is p[i]/2 from the end of arr belongs to the new agent
     and len(arr)-p[i]/2 from the start of arr belongs to agent i
     :param consumption_graph: the original graph
     :param code:the code in form (x1,x2...xi) i = the number of agent in graph, xi in range(number of properties of
      agent i in graph
     :return: consumption_graph for that code
     >>> v = [[40,30,20,10],[40,30,20,10],[40,30,20,10],[10,10,10,10]]
     >>> gg = GraphGenerator(v)
     >>> g = [[0,1,1,0],[1,0,0,0],[0,1,0,1]]
     >>> cg = ConsumptionGraph(g)
     >>> print(gg.code_to_consumption_graph(cg,(0,0,0)).get_graph())
     [[0.0, 1, 1, 0.0], [1, 0.0, 0.0, 0.0], [0.0, 1, 0.0, 1], [0.0, 0.0, 0.0, 0.0]]
     >>> print(gg.code_to_consumption_graph(cg,(4,1,3)).get_graph())
     [[0.0, 0.0, 0.0, 0.0], [1, 0.0, 0.0, 0.0], [0.0, 1, 0.0, 0.0], [1, 1, 1, 1]]
     >>> v1 = [[1,2,3,4],[8,7,6,5],[9,12,10,11],[1,2,3,4]]
     >>> g1 = [[0,1,1,0],[1,0,0,0],[0,1,0,1]]
     >>> gg = GraphGenerator(v1)
     >>> cg = ConsumptionGraph(g1)
     >>> print(gg.code_to_consumption_graph(cg,(2,3,2)).get_graph())
     [[0.0, 1, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 1, 0.0, 0.0], [1, 0.0, 1, 1]]
     >>> print(gg.code_to_consumption_graph(cg,(4,1,3)).get_graph())
     [[0.0, 0.0, 0.0, 0.0], [1, 0.0, 0.0, 0.0], [0.0, 1, 0.0, 0.0], [1, 1, 1, 1]]
     >>> print(gg.code_to_consumption_graph(cg,(3,1,1)).get_graph())
     [[0.0, 1, 0.0, 0.0], [1, 0.0, 0.0, 0.0], [0.0, 1, 0.0, 1], [1, 1, 1, 1]]
     >>> print(gg.code_to_consumption_graph(cg,(1,2,3)).get_graph())
     [[0.0, 1, 1, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 1, 0.0, 0.0], [1, 1, 1, 1]]
     >>> v1 = [[1,2,3,4],[8,7,6,5],[9,12,10,11],[1,4,3,2]]
     >>> gg = GraphGenerator(v1)
     >>> print(gg.code_to_consumption_graph(cg,(2,3,2)).get_graph())
     [[0.0, 0.0, 1, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1], [1, 1, 0.0, 0.0]]
     """
     graph = consumption_graph.get_graph()
     mat = np.zeros((len(graph) + 1, len(graph[0]))).tolist()
     for i in range(len(graph)):
         arr = self.valuation_ratios.create_the_value_ratio_for_2(
             consumption_graph, i, len(graph))
         num_of_properties = len(arr)
         current_agent_properties = math.ceil(num_of_properties -
                                              code[i] / 2)
         new_agent_properties = math.ceil(code[i] / 2)
         for j in range(current_agent_properties):
             mat[i][arr[j][0]] = 1
         for j in range(num_of_properties - new_agent_properties,
                        num_of_properties):
             mat[len(graph)][int(arr[j][0])] = 1
     return ConsumptionGraph(mat)
Beispiel #2
0
 def add_agent(self, genneretor, i):
     """
     this function get generator for all the the graph for i-1 agent
     and generate all the graph for adding agent i
     :param genneretor: generator for the all the  graph for i-1 agents
     :param i: the index for the new agent
     :return: generator for the all the  graph for i agents
     >>> a = (0)
     >>> matv = [[30,20,10],[20,15,10],[5,5,5]]
     >>> gg = GraphGenerator(matv)
     >>> gen = gg.add_agent(a,0)
     >>> for g in gg.add_agent(gen,1):
     ...       print(g.get_graph())
     [[1, 1, 0.0], [0.0, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 1]]
     [[1, 0.0, 0.0], [1, 1, 1]]
     """
     if (i == 0):
         arr = []
         # the first agent gets all the objects
         arr.append([1] * len(self.valuation_matrix[0]))
         yield ConsumptionGraph(arr)
     else:
         for g in genneretor:
             for x in self.add_agent_to_graph(g):
                 yield x
Beispiel #3
0
 def add_agent_to_graph(self, consumption_graph: ConsumptionGraph):
     """
     :param consumption_graph: : some given ConsumptionGraph that represent agent and there properties
     :return: generator for the all the  graphs from adding agent i to the given graph
     >>> matv = [[40,30,20],[40,30,20],[10,10,10]]
     >>> graph = [[1,1,0],[0,1,1]]
     >>> g = GraphGenerator(matv)
     >>> cg = ConsumptionGraph(graph)
     >>> for x in g.add_agent_to_graph(cg):
     ...     print(x.get_graph())
     [[1, 1, 0.0], [0.0, 1, 1], [0.0, 0.0, 1]]
     [[1, 1, 0.0], [0.0, 1, 0.0], [0.0, 0.0, 1]]
     [[1, 1, 0.0], [0.0, 1, 0.0], [0.0, 1, 1]]
     [[1, 1, 0.0], [0.0, 1, 1], [0.0, 1, 0.0]]
     [[1, 1, 0.0], [0.0, 1, 1], [0.0, 1, 1]]
     [[1, 1, 0.0], [0.0, 1, 0.0], [0.0, 1, 1]]
     [[1, 1, 0.0], [0.0, 1, 0.0], [0.0, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 1], [0.0, 1, 0.0]]
     [[1, 0.0, 0.0], [0.0, 1, 1], [0.0, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 0.0], [0.0, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 0.0], [0.0, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 1], [1, 1, 0.0]]
     [[1, 0.0, 0.0], [0.0, 1, 1], [1, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 0.0], [1, 1, 1]]
     [[1, 0.0, 0.0], [0.0, 1, 0.0], [1, 1, 1]]
     >>> matv = [[40,30,20],[40,30,20],[10,10,10]]
     >>> graph = [[1,1,1],[0,0,0]]
     >>> g = GraphGenerator(matv)
     >>> cg = ConsumptionGraph(graph)
     >>> for x in g.add_agent_to_graph(cg):
     ...     print(x.get_graph())
     """
     for code in consumption_graph.generate_all_code():
         g = self.code_to_consumption_graph(consumption_graph, code)
         #anther adding!!!
         if (g.is_prop(self.valuation_matrix)) and (
                 g.get_num_of_sharing() <= self.num_of_sharing_is_allowed):
             # the fixing!!
             #if (g.get_num_of_sharing() <= self.num_of_sharing_is_allowed):
             yield g
 def find_allocation_for_graph(self, consumption_graph: ConsumptionGraph):
     """
     this function get a consumption graph and use cvxpy to solve
     the convex problem to find a envy free allocation.
     the condition for the convex problem is:
     1) each alloc[i][j] >=0 - an agent cant get minus pesent
     from some item
     2) if consumption_graph[i][j] == 0 so alloc[i][j]= 0 .
     if in the current consumption graph the agent i doesnt consume the item j
     so in the allocation he is get 0% from this item
     3) the envy free condition (by definition)
     4) the sum of every column in the allocation == 1
     each item divided exactly to 100 percent
     and after solving the problem - check if the result are better from the
     "min_sharing_allocation"  (meaning if the current allocation as lass shering from "min_sharing_allocation")
     and update it
     :param consumption_graph: some given consumption graph
     :return: update "min_sharing_allocation"
     # the test are according to the result of ver 1 in GraphCheck
     >>> v = [[5, 2, 1.5,1], [9, 1, 3,2.5], [10, 3, 2,4]]
     >>> fefap =FairEnvyFreeAllocationProblem(v)
     >>> g1 = [[1, 1, 0.0, 0.0], [1, 0.0, 1, 0.0], [1, 0.0, 0.0, 1]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     [[0.337 1.    0.    0.   ]
      [0.342 0.    1.    0.   ]
      [0.32  0.    0.    0.999]]
     >>> g1 = [[1, 1, 0.0, 0.0], [1, 0.0, 1, 0.0], [1, 0.0, 0.0, 1]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     [[0.337 1.    0.    0.   ]
      [0.342 0.    1.    0.   ]
      [0.32  0.    0.    0.999]]
     >>> g1 = [[1, 1, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [1, 0.0, 1, 1]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     None
     >>> g1 = [[1, 1, 0.0, 0.0], [1, 0.0, 1, 1], [1, 0.0, 0.0, 0.0]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     [[0.302 0.999 0.    0.   ]
      [0.046 0.    0.999 1.   ]
      [0.651 0.    0.    0.   ]]
     >>> g1 = [[1, 1, 0.0, 0.0], [1, 0.0, 1, 1], [1, 0.0, 0.0, 1]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     [[0.322 1.    0.    0.   ]
      [0.251 0.    1.    0.332]
      [0.425 0.    0.    0.667]]
     >>> g1 = [[1, 1, 0.0, 0.0], [1, 0.0, 1, 1], [0.0, 0.0, 0.0, 0.0]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     None
     >>> g1 = [[1, 1, 0.0, 0.0], [1, 0.0, 1, 0.0], [1, 0.0, 0.0, 1]]
     >>> g = ConsumptionGraph(g1)
     >>> print(fefap.find_allocation_for_graph(g))
     [[0.337 1.    0.    0.   ]
      [0.342 0.    1.    0.   ]
      [0.32  0.    0.    0.999]]
     """
     mat = cvxpy.Variable((self.num_of_agents, self.num_of_items))
     constraints = []
     # every var >=0 and if there is no edge the var is zero
     # and envy_free condition
     for i in range(self.num_of_agents):
         agent_sum = 0
         for j in range(self.num_of_items):
             agent_sum += mat[i][j] * self.valuation[i][j]
             if (consumption_graph.get_graph()[i][j] == 0):
                 constraints.append(mat[i][j] == 0)
             else:
                 constraints.append(mat[i][j] >= 0)
         anther_agent_sum = 0
         for j in range(self.num_of_agents):
             anther_agent_sum = 0
             for k in range(self.num_of_items):
                 anther_agent_sum += mat[j][k] * self.valuation[i][k]
             constraints.append(agent_sum >= anther_agent_sum)
     # the sum of each column is 1 (the property on each object is 100%)
     for i in range(self.num_of_items):
         constraints.append(sum(mat[:, i]) == 1)
     objective = cvxpy.Maximize(1)
     prob = cvxpy.Problem(objective, constraints)
     try:
         prob.solve(solver="OSQP")
     except cvxpy.SolverError:
         prob.solve(solver="SCS")
     if prob.status == 'optimal':
         alloc = Allocation(mat.value)
         alloc.round()
         self.min_sharing_number = alloc.num_of_shering()
         self.min_sharing_allocation = alloc.get_allocation()
         self.find = True
     # only for doctet:
     return (mat.value)
Beispiel #5
0
    def find_allocation_for_graph(self, consumption_graph: ConsumptionGraph):
        """
        this function get a consumption graph and use cvxpy to solve
        the convex problem to find a proportional allocation.
        the condition for the convex problem is:
        1) each alloc[i][j] >=0 - an agent cant get minus pesent
        from some item
        2) if consumption_graph[i][j] == 0 so alloc[i][j]= 0 .
        if in the current consumption graph the agent i doesnt consume the item j
        so in the allocation he is get 0% from this item
        3) the proportional condition (by definition)
        4) the sum of every column in the allocation == 1
        each item divided exactly to 100 percent
        and after solving the problem - check if the result are better from the
        "min_sharing_allocation"  (meaning if the current allocation as lass shering from "min_sharing_allocation")
        and update it
        :param consumption_graph: some given consumption graph
        :return: update "min_sharing_allocation"
        # the test are according to the result of ver 1 in GraphCheck
        >>> v = [[1, 2, 3,4], [4, 5, 6,5], [7, 8, 9,6]]
        >>> fpap =FairProportionalAllocationProblem(v)
        >>> g1 = [[0.0, 0.0, 0.0, 1], [1, 1, 1, 1], [0.0, 0.0, 0.0, 1]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        None
        >>> g1 = [[0.0, 0.0, 0.0, 1], [1, 1, 1, 1], [1, 0.0, 0.0, 1]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        None
        >>> g1 = [[0.0, 0.0, 0.0, 1], [0.0, 1, 1, 1], [1, 0.0, 0.0, 1]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        None
        >>> g1 = [[0.0, 0.0, 0.0, 1], [0.0, 1, 1, 1], [1, 1, 0.0, 1]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        [[0.    0.    0.    0.884]
         [0.    0.464 1.    0.049]
         [1.    0.535 0.    0.065]]
        >>> g1 = [[0.0, 0.0, 0.0, 1], [0.0, 0.0, 1, 1], [1, 1, 0.0, 1]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        [[0.    0.    0.    0.842]
         [0.    0.    0.999 0.147]
         [1.    1.    0.    0.01 ]]
        >>> g1 = [[0.0, 0.0, 0.0, 1], [0.0, 0.0, 1, 1], [1, 1, 1, 1]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        [[0.    0.    0.    0.836]
         [0.    0.    0.994 0.149]
         [1.    1.    0.005 0.013]]
        >>> g1 = [[0.0, 0.0, 0.0, 1], [0.0, 1, 1, 1], [1, 0.0, 0.0, 0.0]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        None
        >>> g1 = [[0.0, 0.0, 0.0, 1], [0.0, 1, 1, 1], [1, 1, 0.0, 0.0]]
        >>> g = ConsumptionGraph(g1)
        >>> print(fpap.find_allocation_for_graph(g))
        [[0.    0.    0.    0.856]
         [0.    0.471 1.    0.143]
         [1.    0.528 0.    0.   ]]
        """
        if (consumption_graph.get_num_of_sharing() ==
                self.graph_generator.num_of_sharing_is_allowed):
            mat = cvxpy.Variable((self.num_of_agents, self.num_of_items))
            constraints = []
            # every var >=0 and if there is no edge the var is zero
            # and proportional condition
            for i in range(self.num_of_agents):
                count = 0
                for j in range(self.num_of_items):
                    if (consumption_graph.get_graph()[i][j] == 0):
                        constraints.append(mat[i][j] == 0)
                    else:
                        constraints.append(mat[i][j] >= 0)
                    count += mat[i][j] * self.valuation[i][j]
                constraints.append(
                    count >= sum(self.valuation[i]) / len(self.valuation))
            # the sum of each column is 1 (the property on each object is 100%)
            for i in range(self.num_of_items):
                constraints.append(sum(mat[:, i]) == 1)
            objective = cvxpy.Maximize(1)
            prob = cvxpy.Problem(objective, constraints)

            try:
                prob.solve(solver="OSQP")
            except cvxpy.SolverError:
                prob.solve(solver="SCS")
            if prob.status == 'optimal':

                # prob.solve(solver="SCS")  # Returns the optimal value. prob.solve(solver="SCS")
                # if not (prob.status == 'infeasible'):
                alloc = Allocation(mat.value)
                alloc.round()
                self.min_sharing_number = alloc.num_of_shering()
                self.min_sharing_allocation = alloc.get_allocation()
                self.find = True
            # only for doctet:
            return (mat.value)