LoginSignup
0
0

More than 1 year has passed since last update.

Knapsack Problem solving by various way like quantum algorithm, python package, and linear programming

Last updated at Posted at 2022-08-07
class KnapsackProblem():
    values: List[int] = []
    weights: List[int] = []
    max_weight: int = 0
    
    def __init__(self, values, weights, max_weight):
        self.values = values
        self.weights = weights
        self.max_weight = max_weight
    
    def solve_by_qaoa(self):
        problem = Knapsack(values=self.values, weights=self.weights, max_weight=self.max_weight)
        quadratic_program = problem.to_quadratic_program()
        backend = Aer.get_backend('aer_simulator')
        quantum_instance = QuantumInstance(backend=backend, shots=800, seed_simulator=99)
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver=QAOA(reps=1, quantum_instance=quantum_instance))
        solved = min_eigen_optimizer.solve(quadratic_program)
        result = problem.interpret(solved)
        print(result)
        return result
    
    def solve_by_numpy_eigensolver(self):
        problem = Knapsack(values=self.values, weights=self.weights, max_weight=self.max_weight)
        quadratic_program = problem.to_quadratic_program()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver=NumPyMinimumEigensolver())
        solved = min_eigen_optimizer.solve(quadratic_program)
        result = problem.interpret(solved)
        print(result)
        return result
    
    def solve_by_ortoolpy(self):
        result = knapsack(self.weights, self.values, self.max_weight)
        print(result)
        return result
    
    def solve_by_pulp(self):
        ran = range(len(self.values))
        problem = LpProblem(sense=LpMaximize)
        var = [LpVariable('x%d'%i, cat=LpBinary) for i in ran]
        problem += lpDot(self.weights, var)
        problem += lpDot(self.values, var) <= self.max_weight
        problem.solve()
        result = (value(problem.objective), [i for i in ran if value(var[i]) > 0.5])
        print(result)
        return result
    
    def solve_by_greedy_algorithm(self):
        N = len(self.values)
        W = self.max_weight
        w = self.weights
        v = self.values
        dp = [[0]*(W+1) for i in range(N+1)]
        for i in range(N):
            for j in range(W+1):
                if j < w[i]:
                    dp[i+1][j] = dp[i][j]
                else:
                    dp[i+1][j] = max(dp[i][j], dp[i][j-w[i]]+v[i])
        result = dp[N][W]
        print(result)
        return result
    
    def solve_by_ising_model(self):
        def Hamiltonian(x):
            B = 10
            W = self.max_weight
            w_sum = 0
            v_sum = 0
            for i, w in enumerate(self.weights):
              w_sum += w*x[i]
            for i, v in enumerate(self.values):
              v_sum += v*x[i]
            H = B*(W-w_sum)**2-v_sum
            return H
        def run(H):
            N = len(self.values)
            T = self.max_weight
            ite = 1000
            targetT = 0.02
            red = 0.97
            q = [random.randint(0,1) for i in range(N)]
            while T>targetT:
                x_list = np.random.randint(0, N, ite)
                for x in x_list:
                  q2 = copy.copy(q)
                  y = np.random.randint(0, N)
                  q2[x] = q[y]
                  q2[y] = q[x]
                  dE = H(q2) - H(q)
                  if np.exp(-dE/T) > np.random.random_sample():
                    q[x] = q2[x]
                    q[y] = q2[y]
                T *= red
            return q
        answer = run(Hamiltonian)
        result = []
        for i, a in enumerate(answer):
            if a == 1:
                result.append(i)
        print(result)
        return result

knapsack_problem = KnapsackProblem(size, weight, capacity)
knapsack_problem.solve_by_qaoa()
knapsack_problem.solve_by_numpy_eigensolver()
knapsack_problem.solve_by_ortoolpy()
knapsack_problem.solve_by_pulp()
knapsack_problem.solve_by_vanila()
knapsack_problem.solve_by_ising_model()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0